博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ruby设计模式之合成模式1————基本的合成模式
阅读量:6174 次
发布时间:2019-06-21

本文共 2542 字,大约阅读时间需要 8 分钟。

前几天在《戏说设计模式》这篇文章中看到了一段关于组合模式的描述:

COMPOSITE—Mary今天过生日。“我过生日,你要送我一件礼物。”“嗯,好吧,去商店,你自己挑。”“这件T恤挺漂亮,买,这条裙子好看,买,这个包也不错,买。”“喂,买了三件了呀,我只答应送一件礼物的哦。”“什么呀,T恤加裙子加包包,正好配成一套呀,小姐,麻烦你包起来。” “……”,MM都会用Composite模式了,你会了没有?

这个例子还是比较通俗的解释了合成模式的。

所谓合成模式就是指将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式就是一个处理对象的树结构的模式。合成模式把部分与整体的关系用树结构表示出来。合成模式使得客户端把一个个单独的成分对象和由他们复合而成的合成对象同等看待。

定义是不是云雾缭绕让人看不明白,没关系再举例说明。

假设我们要做一块蛋糕(cake),我们可能会经历如下的流程:准备面粉->和面->发酵->切割->烘焙->加奶油->加黄油等等。于是我们就可以说做蛋糕这个任务是由一系列的子任务,比如切割、烘焙等组合而成。这些子任务又可能又更细粒度的子任务组合而成。

纵观这些子任务,他们都有一些共同的属性,比如会花费一定的时间,每个子任务都有自己的名字等等。

再看由这些子任务组合而成的更大的任务。这个大一些的任务本质上也是任务,只不过它是由子任务组合而成,仅此而已。

GoF将组合模式描述为: The sum acts like one of the parts。当你需要构造基于继承关系的对象树,并且希望你的代码将单一对象和组合对象一视同仁时,你最好试试组合模式。

在组合模式总GoF将实现统一接口或你需要实现对象树的基类的对象称作:component。在我们的蛋糕例子里,component应该是所有任务的抽象基类。

继承自component、且无法再进行细粒度细分的类为称为leaf,这个应该很好理解。

那么同理leaf的父节点就是composite了,他是更高层级的component。

下面的代码演示了composite的具体实现,其实现了我们的做蛋糕流程。

class Task  attr_reader :name   def initialize name    @name = name  end   def get_time_required    0.0  endend  class AddDryIngredientsTask < Task   def initialize    super 'Add dry ingredients'  end   def get_time_required    1.0  endend class MixTask < Task   def initialize    super 'Mix that batter up'  end   def get_time_required    3.0  end  end class MakeBatterTask < Task   def initialize    super 'Make batter'    @sub_tasks = []    add_sub_task AddDryIngredientsTask.new    add_sub_task MixTask.new  end   def add_sub_task task    @sub_tasks << task  end   def remove_sub_task    @sub_tasks.delete task  end   def get_time_required    time = 0.0    @sub_tasks.each {|task| time += task.get_time_required}    time  endend

在上面的代码中,我们的component就是Task基类。所有的leaf和composite都是继承自该类。Task类实现了统一的接口gettimerequired,表示完成该task需要的时间。

MixTask是leaf,继承自Task且不能进行进一步的细化。

MakeBatterTask是composite。其维护了1个subtasks的子集,所有组成其的子集都保存在其中。另外其提供了一系列的维护subtasks的方法,如新增1个subtask,移除1个subtask。

下面的代码优化了MakeBatterTask类。我们可以直接抽象出Composite类。该类的主要任务是维护属于Composite的subtasks。因为我们可能有若干个Composite类的实例,因此这样做是灵活且有效率的。

class CompositeTask < Task  def initialize name    super name    @sub_tasks = []  end   def add_sub_task task    @sub_tasks << task  end  def remove_sub_task    @sub_tasks.delete task  end   def get_time_required    time = 0.0    @sub_tasks.each {|task| time += task.get_time_required}    time  endend class MakeBatterTask < CompositeTask  def initialize    super 'Make batter'    add_sub_task AddDryIngredientsTask.new    add_sub_task MixTask.new  endend

总的说来合成模式适合表示整体和部分的关系,或者说是零件和模块的关系,若干零件合成一个模块,而从本质上来说模块也可以是一个零件;合成模式可以用来构造树用来表示整体和部分的关系。合成模式将零件和组合而成的模块同等看待。

转载地址:http://bcqba.baihongyu.com/

你可能感兴趣的文章
CRM安装(二)
查看>>
Eclipse工具进行Spring开发时,Spring配置文件智能提示需要安装STS插件
查看>>
NSURLCache内存缓存
查看>>
jquery click嵌套 事件重复注册 多次执行的问题
查看>>
Dev GridControl导出
查看>>
开始翻译Windows Phone 8 Development for Absolute Beginners教程
查看>>
Python tablib模块
查看>>
站立会议02
查看>>
Windows和Linux如何使用Java代码实现关闭进程
查看>>
0428继承性 const static
查看>>
第一课:从一个简单的平方根运算学习平方根---【重温数学】
查看>>
NET反射系统
查看>>
Oracle12C本地用户的创建和登录
查看>>
使用JS制作一个鼠标可拖的DIV(一)——鼠标拖动
查看>>
HDU problem 5635 LCP Array【思维】
查看>>
leetcode10. 正则表达式匹配
查看>>
redis常用命令--zsets
查看>>
springcloud--Feign(WebService客户端)
查看>>
网络攻击
查看>>
sorting, two pointers(cf div.3 1113)
查看>>