Design Patterns with Use Cases and Ruby Class Examples
1. Builder Pattern:
Use Case: Building a complex object step by step, such as creating a house with customizable features.
Example:
class HouseBuilder
def initialize
@house = House.new
end
def build_walls(walls)
@house.walls = walls
self
end
def build_doors(doors)
@house.doors = doors
self
end
def build_roof(roof)
@house.roof = roof
self
end
def build
@house
end
end
Usage:
builder = HouseBuilder.new
house = builder.build_walls(4).build_doors(2).build_roof('gabled').build
puts house.details
2. Factory Pattern:
Use Case: Creating objects without specifying their exact class, such as producing cars of different types.
Example:
class CarFactory
def self.create_car(type)
case type
when :sedan then Sedan.new
when :suv then SUV.new
else Car.new
end
end
end
Usage:
car = CarFactory.create_car(:suv)
puts car.type
3. Command Pattern:
Use Case: Encapsulating requests as objects, such as turning devices on/off via a remote.
Example:
class RemoteControl
def add_command(command)
@commands << command
end
def execute_commands
@commands.map(&:execute)
end
end
Usage:
remote = RemoteControl.new
remote.add_command(TurnOnCommand.new(light))
remote.add_command(TurnOffCommand.new(light))
puts remote.execute_commands
4. Decorator Pattern:
Use Case: Dynamically adding behavior to objects, such as enhancing a coffee's features.
Example:
class Coffee
def cost; 5; end
def description; "Basic Coffee"; end
end
class MilkDecorator
def initialize(coffee); @coffee = coffee; end
def cost; @coffee.cost + 2; end
def description; "#{@coffee.description}, Milk"; end
end
Usage:
coffee = Coffee.new
coffee_with_milk = MilkDecorator.new(coffee)
puts coffee_with_milk.description
5. Context Pattern:
Use Case: Changing an object's behavior dynamically, such as switching payment methods.
Example:
class PaymentContext
def initialize(strategy); @strategy = strategy; end
def pay(amount); @strategy.pay(amount); end
end
Usage:
payment = PaymentContext.new(CreditCardPayment.new)
puts payment.pay(100)
6. Observer Pattern:
Use Case: Notifying dependents of changes, such as updating UI components on data change.
Example:
class Subject
def add_observer(observer); @observers << observer; end
def notify_observers; @observers.each(&:update); end
end
Usage:
subject = Subject.new
subject.add_observer(observer)
subject.notify_observers