zoukankan      html  css  js  c++  java
  • 【设计模式系列】结构型模式之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:
         ......
         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模式,在下一单元会有详细的说明。

  • 相关阅读:
    怎么用代码弹回 UITableView 中左滑出来的删除按钮
    android 利用 aapt 解析 apk 得到应用名称 包名 版本号 权限等信息
    Missy
    html5 websocket + node.js 实现网页聊天室
    android 代码混淆示例
    android volley 发送 POST 请求
    android viewpager 拿到当前显示的 fragment 的实例
    android actionbar viewpager 实现类微信主界面布局
    (转)初学Git及简单搭建git服务器和客户端
    error: Cannot find OpenSSL's <evp.h> Mac
  • 原文地址:https://www.cnblogs.com/secbook/p/2655122.html
Copyright © 2011-2022 走看看