rubyでデザインパターン abstract_factoryパターン

ドアを作るには専門のドア職人にお願いしなければなりません。
しかしドア職人も万能ではありません。木製のドアしか作れない職人、鉄製のドアしか作れない職人と専門があります。
この際のオブジェクトをグループ化したいです。つまり、木製のドアは木製のドアしか作れない職人と一緒にする。鉄製のドアは鉄製が得意な職人と一緒にするといった感じです。ここで心配なことがあります。木製のドアに鉄製のドアが専門の職人を一緒にするといったことがありえそうです。
これを解決するのがabstract_factoryパターンです。複数のオブジェクトをまとめて作るファクトリーといった感じです。

class Door
 def getDescription
 end
end

class WoodenDoor < Door
    def getDescription
        puts "木のドアです。"
    end
    
end

class IronDoor < Door
    def getDescription
        puts "私は鉄のドアです。"
    end
end

class DoorFittingExpert
    def getDescription
    end
end

class Welder < DoorFittingExpert
    def getDescription
        puts "私が取り付けられるのは木製のドアだけです。"
    end
end

class Carpenter < DoorFittingExpert
    def getDescription
        puts "私が取り付けられるのは鉄製のドアだけです。"
    end
end

class DoorFactory
    def makeDoor
    end
    
    def makeFittingExpert
    end
end

class WoodenDoorFactory < DoorFactory
    def makeDoor
        WoodenDoor.new
    end
    
    def makeFittingExpert
        Welder.new
    end
end

class IronDoorFactory < DoorFactory
    def makeDoor
        IronDoor.new
    end
    
    def makeFittingExpert
        Carpenter.new
    end
end

wooden_door_factory = WoodenDoorFactory.new
door = wooden_door_factory.makeDoor
expert = wooden_door_factory.makeFittingExpert
door.getDescription
expert.getDescription

iron_door_factory = IronDoorFactory.new
door = iron_door_factory.makeDoor
expert = iron_door_factory.makeFittingExpert
door.getDescription
expert.getDescription

rubyでデザインパターン factory_methodパターン

面接官が面接を行います。しかし、一人でマーケターやエンジニアなどすべて職種の面接官を一人で行うことは出来ません。エンジニアの面接はエンジニアにお願いし、マーケターの面接はマーケターにしてもらいましょう。
ここでのfactoryはHiringManagerです。このクラスのサブクラスであるDevelopmentManagerとMarketingManagerでmakeInterviewerというメソッドを用意しクラス生成を行なっている。このメソッドのことをファクトリーメソッドという。
テンプレートメソッドパターンをどのオブジェクトを生成するかに使ったパターンです。factory_methodパターンはtemplate_methodパターンの一種と言える。

class Interviewer
    def askQuestion
    end
end

class Developer < Interviewer
    def askQuestion
        puts "開発について"
    end
    
end

class CommunityExecutive < Interviewer
    def askQuestion
        puts "コミュニティについて"
    end
    
end


class HiringManager
    def makeInterviewer
        
    end
    
    def takeInterview
        interviewer = makeInterviewer
        interviewer.askQuestion
    end
end

class DevelopmentManager < HiringManager
    def makeInterviewer
        Developer.new
    end
end

class MarketingManager < HiringManager
    def makeInterviewer
        CommunityExecutive.new
    end
    
end
    
marketer = MarketingManager.new
developer = DevelopmentManager.new

marketer.takeInterview
developer.takeInterview

rubyでデザインパターン simple_factoryパターン

module Door
	
	def getWidth
	end

  def getHeight
  end
end

class WoodenDoor
  include Door
  attr_reader :width, :height

  def initialize(width, height)
    @width = width
    @height = height
  end

  def name
    "木製のドアです。"
  end

end

class DoorFactory

  def self.makeDoor(width, height)
    WoodenDoor.new(width, height)
  end
end

door = DoorFactory::makeDoor(100, 200)
puts door.width
puts door.height
puts door.name

simple factoryパターンは、クライアントが必要とするインスタンスを生成するもの。このとき、インスタンス生成ロジックはクライアントから見えないようにうまく隠しておきます。
WoodernDoorを生成する前に何かロジックを加える必要がある場合はこのようにファクトリーで隠蔽するのが良い。コードを書く人はDoorFactoryに引数渡すと後はなんか知らんけどちゃんとしたドア返ってくるわぐらいの感覚でいられる。

rubyでデザインパターン commandパターン

class Bulb
  def turnOn
    puts "電気がつきました"
  end

  def turnOff
    puts "真っ暗です"
  end
end

class Command
  def execute
  end

  def undo
  end

  def redo
  end
end

class TurnOn < Command
  def initialize(bulb)
    @bulb = bulb
  end

  def execute
    @bulb.turnOn
  end

  def undo
    @bulb.turnOff
  end

  def redo
    execute
  end
end

class TrunOff < Command
  def initialize(bulb)
    @bulb = bulb
  end

  def execute
    @bulb.turnOff
  end

  def undo
    @bulb.turnOn
  end

  def redo
    execute
  end
end

class RemoteControll
  def submit(command)
    @command = command.execute
  end
end

bulb = Bulb.new
turnOn = TurnOn.new(bulb)
turnOff = TrunOff.new(bulb)
remote_controll = RemoteControll.new
remote_controll.submit(turnOn)
remote_controll.submit(turnOff)
#出力
#電気がつきました
#真っ暗です

rubyでデザインパターン compositeパターン

あるオブジェクトの集合で構成されたオブジェクトも同一のインターフェースをもつパターンです。

class Employee

  attr_reader :salary, :name

  def initialize(name, salary)
    @name = name
    @salary = salary
  end

end

class Developer < Employee

  attr_reader :role

  def initialize(name, salary, role)
    super(name, salary)
    @role = role
  end
end

class Designer < Employee

  attr_reader :role

  def initialize(name, salary, role)
    super(name, salary)
    @role = role
  end
end

class Organization
  def initialize
    @Employees = []
  end

  def addEmployee(employee)
    @Employees << employee 
  end

  def salary
    @NetSalary = 0
    @Employees.each do |employee|
      @NetSalary = @NetSalary + employee.salary
    end
    @NetSalary
  end
end

John = Developer.new('John', 20, 'developer')
Aya = Designer.new('Aya', 18, 'designer')
organizatin = Organization.new

organizatin.addEmployee(John)
organizatin.addEmployee(Aya)

puts John.salary
puts Aya.salary
puts organizatin.salary

#出力
#20
#18
#38

rubyでデザインパターン adapterパターン

ライオンを狩るハンタークラスがあったのですが
急遽、野犬も狩るように言われてしまいました。
しかし、野犬はライオンとは別のインターフェイスを持っているので
このままではうまく使えません。
そこで野犬クラスを包み込んだようなadapterクラスを用意して中継する感じです。
このパターンは仕方なくって感じがしますね・・・
もちろん初めから野犬も狩猟の対象になることが分かっていたのなら野犬も同じインターフェイスを備えるべきです。

class Lion
  def roar
    
  end
end

class AfricanLion < Lion
  def roar
    "がおー"
  end
end

class Hunter
  def hunt(target)
    puts "ターゲットは#{target.roar}と威嚇している!"
  end
end

class WildDog
  def bark
    "わん"
  end
end

class WildDOgAdapter < Lion

  def initialize(dog)
    @dog = dog
  end

  def roar
    @dog.bark
  end
end

african_lion = AfricanLion.new

wild_dog = WildDog.new
wild_dog_adapter = WildDOgAdapter.new(wild_dog)

hunter = Hunter.new
hunter.hunt(african_lion)
hunter.hunt(wild_dog_adapter)

#出力
#ターゲットはがおーと威嚇している!
#ターゲットはわんと威嚇している!
#