🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
 廊坊的风一如既往的在窗外刮着,天地间肆意地飘洒,纵情在一刹那,为何现在只剩下风吹乱我的发,乱蓬蓬的,还是去超市逛逛吧,买吃的`(*∩_∩*)′,走进华联超市,热情的店员招呼着我,开始为我介绍,推荐各种各样商品,店员向我推荐了他们的会员卡,全场所有项目均八折,每逢节假日打五折,我心想那太划算了,而且他们总店,分店,加盟店都可以用,所以就办了张会员卡。今天我们的设计模式就从超市会员卡开始说起。 这个俨然就是我们设计模式中的组合模式----组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。看下面的两幅图片: ![](https://box.kancloud.cn/2015-12-30_5683743dcbed6.jpg)            ![](https://box.kancloud.cn/2015-12-30_5683743ddb91a.jpg) 上面两幅图片我们可以看做是一个文件结构,对于这样的结构我们称之为树形结构。在《大话设计模式》中我们了解到可以通过调用某个方法来遍历整个树,当我们找到某个叶子节点后,就可以对叶子节点进行相关的操作。我们可以将这颗树理解成一个大的容器,容器里面包含很多的成员对象,这些成员对象即可是容器对象也可以是叶子对象。但是由于容器对象和叶子对象在功能上面的区别,使得我们在使用的过程中必须要区分容器对象和叶子对象,但是这样就会给客户带来不必要的麻烦,对于客户而言,始终希望能够一致的对待容器对象和叶子对象。这就是组合模式的设计动机:组合模式定义了如何将容器对象和叶子对象进行递归组合,使得客户在使用的过程中无须进行区分,可以对他们进行一致的处理。下面一起来看一下组合模式的结构图:        ![](https://box.kancloud.cn/2015-12-30_5683743dec640.jpg) 以上述在华联超市办会员卡为例,看看组合模式是如何在代码中实现:         ~~~ using System;   using System.Collections.Generic;   using System.Linq;   using System.Text;   using System.Threading.Tasks;      namespace ConsoleApplication3   {       class Program       {           static void Main(string[] args)           {               StoreOrBranch store = new StoreOrBranch("北京总店");               StoreOrBranch brach = new StoreOrBranch("廊坊分店");               JoinInStore jstore = new JoinInStore("安徽加盟店一");               JoinInStore jstore1 = new JoinInStore("海南加盟店二");                  brach.Add(jstore);               brach.Add(jstore1);               store.Add(brach);                  store.PayByCard();           }       }             ///        /// 店面类 抽象出来的店面部件       ///        public abstract class Storefront       {           //店名           protected string storeName = string.Empty;           public string StoreName           {               get               {                   return storeName;               }           }              //添加店面           public abstract void Add(Storefront store);           //删除店面           public abstract void Remove(Storefront store);              //定义所有部件公用的行为 刷卡行为           public abstract void PayByCard();       }          public class StoreOrBranch : Storefront       {           //构造函数           public StoreOrBranch() { }           public StoreOrBranch(string storeName)           {               this.storeName = storeName;           }           List myStoreList = new List();           //刷卡消费           public override void PayByCard()           {               Console.WriteLine("店面{0}的积分已累加进该会员卡", storeName);               foreach (Storefront sf in myStoreList)               {                   sf.PayByCard();               }           }              //增加店面           public override void Add(Storefront store)           {               myStoreList.Add(store);           }              //解除店面           public override void Remove(Storefront store)           {               myStoreList.Remove(store);           }       }          public class JoinInStore : Storefront       {           //构造函数           public JoinInStore() { }           public JoinInStore(string storeName)           {               this.storeName = storeName;           }           //刷卡消费           public override void PayByCard()           {               Console.WriteLine("店面{0}的积分已累加进该会员卡", storeName);           }              public override void Add(Storefront store)           { }              public override void Remove(Storefront store)           { }       }            }   ~~~ 组合模式的目的是:让客户端不再区分操作的是组合对象还是叶子对象,而是以一个统一的方式来操作。实现这个目标的关键之处,是设计一个抽象的组件类,让它可以代表组合对象和叶子对象。这样一来,客户端就不用区分到底是组合对象还是叶子对象了,只需要全部当成组件对象进行统一的操作就可以了。