从理发店流程抽象设计模式中的组合模式

开发 架构
理发店的会员卡很多人都办理过,那他们这种总店加分店的模式该如何抽象化成软件开发语言呢?我们可以借用组合模式来解决。

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

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

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

原文链接:http://www.cnblogs.com/doubleliang/archive/2011/12/27/2304104.html

【编辑推荐】

  1. Java I/O系统基础知识
  2. Java 远程文件对接
  3. Java生成树结构各点之间最短路径算法
  4. Java字符编码根本原理
  5. Java中对象的等价性比较

责任编辑:彭凡 来源: 博客园
相关推荐

2021-09-29 13:53:17

抽象工厂模式

2020-10-19 09:28:00

抽象工厂模式

2013-11-26 15:48:53

Android设计模式SDK

2021-04-19 21:25:48

设计模式到元

2021-03-06 22:50:58

设计模式抽象

2021-09-16 06:44:05

组合模式设计

2020-12-17 09:38:16

设计模式参数

2011-07-28 09:50:58

设计模式

2012-04-12 09:38:21

JavaScript

2009-01-15 10:55:29

JavaScript设计模式抽象工厂

2012-08-30 09:07:33

设计模式

2021-04-18 21:07:32

门面模式设计

2023-08-07 06:30:15

抽象工厂模式软件设计模式

2021-04-14 09:02:22

模式 设计建造者

2010-01-21 09:08:53

.NET设计模式

2019-04-24 09:43:46

代码开发工具

2021-03-10 08:20:54

设计模式OkHttp

2009-06-29 18:11:40

JSP设计模式

2011-07-14 14:46:46

设计模式

2012-04-10 10:04:26

并行编程
点赞
收藏

51CTO技术栈公众号