组合(Composite)模式将对象组合成树形结构以表示“部分-整体”的层次结构。这样使得用户对单个对象和组合对象的使用具有一致性。

组合模式,听名字你可能比较陌生,但是你很可能是这种模式的用户,它的应用非常广泛,例如IOS里的UIView、Cocos2d-x里的Node以及Unity3d里的Transform都是典型的组合模式。

本文简单举个例子,假设我们要开发一款机甲类的游戏,机甲由身体、手臂、腿等组件组成,这些部件还可以搭载火箭助推器和激光加农炮等组件,那么我们就可以考虑使用组合模式来设计。

首先定义一个机器组件的抽象类:

public abstract class RobotComponent
{protected RobotComponent _parent = null;public virtual RobotComponent parent{ get { return _parent;} set{ if (_parent == value) {return;}if (_parent != null) {_parent.RemoveComponentFromList (this);}_parent = value;if (_parent != null) {_parent.AddComponentToList (this);}}}public virtual void RemoveFromParent (){parent = null;}protected List<RobotComponent> _children = new List<RobotComponent> ();protected virtual void AddComponentToList(RobotComponent component){if (!CanAddComponent (component)) {return;}if (!_children.Contains (component)) {_children.Add (component);}}public virtual RobotComponent AddComponent(RobotComponent component){component.parent = this;return component;}public RobotComponent AddComponent<T> () where T : RobotComponent, new(){RobotComponent component = new T ();return AddComponent (component);}protected virtual void RemoveComponentFromList (RobotComponent component){if (!_children.Contains (component)) {return;}_children.Remove (component);component._parent = null;}protected virtual bool CanAddComponent(RobotComponent component){return true;}
}

这个抽象类维护了一个RobotComponent类型的List,用来存放子组件,对外开放了AddComponent和RemoveFromParent方法以及Parent属性。

接着我们可能会考虑到某种类型的组件不能为它添加子组件,例如火箭助推器和激光加农炮,所以我们又定义了一个抽象类——LeafRobotComponent。

public abstract class LeafRobotComponent : RobotComponent
{   public override RobotComponent AddComponent(RobotComponent component){Console.WriteLine ("LeafRobotComponent cannot add component!");return null;}protected override void RemoveComponentFromList (RobotComponent component){Console.WriteLine ("LeafRobotComponent cannot add component! So removing component make no sense!");}
}

还有,机器人的身体应该不能被添加到其他组件上,所以需要再定义一个抽象类——RootRobotComponent。

public abstract class RootRobotComponent : RobotComponent
{   public override RobotComponent parent{ get { return null;} set{ Console.WriteLine ("RootRobotComponent cannot has a parent!");_parent = null;}}
}

这样我们就完成了一个包含根和叶的组合体系了。

然而还没有具体的功能,我们为RobotComponent添加一些属性,并修改CanAddComponent方法。

public abstract class RobotComponent
{protected RobotComponent _parent = null;public virtual RobotComponent parent{ get { return _parent;} set{ if (_parent == value) {return;}if (_parent != null) {_parent.RemoveComponentFromList (this);}_parent = value;if (_parent != null) {_parent.AddComponentToList (this);}}}public virtual void RemoveFromParent (){parent = null;}protected List<RobotComponent> _children = new List<RobotComponent> ();protected virtual void AddComponentToList(RobotComponent component){if (!CanAddComponent (component)) {return;}if (!_children.Contains (component)) {_children.Add (component);}}public virtual RobotComponent AddComponent(RobotComponent component){component.parent = this;return component;}public RobotComponent AddComponent<T> () where T : RobotComponent, new(){RobotComponent component = new T ();return AddComponent (component);}protected virtual void RemoveComponentFromList (RobotComponent component){if (!_children.Contains (component)) {return;}_children.Remove (component);component._parent = null;}protected virtual bool CanAddComponent(RobotComponent component){if (RemainingTech <= component.TechCost) {Console.WriteLine ("We do not have enough technology");return false;}return true;}protected int _attack = 0;public virtual int Attack{get {int ret = _attack;foreach (var comp in _children) {ret += comp.Attack;}return ret;}}protected int _speed = 0;public virtual int Speed{get {int ret = _speed;foreach (var comp in _children) {ret += comp.Speed;}return ret;}}protected int _techCost = 0;public virtual int TechCost{get {int ret = _techCost;foreach (var comp in _children) {ret += comp.TechCost;}return ret;}}protected int _maxTech = 0;public virtual int RemainingTech{get {int ret = _maxTech;foreach (var comp in _children) {ret -= comp.TechCost;if (ret < 0) {ret = 0;break;}}if (_parent != null && ret > _parent.RemainingTech) {ret = _parent.RemainingTech;}return ret;}}
}

然后我们定义继承自RootRobotComponent的RobotBody:

public class RobotBody:RootRobotComponent
{public RobotBody(){_maxTech = 100;}
}

继承自RobotComponent的RobotArm和RobotLeg:

public class RobotArm : RobotComponent
{public RobotArm(){_attack = 10;_techCost = 20;_maxTech = 10;}
}public class RobotLeg : RobotComponent
{public RobotLeg(){_attack = 5;_speed = 5;_techCost = 20;_maxTech = 10;}
}

以及继承自LeafRobotComponent的RocketBooster和LaserCannon:

public class RocketBooster : LeafRobotComponent
{public RocketBooster(){_techCost = 3;}public override int Speed{get {return 2;}}
}public class LaserCannon : LeafRobotComponent
{public LaserCannon(){_techCost = 3;}public override int Speed{get {return -1;}}public override int Attack{get {return 3;}}
}

然后我们就可以组装机甲了:

     RobotComponent robot = new RobotBody ();RobotComponent arm1 = new RobotArm ();//robot.AddComponent<RobotArm> ();RobotComponent arm2 = robot.AddComponent<RobotArm> ();RobotComponent leg1 = new RobotLeg ();//robot.AddComponent<RobotLeg> ();RobotComponent leg2 = robot.AddComponent<RobotLeg> ();arm1.AddComponent<LaserCannon> ();arm2.AddComponent<LaserCannon> ();leg1.AddComponent<RocketBooster> ();leg2.AddComponent<RocketBooster> ();robot.AddComponent<RocketBooster> ();robot.AddComponent<RocketBooster> ();robot.AddComponent (arm1);robot.AddComponent (leg1);robot.AddComponent<LaserCannon> ();Console.WriteLine (robot.RemainingTech);Console.WriteLine (robot.Speed);Console.WriteLine (robot.Attack);

输出:

We do not have enough technology

2

16

36

组合模式的优点:

1、定义了组合对象的层次结构,可以不断的递归产生各种复杂的组件。

2、简化了用户的代码,用户可以一致地使用组合组件和单个组件。

3、易于增加新类型的组件,新组件添加后可以和原来的组件一起使用。

缺点:

很难限制组合中的组件:有时候你可能希望一个组合只能包含某些特定的组件,就只能在运行时进行检查。

小话设计模式(九)组合模式相关推荐

  1. 小话设计模式:Builder模式

    尊重他人的劳动成果,转载请标明出处:http://blog.csdn.net/gengqiquan/article/details/52764455, 本文出自:[gengqiquan的博客] 有一天 ...

  2. 小话设计模式(番外二)委托模式

    委托(Delegate)模式定义了对象之间的一对一的关系,被委托方可以作为委托方的事件接收者或者数据源(Data Source),当它作为事件接受者的时候,可以认为它是一种特殊的观察者(参考小话设计模 ...

  3. 小话设计模式(十)外观模式

    外观(Fascade)模式定义一个高级的接口,将子系统里的一组接口整合起来,提供了一个统一的外观. 在以下情况下可以考虑使用外观模式: (1)设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观 ...

  4. C#软件设计——小话设计模式原则之:依赖倒置原则DIP

    前言:很久之前就想动笔总结下关于软件设计的一些原则,或者说是设计模式的一些原则,奈何被各种bootstrap组件所吸引,一直抽不开身.群里面有朋友问博主是否改行做前端了,呵呵,其实博主是想做" ...

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

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

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

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

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

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

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

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

  9. C#软件设计——小话设计模式原则之:接口隔离原则ISP

    前言:有朋友问我,设计模式原则这些东西在园子里都讨论烂了,一搜一大把的资料,还花这么大力气去整这个干嘛.博主不得不承认,园子里确实很多这方面的文章,并且不乏出色的博文.博主的想法是,既然要完善知识体系 ...

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

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

最新文章

  1. GARFIELD@01-24-2005
  2. fusion 360安装程序的多个实例正在同时运行。_SpringMVC运行原理
  3. POJ 2976 01分数规划基础题目
  4. android cts 编译,使用 Android studio 分析运行 CTS 用例
  5. SSH连接服务器报错(WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED)的解决方案
  6. Mac iterm2 终端优化
  7. 哲学家就餐(避免死锁)(多进程版)
  8. java sleep和wait区别
  9. ubuntu14.04 安装 pyv8
  10. MySQL数据库 资源
  11. 计算机输入什么指令关机,电脑自动关机命令是什么【详细介绍】
  12. hi3519叠加OSD
  13. 很哇塞的网页特效之字符串切换
  14. Linux安装rar压缩软件
  15. 微信小程序——给用户发送通知
  16. 一起学WEB HTML5 第1讲
  17. php+病毒代码,蠕虫病毒VB代码
  18. mysql repair 所有表_MySQL磁盘满repair多个表问题的解决
  19. python获取星期几_如何在Python中获取日期的星期几?
  20. [论文笔记]Trajectory Data Driven V2V/V2I Mode Switching and Bandwidth Allocation for Vehicle Networks

热门文章

  1. 加入收藏夹,设为首页代码,强制设为主页代码
  2. 联通下调国际漫游数据流量资费
  3. MFC 获取所有USB设备 列举所有USB设备 列举所有USB HUB
  4. 2021年三季度中国服装家纺行业A股上市企业营收排行榜:海澜之家业绩突出,再度蝉联榜单TOP1(附热榜TOP61详单)
  5. 【项目实战】 ---- 简单整合SpringBoot + MyBatis + Themyleaf小项目
  6. BUUCTF:[SWPUCTF 2016]Web blogsys
  7. 骨骼动画——论文与代码精读《Phase-Functioned Neural Networks for Character Control》
  8. zz一篇很赞同的文章:2008年以后房价会降?想都不要想
  9. 人在回路的数据准备技术研究进展
  10. 2022年化工自动化控制仪表考试试题模拟考试平台操作