【设计模式攻略】结构型模式之Composite模式

概要
具备一系列既有独立功能,又需要排列组合其中的几种功能来达成一些复合的新功能时,可以采用组合模式。比如说,你设计了一个备份模块,有email备份,note备份,message备份,log备份等一系列备份功能,而你又会需要同时备份它们中间不定的几种时,考虑用组合模式吧。它能组合对象处理,而又不增加额外的耦合,并保证接口一致,以及模块的易用性和扩展性。

目的
自由组合既有对象处理来实现复合对象,保证单一对象和复合对象具有统一的对外接口。

实例
Command模式应该都比较熟悉了,这里结合Command模式来举个例子。
有时我们会把行为(action)封装为类,比如我们需要如下这些action,保存action,备份action,发送action,显示action等,那么考虑用Command模式来进行封装,如下所示:

class CommandAction {
public:
     virtual void Execute ();
};
class SaveAction : public CommandAction {
public:
     virtual void Execute ();
};
class BackupAction : public CommandAction {
public:
     virtual void Execute ();
};
class SendAction : public CommandAction {
public:
     virtual void Execute ();
};
......


我们有需要实现几种复合行为,Composite1是(保存+备份)action,Composite2是(保存+显示)action,Composite3是(保存+显示+发送)action,不要告诉我你会如下这样去实现!为每种复合行为都设计一个类?


class CommandAction {
public:
     virtual void Execute ();
};
class Composite1: public CommandAction {
public:
     ......
     virtual void Execute () {
          mSave->Execute();
          mBackup->Execute();          
     }
private:
     SaveAction* mSave;
     BackupAction * mBackup;     
};

(省略Composite2, Composite3)
很容易看出,这不是一种好方法,扩展性太差,增加了类间的耦合度。如果又需要更多的不同的复合行为,难道再继续追加类?太复杂,太烦了,模块维护者看到这种设计会疯掉的。
那么,让我们看看如果用Composite模式是怎么解决的。


class CommandAction {
public:
     virtual void Execute() = 0;
     virtual void AddAction(CommandAction* action);
     virtual void DeleteAction(CommandAction* action);
};
class CompositeAction : public CommandAction {
public:
     ......
     virtual void Execute() {
          list<CommandAction*>::iterator it;
          for (it = mCompositor.begin(); it != mCompositor.end(); it++) {
               if (*it != NULL) {
                    (*it)->Execute(pack);
               }
          }
     }
     virtual void AddAction(CommandAction* action) {
          if (action != NULL) {
               mCompositor.push_back(action);
          }
     }
     virtual void DeleteAction(CommandAction* action) {
          list<CommandAction*>::iterator it;
          if (action != NULL) {
               for (it = mCompositor.begin(); it != mCompositor.end(); it++) {
               if (*it == action) {
               mCompositor.erase(it);
               break;
               }
          }
     }
private:
     list<CommandAction*> mCompositor;
};

设计一个CompositeAction类,具有跟其他Action统一的接口(Execute),CompositeAction包含一个基类CommandAction的list容器对象,通过AddAction和DeleteAction,可以由Client调用方自由追加和删除复合对象中需要包含的Action,而Execute方法会执行list中push进来的所有Action。

应用
在文件系统库中,存储文件节点包含文件夹和文件的组合,而一些UI库中,复杂的UI也经常会由很多可定制的基本UI组成,当然相关应用还有很多,在这些库中,Composite模式经常会被使用。另外Composite模式也经常跟Decorator模式结合起来使用,关于Decorator模式,在下一单元会有详细的说明。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目 录 序言 前言 读者指南 第1章 引言 1 1.1 什么是设计模式 2 1.2 Smalltalk MVC中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象接口 9 1.6.4 描述对象的实现 10 1.6.5 运用复用机制 13 1.6.6 关联运行时刻和编译时刻的 结构 15 1.6.7 设计应支持变化 16 1.7 怎样选择设计模式 19 1.8 怎样使用设计模式 20 第2章 实例研究:设计一个文档编 辑器 22 2.1 设计问题 23 2.2 文档结构 23 2.2.1 递归组合 24 2.2.2 图元 25 2.2.3 组合模式 27 2.3 格式化 27 2.3.1 封装格式化算法 27 2.3.2 Compositor和Composition 27 2.3.3 策略模式 29 2.4 修饰用户界面 29 2.4.1 透明围栏 29 2.4.2 Monoglyph 30 2.4.3 Decorator 模式 32 2.5 支持多种视感标准 32 2.5.1 对象创建的抽象 32 2.5.2 工厂类和产品类 33 2.5.3 Abstract Factory模式 35 2.6 支持多种窗口系统 35 2.6.1 我们是否可以使用Abstract Factory 模式 35 2.6.2 封装实现依赖关系 35 2.6.3 Window和WindowImp 37 2.6.4 Bridge 模式 40 2.7 用户操作 40 2.7.1 封装一个请求 41 2.7.2 Command 类及其子类 41 2.7.3 撤消和重做 42 2.7.4 命令历史记录 42 2.7.5 Command 模式 44 2.8 拼写检查和断字处理 44 2.8.1 访问分散的信息 44 2.8.2 封装访问和遍历 45 2.8.3 Iterator类及其子类 46 2.8.4 Iterator模式 48 2.8.5 遍历和遍历过程中的动作 48 2.8.6 封装分析 48 2.8.7 Visitor 类及其子类 51 2.8.8 Visitor 模式 52 2.9 小结 53 第3章 创建型模式 54 3.1 Abstract Factory(抽象工厂)— 对象创建型模式 57 3.2 Builder(生成器)—对象创建型 模式 63 3.3 Factory Method(工厂方法)— 对象创建型模式 70 3.4 Prototype(原型)—对象创建型 模式 87 3.5 Singleton(单件)—对象创建型 模式 84 3.6 创建型模式的讨论 89 第4章 结构型模式 91 4.1 Adapter(适配器)—类对象结构型 模式 92 4.2 Bridge(桥接)—对象结构型 模式 100 4.3 Composite(组成)—对象结构型 模式 107 4.4 Decorator(装饰)—对象结构型 模式 115 4.5 FACADE(外观)—对象结构型 模式 121 4.6 Flyweight(享元)—对象结构型 模式 128 4.7 Proxy(代理)—对象结构型 模式 137 4.8 结构型模式的讨论 144 4.8.1 Adapter与Bridge 144 4.8.2 CompositeDecorator与Proxy 145 第5章 行为模式 147 5.1 CHAIN OF RESPONSIBIL ITY(职责链) —对象行为型模式 147 5.2 COMMAND(命令)—对象行为型 模式 154 5.3 INTERPRETER(解释器)—类行为型 模式 162 5.4 ITERATOR(迭代器)—对象行为型 模式 171 5.5 MEDIATOR(中介者)—对象行为型 模式 181 5.6 MEMENTO(备忘录)—对象行为型 模式 188 5.7 OBSERVER(观察者)—对象行为型 模式 194 5.8 STATE(状态)—对象行为型模式 201 5.9 STRATEGY(策略)—对象行为型 模式 208 5.10 TEMPLATE METHOD(模板方法) —类行为型模式 214 5.11 VISITOR(访问者)—对象行为型 模式 218 5.12 行为模式的讨论 228 5.12 1 封装变化 228 5.12.2 对象作为参数 228 5.12.3 通信应该被封装还是被分布 229 5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 本书简史 234 6.7 模式界 235 6.8 Alexander 的模式语言 235 6.9 软件中的模式 236 6.10 邀请参与 237 6.11 临别感想 237 附录A 词汇表 238 附录B 图示符号指南 241 附录C 基本类 244 参考文献 249

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值