Java设计模式之从[魔兽世界包裹系统]分析组合(Composite)模式
来源:互联网 发布:电脑自动改mac地址 编辑:程序博客网 时间:2024/05/16 02:34
RPG游戏中的包裹(或者称为背包)是玩家携带物品的地方,它的大小决定着玩家能够携带物品数量。如在魔兽世界中,玩家起初的物品栏(将物品栏视为玩家的唯一一个包裹)的格子很少,但是玩家可以将新的包裹放在物品栏中,达到扩充物品栏的效果。也就是说,物品栏可以放消耗品、武器等零散的物品,当然也可以放包裹。
假定魔兽世界有如下设定:玩家一开始拥有一个默认的包裹(物品栏),玩家可以获得新的包裹放在物品栏上。包裹可以存放武器、防具、消耗品,以及包裹。它可以无限次的迭代,形成树状,如下所示:
以上的模型反应了组合(Composite)模式的思维。在上述的树中,我们把节点分为两种:部分和整体。所谓“部分”,就是指那些没有子节点的项,如炉石、匕首等;整体是指拥有子节点的项,它可以储存子节点。组合模式的意图是将对象组成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
下面是实现这个机制的Java代码:
import java.util.ArrayList;interface WowItem { String getName(); void add(WowItem item); void remove(WowItem item); WowItem get(int i); void print();}class Bag implements WowItem { ArrayList<WowItem> items = new ArrayList<WowItem>(); public String getName(){ return "背包 "; } public void add(WowItem item){ items.add(item); } public void remove(WowItem item){ items.remove(item); } public WowItem get(int i){ return items.get(i); } public void print(){ System.out.println(getName() + "{" ); for ( WowItem i : items){ i.print(); } System.out.println("}"); }}class Hearthstone implements WowItem { public String getName(){ return "炉石"; } public void add(WowItem item){ } public void remove(WowItem item){ } public WowItem get(int i){ return null; } public void print(){ System.out.println(getName()); }}class Dagger implements WowItem { public String getName(){ return "匕首"; } public void add(WowItem item){ } public void remove(WowItem item){ } public WowItem get(int i){ return null; } public void print(){ System.out.println(getName()); }}class Composite{ public static void main(String[] args) { WowItem myBag = new Bag(); WowItem smallBag = new Bag(); myBag.add(new Dagger()); myBag.add(smallBag); smallBag.add(new Dagger()); myBag.add(new Hearthstone()); myBag.print(); }}
为了简化期间,我们构造三个物品:包裹、匕首和炉石。其中,包裹可以容纳子物品,匕首和炉石不可以。为了保持一致性(能在同一容器中容纳它们),它们必须继承于同一个类或者接口,在这个例子上它们均继承于WowItem接口。这个接口声明了4个方法,分别是表示添加、删除、获取某一子物品、打印本物品名称。有几点需要注意:1、我采用了ArrayList容器来保存WowItem,因此所有物品必须继承WowItem。2、在Bag(包裹)类中,均有对add、remove和get做实现,Bag类中的print会调用其所有子节点的print方法。3、对于非Bag类,如Dagger、Hearthstone,它们没有子节点,因此对add、remove、get做了空实现(get返回了null),print方法则直接打印出了它们的名字。
在main方法中,我们定义了个根节点myBag,为它增加了一把匕首Dagger、一个小背包(smallBag),在小背包中添加了一把匕首,然后再在myBag中添加了一个炉石,程序运行结果如下:
背包 {
匕首
背包 {
匕首
}
炉石
}
最后再说两个问题:
一、你可能会发现,对于非组合类(Dagger、Hearthstone),有许多代码是多余的,例如它们不需要实现add、remove、get等方法,如果这些类均继承于WowItem,代码编写会比较繁琐(因为要每个继承的方法都要空实现),而且会损失安全性——我们可能一不小心为一个Dagger调用了add方法或者remove方法。因此,你可以选择为这些非组合类建立一个另外一个类来管理这些子部件,这样的话,就丧失了透明性,它让部分和整体变成了两个独立的部分,我是不推荐这么做的。改善的方法有很多,例如非组合类都继承于一个抽象类A,而这个抽象类A是继承于WowItem的,并且实现了add、remove、get方法,均为抛出一个异常。那么,只要是非组合类调用了add、remove或get,均会得到一个异常。
二、组合在实际的使用中用途非常广。如在编写界面的时候,用到的控件机制——有些控件可以当做“容器”,例如,Frame中可以放入Button、RadioButton,也可以放入Frame,这就是典型的组合模式的运用。
- Java设计模式之从[魔兽世界包裹系统]分析组合(Composite)模式
- java设计模式之组合模式Composite
- java设计模式之 Composite(组合)
- 设计模式之Composite(组合)
- 设计模式之Composite(组合)
- 设计模式之Composite(组合)
- 设计模式之Composite(组合)
- 设计模式之Composite(组合)
- 设计模式之Composite(组合)
- 设计模式之Composite(组合)
- 设计模式之Composite(组合)
- 设计模式之Composite(组合)
- 设计模式之Composite(组合)
- 模式设计之组合Composite
- 设计模式之Composite组合设计模式
- java 设计模式之: 组合模式(Composite)---1 【转】
- JAVA设计模式之 组合模式【Composite Pattern】
- Java设计模式之组合模式(Composite)
- 最大流-hdoj-1532
- AJAX笔试面试题汇总
- github版本库使用详细教程(命令行及图形界面版)
- vim常用命令整理
- hdoj 2531 Catch him(BFS)
- Java设计模式之从[魔兽世界包裹系统]分析组合(Composite)模式
- JAVA 综合面试题
- java操作oracle
- PHP发表文章里的回复数的function的写法
- oracle中的事务
- Deformable Part Model + UpperBodyDetector + HumanPoseEstimation
- 【BZOJ】【P1087】【SCOI2005】【互不侵犯King】【状压DP】【题解】
- 【Linux 入门笔记】系统目录架构
- mysql 特殊字符#导致的后果