命令模式:核心是将具体的动作提取出来,放入它自己的对象中的模式(和策略模式,用到的是代理形式)
#一般的命令形式
class SlickButton
def initialize(command)
@command = command
end
def on_button_push
@command.execute if @command
end
end
class SaveCommand
def execute
puts "save command"
end
end
obj = SlickButton.new(SaveCommand.new)
obj.on_button_push
#使用代码块的命令形式,适用于简单的命令形式,而且块对象只能调用call方法
class SlickButton
def initialize(&block)
@command = block
end
def on_button_push
@command.call if @command
end
end
obj = SlickButton.new do
puts "block button"
end
obj.on_button_push
命令模式的结构:命令模式在结构上十分简单,它是由享有共同接口的类所组成
下面使用记录操作的命令作为示例
require 'fileutils'
class Command
attr_accessor :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
f= File.open(@path, "w")
f.write(@contents)
f.close
end
def unexecute
File.delete(@path)
end
end
class DeleteFile < Command
def initialize(path)
super("delete file: #{path}")
@path = path
end
def execute
if File.exist?(@path)
@contents = File.read(@path)
end
File.delete(@path)
end
def unexecute
if @contents
f = File.open(@path, "w")
f.write(@contents)
f.close
end
end
end
class CopyFile < Command
def initialize(source, target)
super("copy file #{source} to #{target}")
@source = source
@target = target
end
def execute
FileUtils.copy(@source, @target)
end
def unexecute
File.delete(@target)
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("./create.txt", "create file"))
cmds.add_command(DeleteFile.new("./create.txt"))
cmds.add_command(CopyFile.new("./command.rb", "./demo_cc.txt"))
cmds.execute
cmds.unexecute
p cmds.description
从上面的代码实现中可以看到,命令类是由基于Command的子类并且实现同一个接口的子类们构成的,其中CompositeCommand实现了组合模式。
https://medium.com/@dljerome/design-patterns-in-ruby-command-802b785d1bbd