Created
June 1, 2018 05:46
-
-
Save Mardiniii/209aa9fa3e5ed451d50f291a2025135a to your computer and use it in GitHub Desktop.
Design Patterns using Ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Adaptee | |
class Hammer | |
def swing | |
'swing' | |
end | |
end | |
# Target | |
class Tool | |
def initialize(adapter) | |
@adapter = adapter | |
end | |
def use_tool | |
@adapter.use_tool | |
end | |
end | |
# Adapter | |
class HammerAdapter | |
def initialize(hammer) | |
@hammer = hammer | |
end | |
def use_tool | |
@hammer.swing | |
end | |
end | |
hammer = Hammer.new | |
hammer_adapter = HammerAdapter.new(hammer) | |
tool = Tool.new(hammer_adapter) | |
puts tool.use_tool | |
puts tool.use_tool | |
puts tool.use_tool |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Payment | |
attr_reader :country, :amount | |
def initialize(country, amount) | |
@country = country | |
@amount = amount | |
end | |
end | |
# North american payments | |
class PayPalHandler < PaymentHandler | |
COUNTRIES = ['United States', 'Mexico', 'Canada'] | |
private_constant :COUNTRIES | |
def accept_payment(payment) | |
if COUNTRIES.include?(payment.country) | |
charge(payment) | |
true | |
else | |
false | |
end | |
end | |
private | |
def charge(payment) | |
# Logic to process payment with PayPal | |
puts "Processing payment for #{payment.country} for #{payment.amount} with PayPal" | |
end | |
end | |
# Latin american payments | |
class StripeHandler < PaymentHandler | |
COUNTRIES = ['Colombia', 'Brasil', 'Argentina'] | |
private_constant :COUNTRIES | |
def accept_payment(payment) | |
if COUNTRIES.include?(payment.country) | |
charge(payment) | |
true | |
else | |
false | |
end | |
end | |
def charge(payment) | |
# Logic to process payment with Stripe | |
puts "Processing payment for #{payment.country} for #{payment.amount} with Stripe" | |
end | |
end | |
class PaymentHandler | |
attr_accessor :next_receiver | |
def initialize(next_receiver = nil) | |
@next_receiver = next_receiver | |
end | |
def process_payment(payment) | |
if accept_payment(payment) | |
return | |
elsif @next_receiver | |
@next_receiver.process_payment(payment) | |
else | |
reject_payment(payment) | |
end | |
end | |
def reject_payment(payment) | |
puts "The payment for #{payment.country} for #{payment.amount} can not be processed with any gateway" | |
end | |
def accept_payment(payment) | |
raise NotImplementedError | |
end | |
end | |
north_american_payment = Payment.new('United States', 450) | |
latin_american_payment = Payment.new('Colombia', 300) | |
unvalid_european_payment = Payment.new('Spain', 150) | |
chain_of_responsibility = StripeHandler.new(PayPalHandler.new()) | |
chain_of_responsibility.process_payment(latin_american_payment) | |
chain_of_responsibility.process_payment(north_american_payment) | |
chain_of_responsibility.process_payment(unvalid_european_payment) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Driver | |
def pick_up_at(address, date) | |
puts "Ready for picking up at #{address} on #{date}" | |
end | |
end | |
class Restaurant | |
def order_for(address, plate) | |
puts "Ready for cooking #{plate} to #{address}" | |
end | |
end | |
# Services | |
class DriverService | |
attr_reader :address, :date, :driver | |
def initialize(address, date) | |
@address = address | |
@date = date | |
@driver = Driver.new | |
end | |
def execute | |
driver.pick_up_at(address, date) | |
end | |
end | |
class FoodService | |
attr_reader :address, :plate | |
def initialize(address, plate) | |
@address = address | |
@plate = plate | |
@restaurant = Restaurant.new | |
end | |
def execute | |
@restaurant.order_for(address, plate) | |
end | |
end | |
class Secretary | |
def initialize(name) | |
@name = name | |
@request_list = [] | |
end | |
def add_request(request) | |
@request_list << request | |
end | |
def dispatch_requests | |
@request_list.each do |request| | |
request.execute | |
end | |
end | |
end | |
class Boss | |
def submit_request(secretary, request) | |
secretary.add_request(request) | |
end | |
end | |
boss = Boss.new | |
secretary = Secretary.new('Linda') | |
driver_service = DriverService.new("7901 South Main Street", Time.now) | |
food_service = FoodService.new("7901 South Main Street", 'Baby Beef') | |
boss.submit_request(secretary, driver_service) | |
boss.submit_request(secretary, food_service) | |
driver_service = DriverService.new("Casa Tia Ilse", Time.now + 1 * 86400) | |
food_service = FoodService.new("7901 South Main Street", 'Salad and shrimp') | |
boss.submit_request(secretary, driver_service) | |
boss.submit_request(secretary, food_service) | |
driver_service = DriverService.new("Mountain view hospital", Time.now + 2 * 86400) | |
food_service = FoodService.new("7901 South Main Street", 'Bandeja Paisa') | |
boss.submit_request(secretary, driver_service) | |
boss.submit_request(secretary, food_service) | |
secretary.dispatch_requests |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'byebug' | |
class Ticket | |
attr_accessor :price | |
def price | |
99.99 | |
end | |
end | |
class TicketWithSpecialAccess | |
def initialize(ticket) | |
@ticket = ticket | |
end | |
def price | |
@ticket.price + 49.99 | |
end | |
end | |
class TicketWithDiscount | |
def initialize(ticket) | |
@ticket = ticket | |
end | |
def price | |
@ticket.price * 0.5 | |
end | |
end | |
ticket = Ticket.new | |
ticket = TicketWithSpecialAccess.new(ticket) | |
ticket = TicketWithDiscount.new(ticket) | |
puts ticket.price |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Shape | |
def draw | |
raise NotImplementedError | |
end | |
end | |
class Triangle < Shape | |
def initialize(a, b, c) | |
@a = a | |
@b = b | |
@c = c | |
end | |
def draw | |
"drawing triangle with sides: #{@a} #{@b} #{@c}" | |
end | |
end | |
class Circle < Shape | |
def initialize(radius) | |
@radius = radius | |
end | |
def draw | |
"drawing circle with radius: #{@radius}" | |
end | |
end | |
class Square < Shape | |
def initialize(side) | |
@side = side | |
end | |
def draw | |
"drawing square with side #{@side}" | |
end | |
end | |
class Rectangule < Shape | |
def initialize(width, height) | |
@width = width | |
@height = height | |
end | |
def draw | |
"drawing rectangule with with #{@width} and height #{@height}" | |
end | |
end | |
class ShapeFactory | |
TYPES = { | |
triangle: Triangle, | |
circle: Circle, | |
square: Square, | |
rectangule: Rectangule | |
} | |
private_constant :TYPES | |
def self.for(shape, attributes) | |
raise NotImplementedError if TYPES[shape].nil? | |
TYPES[shape].new(*attributes) | |
end | |
end | |
triangle = ShapeFactory.for(:triangle, [5, 6, 7]) | |
puts triangle.draw | |
circle = ShapeFactory.for(:circle, [5]) | |
puts circle.draw | |
square = ShapeFactory.for(:square, [7]) | |
puts square.draw | |
rectangule = ShapeFactory.for(:rectangule, [5, 6]) | |
puts rectangule.draw |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Observable logic | |
module Observable | |
def initialize | |
@observers = [] | |
end | |
def add_observer(observer) | |
@observers << observer | |
end | |
def delete_observer(observer) | |
@observers.delete(observer) | |
end | |
def notify_observers(date) | |
@observers.each { |o| o.update(date) } | |
end | |
end | |
module DateFormat | |
def format(date) | |
date.strftime("%A - %B %d, %Y") | |
end | |
end | |
# Observable | |
class League | |
include Observable | |
include DateFormat | |
def initialize(name) | |
super() | |
@name = name | |
end | |
def set_game_day(args) | |
date = Time.new(*args) | |
puts "League: The game will be on: #{format(date)}" | |
notify_observers(date) | |
end | |
end | |
# Observers | |
class SoccerTeam | |
include DateFormat | |
def initialize(name, league) | |
@name = name | |
league.add_observer(self) | |
end | |
def update(date) | |
puts "Team #{@name}: We are ready for the game on #{format(date)}" | |
end | |
end | |
class Referee | |
include DateFormat | |
def initialize(name, league) | |
@name = name | |
league.add_observer(self) | |
end | |
def update(date) | |
puts "Referee #{@name}: I am ready for the game on #{format(date)}" | |
end | |
end | |
soccer_league = League.new('World Cup Soccer League') | |
colombia = SoccerTeam.new('Colombia', soccer_league) | |
japan = SoccerTeam.new('Japan', soccer_league) | |
referee = Referee.new('Pierluigi Collina', soccer_league) | |
soccer_league.set_game_day([2018, 06, 19, 17, 30, 0, "+03:00"]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Node | |
def accept(visitor) | |
raise NotImpelementedError.new | |
end | |
end | |
module Visitable | |
def accept(visitor) | |
visitor.visit self | |
end | |
end | |
class IntegerNode < Node | |
include Visitable | |
attr_reader :value | |
def initialize(value) | |
@value = value | |
end | |
end | |
class Ast < Node | |
def initialize | |
@nodes = [] | |
@nodes << IntegerNode.new(2) | |
@nodes << IntegerNode.new(3) | |
end | |
def accept(visitor) | |
@nodes.each do |node| | |
node.accept visitor | |
end | |
end | |
end | |
class DoublerVisitor | |
def visit(subject) | |
puts subject.value * 2 | |
end | |
end | |
class TriplerVisitor | |
def visit(subject) | |
puts subject.value * 3 | |
end | |
end | |
ast = Ast.new | |
puts "Doubler:" | |
ast.accept DoublerVisitor.new | |
puts "Tripler:" | |
ast.accept TriplerVisitor.new |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment