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

    设计模式系列-组合模式

     

          今天下班客厅的灯确实亮堂了许多,照照镜子感觉自己一下苍老许多,看来还是灯光暗比较好,看不出来自己的憔悴啊,哈哈,其实还是头发长了,决定出去剪发。

           进到美发店,便有热情的服务生招呼,显示洗头,挑选造型师,开始剪发,剪发中被造型师推荐了各种各样的收费项目,我只选择了一样软化头发。完毕之后,看了下单子哇塞、好贵噢,不过造型师给我剪的发型我还是很喜欢的,我决定以后还找他剪,但是又太贵,无奈中,发型师向我推荐了他们的会员卡,全场所有项目均5折,最近因为圣诞节还在搞活动这期间办卡的可享受折上折8.6,我心想那这下就太划算了,而且他们总店,分店都可以用,所以毫不犹豫的办了张会员卡。。。囧。。。。

           到家后稍微有点后悔,我竟然一时冲动花了那么多钱办了张剪发的会员卡,不过办也办了,只好自己安慰安慰自己,心想,办了卡可以打折上折,而且那么多分店想去哪家去哪家,顿时心情好为能好一点了,突然间想到了一个模式,跟现在的场景很合适,名字叫《组合模式》,为什么说跟组合模式很相似呢?

           先看看组合模式的定义吧,在《大话设计模式一书中》组合模式的定义为:“将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

           那就拿我剪发办卡的事情来分析一下吧。

           首先,一张卡可以在总部,分店,加盟店使用,那么总部可以刷卡,分店也可以刷卡,加盟店也可以刷卡,这个属性结构的店面层级关系就明确啦。

           那么,总店刷卡消费与分店刷卡消费是一样的道理,那么总店与分店对会员卡的使用也具有一致性。

          1.组合模式的例子

            组合模式结构图:

            那么组合模式的实例如下:

    复制代码
     //抽象的部件类描述将来所有部件共有的行为
        public abstract class Component
        {
            protected string name;
            public string Name
            {
                get
                {
                    return name;
                }
                set
                {
                    name = value;
                }
            }
            //添加部件
            public abstract void Add(Component component);
            //删除部件
            public abstract void Remove(Component component);
            //遍历所有子部件
            public abstract void eachChild();
        }

        //组合部件类
        public class Leaf : Component
        {
            //叶子节点不具备添加的能力,所以不实现
            public override void Add(Component component)
            {
                throw new NotImplementedException();
            }

            //叶子节点不具备添加的能力必然也不能删除
            public override void Remove(Component component)
            {
                throw new NotImplementedException();
            }

            //叶子节点没有子节点所以显示自己的执行结果
            public override void eachChild()
            {
                Console.WriteLine("{0}执行了..",name);
            }
        }

        //组合类
        public class Composite : Component
        {
            //用来保存组合的部件
            List<Component> myList = new List<Component>();

            //添加节点 添加部件
            public override void Add(Component component)
            {
                myList.Add(component);
            }

            //删除节点 删除部件
            public override void Remove(Component component)
            {
                myList.Remove(component);
            }

            //遍历子节点
            public override void eachChild()
            {
                Console.WriteLine("{0}执行了..", name);
                foreach (Component c in myList)
                {
                    c.eachChild();
                }
            }
        }
        static void Main(string[] args)
        {
                //构造根节点
                Composite rootComponent = new Composite();
                rootComponent.Name = "根节点";

                //添加两个叶子几点,也就是子部件
                Leaf l = new Leaf();
                l.Name = "叶子节点一";
                Leaf l1 = new Leaf();
                l1.Name = "叶子节点二";

                rootComponent.Add(l);
                rootComponent.Add(l1);

                //遍历组合部件
                rootComponent.eachChild();
         }
    复制代码

            运行结果如下:

          

          2.应用组合模式的会员卡消费

            那么我们就根据我们会员卡的消费,来模拟一下组合模式的实现吧!let's go!

            首先:

                   1.我们的部件有,总店,分店,加盟店!

                   2.我们的部件共有的行为是:刷会员卡

                   3.部件之间的层次关系,也就是店面的层次关系是,总店下有分店、分店下可以拥有加盟店。

            有了我们这几个必要条件后,我的要求就是目前店面搞活动当我在总店刷卡后,就可以累积相当于在所有下级店面刷卡的积分总额,设计的代码如下:

    复制代码
     /// <summary>
        /// 店面类 抽象出来的店面部件
        /// </summary>
        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<Storefront> myStoreList = new List<Storefront>();
            //刷卡消费
            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)
            {
                throw new NotImplementedException();
            }

            public override void Remove(Storefront store)
            {
                throw new NotImplementedException();
            }
        }

       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();
        }
    复制代码

          运行结果如下:

          

           这样在累积所有子店面积分的时候,就不需要去关心子店面的个数了,也不用关系是否是叶子节点还是组合节点了,也就是说不管是总店刷卡,还是加盟店刷卡,都可以正确有效的计算出活动积分。

          3.什么情况下使用组合模式

           引用大话设计模式的片段:“当发现需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑组合模式了。”

  • 相关阅读:
    WampServer Mysql配置
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 陶陶摘苹果2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 质因数2
    Java实现 蓝桥杯VIP 算法提高 前10名
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4834129.html
Copyright © 2011-2022 走看看