programs/oop_patterns/oop_patterns.rb
tests/_examples/programs/oop_patterns/oop_patterns.rb in the metorex repository.
# Object-Oriented Design Patterns
# === Strategy Pattern ===
# Different sorting/formatting strategies
class UpperFormatter
def format(text)
text.upcase
end
end
class LowerFormatter
def format(text)
text.downcase
end
end
class Printer
def initialize(formatter)
@formatter = formatter
end
def print_formatted(text)
puts @formatter.format(text)
end
end
puts "=== Strategy Pattern ==="
upper = Printer.new(UpperFormatter.new)
lower = Printer.new(LowerFormatter.new)
upper.print_formatted("Hello World")
lower.print_formatted("Hello World")
# === Template Method Pattern ===
# Base class defines algorithm skeleton, subclasses fill in steps
class Report
def generate
puts self.header
puts self.body
puts self.footer
end
def header
"--- Report ---"
end
def footer
"--- End ---"
end
end
class SalesReport < Report
def body
"Total sales: $1000"
end
end
class InventoryReport < Report
def body
"Items in stock: 42"
end
def header
"*** Inventory ***"
end
def footer
"*** End ***"
end
end
puts ""
puts "=== Template Method Pattern ==="
SalesReport.new.generate
puts ""
InventoryReport.new.generate
# === Observer Pattern ===
# Objects subscribe to events and get notified
class EventEmitter
def initialize
@listeners = []
end
def on(&block)
@listeners.push(block)
end
def emit(data)
@listeners.each do |listener|
listener.call(data)
end
end
end
puts ""
puts "=== Observer Pattern ==="
emitter = EventEmitter.new
emitter.on do |data|
puts "Listener 1: #{data}"
end
emitter.on do |data|
puts "Listener 2: #{data}"
end
emitter.emit("event fired")
# === Decorator Pattern ===
# Wrap objects to add behavior
class BasicCoffee
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
class SugarDecorator
def initialize(coffee)
@coffee = coffee
end
def cost
@coffee.cost + 1
end
def description
"#{@coffee.description} + sugar"
end
end
puts ""
puts "=== Decorator Pattern ==="
coffee = BasicCoffee.new
puts "#{coffee.description}: $#{coffee.cost}"
coffee = MilkDecorator.new(coffee)
puts "#{coffee.description}: $#{coffee.cost}"
coffee = SugarDecorator.new(coffee)
puts "#{coffee.description}: $#{coffee.cost}"
Output:
=== Strategy Pattern ===
HELLO WORLD
hello world
=== Template Method Pattern ===
--- Report ---
Total sales: $1000
--- End ---
*** Inventory ***
Items in stock: 42
*** End ***
=== Observer Pattern ===
Listener 1: event fired
Listener 2: event fired
=== Decorator Pattern ===
Basic coffee: $5
Basic coffee + milk: $7
Basic coffee + milk + sugar: $8