`

设计模式学习笔记——组合模式

阅读更多

 

组合模式

又称合成模式,属于对象的结构模式,也被叫做部分-整体模式。

合成模式将对象组织到树结构中,使客户端将单纯元素和复合元素同等看待。

 

传统的盗图


合成模式主要涉及的3个角色

1 抽象构件(Component):抽象角色,对参加组合的对象规定了统一接口

2 树叶构件(Leaf):代表参加组合的对象

3 树枝构件(Composite):代表参加组合的含有子对象的对象

 

合成模式有2种形式

安全式

在Composite树枝构件中声明管理子类对象的方法,但是这种方法不够透明

透明式

在Component抽象构件中就定义所有管理子类对象的方法,但是这种方式并不安全,并且在Leaf树叶中需要对无用方法进行平庸实现(返回null,置空等)

GOF中相对于安全性更推崇透明性

 

下面是我的一个透明式的小Demo

首先是抽象角色接口

 

public interface Component {
	void display();
	void add(Component component);
	void del(Component component);
	void getChild();
}

 定义了组件应该具有的方法规范

之后Composite树枝构件,方便起见给了他们各自一个名称

 

public class Composite implements Component {
	private ArrayList<Component> childList=new ArrayList();
	private String name;
	public Composite(String name){
		this.name="Composite: "+name;
	}
	public void display() {
		System.out.println(name);
	}
	public void add(Component component) {
		childList.add(component);
	}
	public void del(Component component) {
		childList.remove(component);
	}
	public void getChild() {
		System.out.println(name+"'s children");
		for(int i=0;i<childList.size();i++){
			childList.get(i).display();
		}
	}
}

可以看到其中有管理构件的add,del等方法

最后是Leaf叶子构件,其中与管理相关的方法都采取了置空

 

public class Leaf implements Component {
	private String name;
	public Leaf(String name){
		this.name="Leaf: "+name;
	}
	public void display() {
		System.out.println(name);
	}
	public void add(Component component) {
	}
	public void del(Component component) {
	}
	public void getChild() {
	}
}

构件一个类来测试一下结果:

 

public class CompositePattern {
	public static void main(String[] args) {
		Composite root=new Composite("root");
		Composite branch1=new Composite("branch1");
		Composite branch2=new Composite("branch2");
		Leaf leaf1=new Leaf("Leaf1");
		Leaf leaf2=new Leaf("Leaf2");
		Leaf leaf3=new Leaf("Leaf3");
		root.add(branch1);
		root.add(leaf1);
		branch1.add(branch2);
		branch1.add(leaf2);
		branch1.add(leaf3);
		root.display();
		branch1.display();
		branch1.getChild();
		branch1.del(leaf3);
		branch1.getChild();
	}
}

即一颗下列形式的树

root——branch1 ——branch2

| |

——leaf1 ——leaf2

|

——leaf3

 输出结果

 

Composite: root

Composite: branch1

Composite: branch1's children

Composite: branch2

Leaf: Leaf2

Leaf: Leaf3

Composite: branch1's children

Composite: branch2

Leaf: Leaf2

 

组合模式的优点

1 使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关心自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。 

2 更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。这一点符合开闭原则的要求,对系统的二次开发和功能扩展很有利。

缺点

不容易限制组合中的构件

 

(转)使用组合模式时考虑的问题

1 明显的给出父对象的引用。在子对象里面给出父对象的引用,可以很容易的遍历所有父对象。有了这个引用,可以方便的应用责任链模式。

2 在通常的系统里,可以使用享元模式实现构件的共享,但是由于合成模式的对象经常要有对父对象的引用,因此共享不容易实现。

3 有时候系统需要遍历一个树枝结构的子构件很多次,这时候可以考虑把遍历子构件的结果暂时存储在父构件里面作为缓存。

4 关于使用什么数据类型来存储子对象的问题,在示意性的代码中使用了ArrayList,在实际系统中可以使用其它聚集或数组等。

5 客户端尽量不要直接调用树叶类中的方法,而是借助其父类(Component)的多态性完成调用,这样可以增加代码的复用性

 

 

参考链接:

http://www.iteye.com/topic/285021

http://blog.csdn.net/rocket5725/article/details/4308476

  • 大小: 8.5 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics