Ruby/Design Patterns/Command

Материал из Wiki.crossplatform.ru

Версия от 17:10, 26 мая 2010; (Обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Содержание

An Easier Way of Command Pattern

class Commander
  attr_accessor :command
  def initialize(command)
    @command = command
  end
  def on_button_push
    @command.execute if @command
  end
end
class YourCommand
  def execute
  end
end
save_button = Commander.new( YourCommand.new )



Code Blocks as Commands

class Commander
  attr_accessor :command
  def initialize(&block)
    @command = block
  end
  def on_button_push
    @command.call if @command
  end
end
new_button = Commander.new do
   puts "asdf"
end



Commands That Record (Command and composite pattern)

class Command
  attr_reader :description
  def initialize(description)
    @description = description
  end
  def execute
  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
end
class DeleteFile < Command
  def initialize(path)
    super("Delete file: #{path}")
    @path = path
  end
  def execute
    File.delete(@path)
  end
end
class CopyFile < Command
  def initialize(source, target)
    super("Copy file: #{source} to #{target}")
    @source = source
    @target = target
  end
  def execute
    puts @source + " >>" + @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 description
    description = ""
    @commands.each {|cmd| description += cmd.description + "\n"}
    description
  end
end
cmds = CompositeCommand.new
cmds.add_command(CreateFile.new("file1.txt", "hello world\n"))
cmds.add_command(CopyFile.new("file1.txt", "file2.txt"))
cmds.add_command(DeleteFile.new("file1.txt"))
cmds.execute
puts(cmds.description)



Undo by a Command

class Command
  attr_reader :description
  def initialize(description)
    @description = description
  end
  def execute
  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.exists?(@path)
      @contents = File.read(@path)
    end
    f = 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
    puts @source + ">>" + @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 description
    description = ""
    @commands.each {|cmd| description += cmd.description + "\n"}
    description
  end
  def unexecute
    @commands.reverse.each { |cmd| cmd.unexecute }
  end  
end
cmds = CompositeCommand.new
cmds.add_command(CreateFile.new("file1.txt", "hello world\n"))
cmds.add_command(CopyFile.new("file1.txt", "file2.txt"))
cmds.add_command(DeleteFile.new("file1.txt"))
cmds.execute
puts(cmds.description)