zoukankan      html  css  js  c++  java
  • 11 组合模式

    组合模式(Composite)定义:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

    UML类图如下:

    组合模式

    比如《大话》中举的例子,公司总部在北京,然后在南京、杭州设有办事处,总公司和分支办事处都有相似的组织结构,比如都有人力资源部、财务部等。如下图:

    搜狗截图20161204221156

    再有HeadFirst举的关于菜单的例子,如下图:

    搜狗截图20161204221355

    如果程序需要表达上面例子中的公司层级组织或是菜单层级的结构,就可以采用组合模式。

    组合模式能让我们用树形方式创建对象的结构,树里面包含了组合以及个别的对象。使用组合结构,我们能把相同得操作应用在组合和个别对象上。换句话说,在大对数大多数情况下,我们可以忽略对象组合和个别对象之间的差别。这为编程带了了极大的方便。

    关于餐厅菜单的代码如下:

    MenuComponent类:

     1 class MenuComponent 
     2     {
     3         public virtual void Add(MenuComponent menuComponent)
     4         {
     5             throw new NotImplementedException();
     6         }
     7         public virtual void Remove(MenuComponent menuComponent)
     8         {
     9             throw new NotImplementedException();
    10         }
    11         public virtual MenuComponent GetChild(int i)
    12         {
    13             throw new NotImplementedException();
    14         }
    15         public virtual string GetName()
    16         {
    17             throw new NotImplementedException();
    18         }
    19         public virtual string GetDescription()
    20         {
    21             throw new NotImplementedException();
    22         }
    23         public virtual double GetPrice()
    24         {
    25             throw new NotImplementedException();
    26         }
    27         public virtual bool IsVegetarian()
    28         {
    29             throw new NotImplementedException();
    30         }
    31         public virtual void Print()
    32         {
    33             throw new NotImplementedException();
    34         }
    35     }
    View Code

     所有组件都必须继承MenuComponent类,类中的虚方法都默认抛出异常,子类根据需要进行重写。

    MenuItem类(比如午餐菜单中的某一道具体的菜):

     1  class MenuItem : MenuComponent
     2     {
     3         string name;
     4         string description;
     5         bool isVegetarian;
     6         double price;
     7 
     8         public MenuItem(string name, string description, bool isVegetarian, double price)
     9         {
    10             this.name = name;
    11             this.description = description;
    12             this.isVegetarian = isVegetarian;
    13             this.price = price;
    14         }
    15 
    16         public override string GetName()
    17         {
    18             return name;
    19         }
    20         public override string GetDescription()
    21         {
    22             return description;
    23         }
    24         public override double GetPrice()
    25         {
    26             return price;
    27         }
    28         public override bool IsVegetarian()
    29         {
    30             return isVegetarian;
    31         }
    32         public override void Print()
    33         {
    34             Console.Write("-----Name:{0}--Price:{1}--Description:{2}--{3}", name, price, description, (isVegetarian ? "V" : ""));
    35             Console.WriteLine();
    36         }
    37     }
    View Code

     Menu类(比如煎饼屋菜单、午餐菜单):

     1 class Menu : MenuComponent
     2     {
     3         List<MenuComponent> listMenuComponent = new List<MenuComponent>();
     4         string name;
     5         string description;
     6 
     7         public Menu(string name, string description)
     8         {
     9             this.name = name;
    10             this.description = description;
    11         }
    12 
    13         public override void Add(MenuComponent menuComponent)
    14         {
    15             listMenuComponent.Add(menuComponent);
    16         }
    17         public override void Remove(MenuComponent menuComponent)
    18         {
    19             listMenuComponent.Remove(menuComponent);
    20         }
    21         public override MenuComponent GetChild(int i)
    22         {
    23             return listMenuComponent[i];
    24         }
    25         public override string GetName()
    26         {
    27             return name;
    28         }
    29         public override string GetDescription()
    30         {
    31             return description;
    32         }
    33         public override void Print()
    34         {
    35             Console.WriteLine("--Name:{0}--Description:{1}", name, description);
    36             foreach (var item in listMenuComponent)
    37             {
    38                 item.Print();
    39             }
    40         }
    41     }
    View Code

     Menu类不必重写GetPrice()和IsVegetarian()方法,而且Menu类的Print()类比较特殊,需要遍历内部的所有MenuItem类并逐个打印。

  • 相关阅读:
    怎样检测数据类型
    怎样理解函数参数的传递
    怎样在微信H5中点击直接跳转到公众号
    怎样启动和关闭nginx服务器
    怎样测试nginx.conf配置文件的正确性
    怎样查找/搜索文件
    怎样创建用户组并添加用户进用户组
    怎样查看Nginx版本号
    怎样写一个Hello World!
    怎样理解基本类型(原始类型)的数据和引用类型的数据
  • 原文地址:https://www.cnblogs.com/zhixin9001/p/6132213.html
Copyright © 2011-2022 走看看