命令设计模式的综合

时间:2012-05-12 03:40:50

标签: ruby oop design-patterns ooad

有没有人在Ruby中使用复合命令?这是我在各种设计模式文献中提到的一种设计模式混合,听起来非常强大,但却找不到任何有趣的用例或代码。

2 个答案:

答案 0 :(得分:3)

受到总体思路和the sample pattern implementations in this blog post的启发,这里有一个可能的样子:

class CompositeCommand
  def initialize(description, command, undo)
    @description=description; @command=command; @undo=undo
    @children = []
  end
  def add_child(child); @children << child; self; end
  def execute
    @command.call() if @command && @command.is_a?(Proc)
    @children.each {|child| child.execute}
  end
  def undo
    @children.reverse.each {|child| child.undo}
    @undo.call() if @undo && @undo.is_a?(Proc)
  end
end

使用软件安装程序的应用程序进行样本使用:

class CreateFiles < CompositeCommand
  def initialize(name)
    cmd = Proc.new { puts "OK: #{name} files created" }
    undo = Proc.new { puts "OK: #{name} files removed" }
    super("Creating #{name} Files", cmd, undo)
  end
end

class SoftwareInstaller
  def initialize; @commands=[]; end
  def add_command(cmd); @commands << cmd; self; end
  def install; @commands.each(&:execute); self; end
  def uninstall; @commands.reverse.each(&:undo); self end
end

installer = SoftwareInstaller.new
installer.add_command(
  CreateFiles.new('Binary').add_child(
    CreateFiles.new('Library')).add_child(
    CreateFiles.new('Executable')))
installer.add_command(
  CreateFiles.new('Settings').add_child(
    CreateFiles.new('Configuration')).add_child(
    CreateFiles.new('Preferences')).add_child(
    CreateFiles.new('Help')))
installer.install # => Runs all commands recursively
installer.uninstall

答案 1 :(得分:1)

我正在尝试自己理解这种模式,并且一直在考虑以这种方式建模的东西。

复合模式的基本思想是需要在某些方面以相同的方式处理项目和集合的情况。集合可能包含项目和子集合的混合,可以根据需要嵌套。

我有一些想法(从Design Patterns in RubyRuby Under a Microscope借用一些):

文件系统

您可以询问文件的大小,并返回一个简单的值。您还可以询问文件夹的大小,并返回其文件和子文件夹大小的总和。子文件夹当然会返回其文件和子文件夹的总和。

同样,可以移动,重命名,删除,备份,压缩等文件和文件夹。

系统命令

命令对象可以使用run方法。该方法可以通过运行任意数量的具有子命令等的子命令来工作。如果所有子命令都返回true,它可以返回true,并且可以根据子项的统计信息(经过的时间,修改的文件等)报告统计信息。 / p>

公司层级

个人,团队,部门和整个公司都可以被视为有工资,带来收入,完成工作单位等。

军事单位

在游戏中,士兵可以拥有防御和进攻统计数据,可以被告知移动到某个位置,攻击基地等等。团队和师可以采用相同的方式对待。

重量或货币价值

装满箱子的卡车的重量包括每个箱子的重量。每个盒子的重量包括每件物品的重量,部件等等。

同样,金融投资组合的货币价值是其所有资产的价值。其中一些资产可能是包含多个股票的指数基金。您可以买卖个人股票或整个投资组合。

GUI元素

窗口可以由帧组成,帧由帧组成,帧由帧组成。任何元素都可以定位,着色,聚焦,隐藏等。

编程语言中的表达式

当Ruby解释器评估一个表达式时,它会通过将其分解为表达式树(一个抽象语法树)并评估每个表达式来实现,并通过返回到顶部来实现最终值。树。从某种意义上说,树的每个级别都会被问到同样的问题:“你的价值是什么?”

举个简单的例子,找到((4 + 8) * 2)) + 9的值的第一步是找到4 + 8的值。