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

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

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

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

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

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

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

1.组合模式的例子

组合模式结构图:

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

  1. //抽象的部件类描述将来所有部件共有的行为
  2. public abstract class Component
  3. {
  4. protected string name;
  5. public string Name
  6. {
  7. get
  8. {
  9. return name;
  10. }
  11. set
  12. {
  13. name = value;
  14. }
  15. }
  16. //添加部件
  17. public abstract void Add(Component component);
  18. //删除部件
  19. public abstract void Remove(Component component);
  20. //遍历所有子部件
  21. public abstract void eachChild();
  22. }
  23. //组合部件类
  24. public class Leaf : Component
  25. {
  26. //叶子节点不具备添加的能力,所以不实现
  27. public override void Add(Component component)
  28. {
  29. throw new NotImplementedException();
  30. }
  31. //叶子节点不具备添加的能力必然也不能删除
  32. public override void Remove(Component component)
  33. {
  34. throw new NotImplementedException();
  35. }
  36. //叶子节点没有子节点所以显示自己的执行结果
  37. public override void eachChild()
  38. {
  39. Console.WriteLine("{0}执行了..",name);
  40. }
  41. }
  42. //组合类
  43. public class Composite : Component
  44. {
  45. //用来保存组合的部件
  46. List<Component> myList = new List<Component>();
  47. //添加节点 添加部件
  48. public override void Add(Component component)
  49. {
  50. myList.Add(component);
  51. }
  52. //删除节点 删除部件
  53. public override void Remove(Component component)
  54. {
  55. myList.Remove(component);
  56. }
  57. //遍历子节点
  58. public override void eachChild()
  59. {
  60. Console.WriteLine("{0}执行了..", name);
  61. foreach (Component c in myList)
  62. {
  63. c.eachChild();
  64. }
  65. }
  66. }
  67. static void Main(string[] args)
  68. {
  69. //构造根节点
  70. Composite rootComponent = new Composite();
  71. rootComponent.Name = "根节点";
  72. //添加两个叶子几点,也就是子部件
  73. Leaf l = new Leaf();
  74. l.Name = "叶子节点一";
  75. Leaf l1 = new Leaf();
  76. l1.Name = "叶子节点二";
  77. rootComponent.Add(l);
  78. rootComponent.Add(l1);
  79. //遍历组合部件
  80. rootComponent.eachChild();
  81. }

运行结果如下:

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

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

首先:

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

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

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

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

  1. /// <summary>
  2. /// 店面类 抽象出来的店面部件
  3. /// </summary>
  4. public abstract class Storefront
  5. {
  6. //店名
  7. protected string storeName = string.Empty;
  8. public string StoreName
  9. {
  10. get
  11. {
  12. return storeName;
  13. }
  14. }
  15. //添加店面
  16. public abstract void Add(Storefront store);
  17. //删除店面
  18. public abstract void Remove(Storefront store);
  19. //定义所有部件公用的行为 刷卡行为
  20. public abstract void PayByCard();
  21. }
  22. public class StoreOrBranch : Storefront
  23. {
  24. //构造函数
  25. public StoreOrBranch() { }
  26. public StoreOrBranch(string storeName)
  27. {
  28. this.storeName = storeName;
  29. }
  30. List<Storefront> myStoreList = new List<Storefront>();
  31. //刷卡消费
  32. public override void PayByCard()
  33. {
  34. Console.WriteLine("店面{0}的积分已累加进该会员卡", storeName);
  35. foreach (Storefront sf in myStoreList)
  36. {
  37. sf.PayByCard();
  38. }
  39. }
  40. //增加店面
  41. public override void Add(Storefront store)
  42. {
  43. myStoreList.Add(store);
  44. }
  45. //解除店面
  46. public override void Remove(Storefront store)
  47. {
  48. myStoreList.Remove(store);
  49. }
  50. }
  51. public class JoinInStore : Storefront
  52. {
  53. //构造函数
  54. public JoinInStore() { }
  55. public JoinInStore(string storeName)
  56. {
  57. this.storeName = storeName;
  58. }
  59. //刷卡消费
  60. public override void PayByCard()
  61. {
  62. Console.WriteLine("店面{0}的积分已累加进该会员卡", storeName);
  63. }
  64. public override void Add(Storefront store)
  65. {
  66. throw new NotImplementedException();
  67. }
  68. public override void Remove(Storefront store)
  69. {
  70. throw new NotImplementedException();
  71. }
  72. }
  73. static void Main(string[] args)
  74. {
  75. StoreOrBranch store = new StoreOrBranch("朝阳总店");
  76. StoreOrBranch brach = new StoreOrBranch("东城分店");
  77. JoinInStore jstore = new JoinInStore("海淀×××店一");
  78. JoinInStore jstore1 = new JoinInStore("上地×××店二");
  79. brach.Add(jstore);
  80. brach.Add(jstore1);
  81. store.Add(brach);
  82. store.PayByCard();
  83. }
运行结果如下:

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

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

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

转载于:https://blog.51cto.com/wangboyang/752433

设计模式系列-组合模式相关推荐

  1. Android设计模式系列-组合模式

    Android中对组合模式的应用,可谓是泛滥成粥,随处可见,那就是View和ViewGroup类的使用.在android UI设计,几乎所有的widget和布局类都依靠这两个类. 组合模式,Compo ...

  2. 每天一个设计模式之组合模式

    作者按:<每天一个设计模式>旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现.诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :) ...

  3. 1、【设计模式】组合模式

    java设计模式之组合模式 [学习难度:★★★☆☆,使用频率:★★★★☆]  树形结构在软件中随处可见,例如操作系统中的目录结构.应用软件中的菜单.办公系统中的公司组织结构等等,如何运用面向对象的方式 ...

  4. 详解设计模式:组合模式

    组合模式(Composite Pattern),又叫部分整体模式,是 GoF 的 23 种设计模式中的一种结构型设计模式. 组合模式 是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组 ...

  5. 结构型设计模式之组合模式

    结构型设计模式之组合模式 组合模式 应用场景 优缺点 主要角色 组合模式结构 分类 透明组合模式 创建抽象根节点 创建树枝节点 创建叶子节点 客户端调用 安全组合模式 创建抽象根节点 创建树枝节点 创 ...

  6. java设计模式之组合模式(树形层级)

    java设计模式之组合模式 学习难度:★★★☆☆,使用频率:★★★★☆]  树形结构在软件中随处可见,例如操作系统中的目录结构.应用软件中的菜单.办公系统中的公司组织结构等等,如何运用面向对象的方式来 ...

  7. Java设计模式之组合模式详解

    文章目录 详解Java设计模式之组合模式 案例引入 组合模式 定义 模式类图结构 相关角色 典型代码 案例分析 类图设计 实例代码 结果分析 JavaJDK中的组合模式 透明组合模式 安全组合模式 组 ...

  8. Java设计模式之组合模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  9. 设计模式系列——克隆模式

    设计模式系列--克隆模式 前言 native关键字 原型模式适用的场景 原型模式的应用 原型模式实战 浅克隆 深克隆 前言 在我们工作中经常能遇到大幅度使用get或set方法,例如下面这样的代码 pu ...

最新文章

  1. angularjs 日期倒计时效果
  2. NetBeans IDE 7.0 Beta 发布
  3. windows下利用sox批量将PCM转为WAV
  4. spanning-tree extend system-id
  5. chrome切换前端模式_H5暗黑模式在京东收银台中的实践
  6. python 01列表异或_python基础篇三
  7. 类库、委托、is/as
  8. 基于Java的酒店管理系统论文
  9. 2021年度总结——波澜不惊
  10. mac空格代表图标_最糟糕的图标代表功能
  11. 由“外”向“内”,安踏破解运动科技“卡脖子”难题
  12. 【iOS】应用跳转到系统应用
  13. 2021年中国网上办理车辆和驾驶证业务情况:网上办理车辆和驾驶证相关业务6769万次其中,网上发放临时号牌2043万副[
  14. 【干货】BIOS、UEFI、MBR、GPT、GRUB 到底是什么意思?
  15. 一直显示无法连接服务器失败,老显示无法连接服务器失败
  16. linux /etc/security/login.cfg,AIX用户管理
  17. 用latex在写MDPI的文章文献References部分时遇到的问题(! Misplaced alignment tab character .)
  18. 【工作】python识别不同国家语言类型
  19. 《802.11无线网络权威指南》摘录
  20. 第21课 微信小程序视频标签显示弹幕

热门文章

  1. VTK:几何对象之EarthSource
  2. Qt Creator使用补充工具栏
  3. C语言快速排序 quick sort 算法(附完整源码)
  4. C++确定对象被使用前已先被初始化
  5. C++尽量在operater=中处理“自我赋值”
  6. 计算机 java_Java程序到底是如何运行的?
  7. 神奇的机器人评课_《聪明的机器人》教学反思
  8. python数据库优化_Python学习(二十九)—— pymysql操作数据库优化
  9. mybatis jar包_Java修行第039天---Mybatis框架
  10. java 3d游戏_不放一行代码分享一下java实现3D游戏逻辑