设计模式(C#)——08组合模式
推荐阅读:
游戏通常包含许多视图。主视图中显示角色。有一个子视图,显示玩家的积分。有一个子视图,显示游戏中剩下的时间。
可维护性应该是游戏开发过程中的主要关注点。每个视图不应具有不同的函数名称或不同的访问点。相反,你想要为每个视图提供一个统一的访问点,即相同的函数调用应该既能够访问主视图也能够访问子视图。这种统一的接入点可以使用组合设计模式。
游戏开发中常用的设计模式之一组合模式
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。
组合模式依据树形结构来组合对象,用来表示部分以及整体层次。它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
组合模式使得用户对单个对象和组合对象的使用具有一致性。
组合模式的要素:
1、抽象构件(Component ):它是所有叶子构件和容器构件的共同父类,里面声明了叶子构件和容器构件的所有方法;
2、容器构件(Composite):定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(Add)和删除(Delete)等。
3、叶子构件(Leaf):在组合中表示叶子结点对象,叶子结点没有子结点,对于从父类中继承过来的容器构件的方法,由于它不能实现,可以抛出异常;
此模式将每个视图放置在树状结构中,从而为每个视图提供统一的访问点。取代了需要用不同的函数来访问不同的子视图,组合模式可以用相同的函数访问任何视图。继续使用上面的列子,使用组合模式来分解游戏中的视图如下:

下面举一个Unity中组件的层级结构的例子来帮助大家更加清除的学习组合模式。在Unity中每个GameObject对象都有一个Transform组件,这个组件提供了几个和游戏对象分层操作有关的方法和变量。
变量:
childCount:代表子组件数量
parent:代表父组件中的Transform对象引用
方法:
DetachChildren:解除所有子组件与本身的关联
Find: 寻找子组件
GetChild: 使用Index的方式取回子组件
IsChildOf: 判断某个Transform对象是否为其子组件
SetParent:设置某个Transform对象为其父组件
再仔细分析,则可以将Unity3D的Transform类当成是一个通用类,因为它并不明显得可以察觉出其下又被再分成“目录节点”或是单纯的“单的终端节点”
其实应该说,Transform类完全符合组合模式的需求:“让客户端在操作各个对象或组件时是一致的”。
因此对于场景上所有的游戏对象GameObject,可以不管它们最终代表的什么,对于所有操作都能正确反应。
下面介绍下如何使用代码实现:
1.创建抽象构件(IComponent):
public abstract class IComponent
{
protected string m_Value;
public abstract void Operation();
public virtual void Add(IComponent theComponent) {}
public virtual void Remove(IComponent theComponent) { }
public virtual IComponent GetChild(int index)
{
return null;
}
}
2、容器构件(Composite):
//节点类
public class Composite : IComponent
{
List<IComponent> m_Childs = new List<IComponent>();
public Composite(string Value)
{
m_Value = Value;
}
public override void Operation()
{
foreach (IComponent theComponent in m_Childs)
{
theComponent.Operation();
}
}
public override void Add(IComponent theComponent)
{
m_Childs.Add(theComponent);
}
public override void Remove(IComponent theComponent)
{
m_Childs.Remove(theComponent);
}
public override IComponent GetChild(int index)
{
return m_Childs[index];
}
}
3、叶子构件(Leaf)
//叶子类
public class Leaf : IComponent
{
public Leaf(string Value)
{
m_Value = Value;
}
public override void Operation(){}
}
4.使用组合模式:
//测试类
public class TestComposite
{
void UnitTest()
{
IComponent theRoot = new Composite("Root");
theRoot.Add(new Leaf("Leaf1"));
theRoot.Add(new Leaf("Leaf2"));
IComponent theChild1 = new Composite("Child1");
theChild1.Add(new Leaf("Child1.Leaf1"));
theChild1.Add(new Leaf("Child1.Leaf2"));
theRoot.Add(theChild1);
IComponent theChild2 = new Composite("Child2");
theChild2.Add(new Leaf("Child2.Leaf1"));
theChild2.Add(new Leaf("Child2.Leaf2"));
theChild2.Add(new Leaf("Child2.Leaf3"));
theRoot.Add(theChild2);
theRoot.Operation();
}
}
总结
优点:
界面与功能分离,更具移植性
工作切分更容易,当脚本移除,就可以让UI设计交由美术和企划组装
界面更改不影响项目:只要维持组件名称不变,界面的更改就不容易影响到游戏现有程序功能的运行。
缺点:
组件名称重复,如果没有将层级切分好,就容易出现该问题,在工具名称添加警告可以解决。
组件更名不易:组件名需要通过字符串来查找,界面组件一旦不能获取,则会出现null值,和不正确的场景,应对的方法同样是在UnityTool中添加查找失败的警告。
设计模式(C#)——08组合模式的更多相关文章
- java23种设计模式——八、组合模式
目录 java23种设计模式-- 一.设计模式介绍 java23种设计模式-- 二.单例模式 java23种设计模式--三.工厂模式 java23种设计模式--四.原型模式 java23种设计模式-- ...
- [设计模式] javascript 之 组合模式
组合模式说明 组合模式用于简单化,一致化对单组件和复合组件的使用:其实它就是一棵树: 这棵树有且只有一个根,访问入口,如果它不是一棵空树,那么由一个或几个树枝节点以及子叶节点组成,每个树枝节点还包含自 ...
- 设计模式学习之组合模式(Composite,结构型模式)(10)
转载地址:http://www.cnblogs.com/zhili/p/CompositePattern.html 一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系 ...
- 设计模式之:组合模式(Composite)
支持原创:http://blog.csdn.net/hguisu/article/details/7530783 设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构 ...
- [js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表
所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理, ...
- C#设计模式之十组合模式(Composite)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第四个模式,该模式是[组合模式],英文名称是:Composite Pattern.当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达 ...
- 设计模式学习心得<组合模式 Composite>
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式, ...
- C#设计模式之九组合模式(Composite Pattern)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第四个模式,该模式是[组合模式],英文名称是:Composite Pattern.当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达的意 ...
- Java设计模式学习记录-组合模式
前言 今天要介绍的设计模式是组合模式,组合模式也是结构型设计模式的一种,它主要体现了整体与部分的关系,其典型的应用就是树形结构.组合是一组对象,其中的对象可能包含一个其他对象,也可能包含一组其他对象. ...
随机推荐
- Java简单公式计算器
最近给公司开发业务代码时,碰到一个场景,简单描述是这样的: 客户要向咱们公司定制一件产品,这个产品呢,有很多属性,那公司得根据这些属性报价呀,怎么报价呢?公司针对某种类型的产品有一个基准价,在同类产品 ...
- 如何启用linux的路由转发功能
如何使用iptables的NAT功能把红帽企业版Linux作为一台路由器使用? 方法: 提示: 以下方法只适用于红帽企业版Linux 3 以上. 1.打开包转发功能: echo "1&quo ...
- linux初学者-正则表达式
在windows中,是没有办法批量处理文件的,但是在linux系统中,可以通过命令直接处理一系列文件,这些文件的处理就需要用到正则表达式.这同样可以应用与目录. 1.处理多个文件 正则表达式中批量 ...
- chapter02 - 03
1.分别用cat \tac\nl三个命令查看文件/etc/ssh/sshd_config文件中的内容,并用自己的话总计出这三个文档操作命令的不同之处? 答:cat /etc/ssh/sshd_conf ...
- java往文本文件中写入信息并修改
题目要求: 1.可以往一个文本文档中写入员工信息:name,id和详情 2.可以更改name package FanCQ.Xue.practice; import java.io.*;import j ...
- WIN10安装VC6.0无法使用的解决办法
WIN10安装VC6.0无法使用的解决办法 VC6.0确实已经太老了 VC6.0实在是很久以前的开发工具了,现在的win10已经对该软件不兼容,但是为了能使抱着怀旧情节的初学者们能像教科书或老前辈们一 ...
- Cassandra之Docker环境实践
Cassandra简介 Cassandra是一个开源分布式NoSQL数据库系统. 它最初由Facebook开发,用于储存收件箱等简单格式数据,集GoogleBigTable的数据模型与Amazon D ...
- .Net异步编程详解入门
前言 今天周五,早上起床晚了.赶着挤公交上班.但是目前眼前有这么几件事情.刷牙洗脸.泡牛奶.煎蛋.在同步编程眼中.先刷牙洗脸,然后烧水泡牛奶.再煎蛋,最后喝牛奶吃蛋.毫无疑问,在时间紧促的当下.它完了 ...
- 1、Java小白之路前言
大二一年准备好好学习Java,养成一个良好的习惯写博客,但是由于各种各样的原因,并没有坚持下来.而正好又赶上大三结束,去实习,发现自己的基础还是有些薄弱,所以决定,重新走上这条Java小白之路. 时隔 ...
- ibatis 核心原理解析
最近查找一个生产问题的原因,需要深入研究 ibatis 框架的源码.虽然最后证明问题的原因与 ibatis 无关,但是这个过程加深了对 ibatis 框架原理的理解. 这篇文章主要就来讲讲 ibati ...