「Rubyによるデザインパターン」の読書メモです。
コマンドをクラスにするパターン
class SlickButton
attr_accessor :command
def initialize(command)
@command = command
end
def on_button_push
@command.execute if @command
end
end
class SaveCommand
def execute
p "#{self.class}##{__method__}"
end
end
save_button = SlickButton.new(SaveCommand.new)
save_button.on_button_push
コマンドをコードブロックにするパターン
コマンドは何か特定のことを行うコードの単純なラッパーで、唯一の存在理由は、適切なタイミングでコードを実行することです。
class SlickButton
attr_accessor :command
def initialize(&block)
@command = block
end
def on_button_push
@command.call if @command
end
end
new_button = SlickButton.new do
p "#{self.class}"
end
new_button.on_button_push
記録 + 戻るの例
class Command
attr_reader :description
def initialize(description)
@description = description
end
def execute
end
def unexecute
end
end
class CreateFile < Command
def initialize(path, contents)
super("Create file: #{path}")
@path = path
@contents = contents
end
def execute
p "#{self.class}##{__method__}"
end
def unexecute
p "#{self.class}##{__method__}"
end
end
class DeleteFile < Command
def initialize(path)
super("Delete file: #{path}")
@path = path
end
def execute
p "#{self.class}##{__method__}"
end
def unexecute
p "#{self.class}##{__method__}"
end
end
class CopyFile < Command
def initialize(source, target)
super("Copy file: #{source} to #{target}")
@source = source
@target = target
end
def execute
p "#{self.class}##{__method__}"
end
def unexecute
p "#{self.class}##{__method__}"
end
end
class CompositeCommand < Command
def initialize
@commands = []
end
def add_command(cmd)
@commands << cmd
end
def execute
@commands.each {|cmd| cmd.execute}
end
def unexecute
@commands.reverse.each {|cmd| cmd.unexecute}
end
def description
description = ''
@commands.each {|cmd| description += cmd.description + "\n"}
description
end
end
cmds = CompositeCommand.new
cmds.add_command(CreateFile.new('file1.txt', 'hello world'))
cmds.add_command(CopyFile.new('file1.txt', 'file2.txt'))
cmds.add_command(DeleteFile.new('file1.txt'))
puts cmds.description
p '---'
cmds.execute
p '---'
cmds.unexecute
注意
Commandパターンのポイントは何を行うかの決定と、それの実行とを分離することです。
まとめ
Commandパターンでは、ある特定の動作を実行するオブジェクトを構築します。「特定」という部分が重要です。