求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
从理发店流程抽象设计模式中的组合模式
 

发布于2012-5-9

 

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

进到美发店,便有热情的服务生招呼,显示洗头,挑选造型师,开始剪发,剪发中被造型师推荐了各种各样的收费项目,我只选择了一样软化头发。完毕之后,看了 下单子哇塞、好贵噢,不过造型师给我剪的发型我还是很喜欢的,我决定以后还找他剪,但是又太贵,无奈中,发型师向我推荐了他们的会员卡,全场所有项目均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 myList = new List();

        //添加节点 添加部件
        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.什么情况下使用组合模式

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


相关文章

企业架构、TOGAF与ArchiMate概览
架构师之路-如何做好业务建模?
大型网站电商网站架构案例和技术架构的示例
完整的Archimate视点指南(包括示例)
相关文档

数据中台技术架构方法论与实践
适用ArchiMate、EA 和 iSpace进行企业架构建模
Zachman企业架构框架简介
企业架构让SOA落地
相关课程

云平台与微服务架构设计
中台战略、中台建设与数字商业
亿级用户高并发、高可用系统架构
高可用分布式架构设计与实践

 
分享到
 
 
     


专家视角看IT与架构
软件架构设计
面向服务体系架构和业务组件
人人网移动开发架构
架构腐化之谜
谈平台即服务PaaS


面向应用的架构设计实践
单元测试+重构+设计模式
软件架构师—高级实践
软件架构设计方法、案例与实践
嵌入式软件架构设计—高级实践
SOA体系结构实践


锐安科技 软件架构设计方法
成都 嵌入式软件架构设计
上海汽车 嵌入式软件架构设计
北京 软件架构设计
上海 软件架构设计案例与实践
北京 架构设计方法案例与实践
深圳 架构设计方法案例与实践
嵌入式软件架构设计—高级实践
更多...