命令模式:核心是将具体的动作提取出来,放入它自己的对象中的模式(和策略模式,用到的是代理形式)

#一般的命令形式
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

results matching ""

    No results matching ""