`
java苹果+番茄
  • 浏览: 65751 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

合成(Composite)模型模式【结构模式第二篇】

阅读更多
合成(Composite)模型模式:
属于对象的结构模式,有时又叫做部分-整体(Part-Whole)模式。
合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。

1、模式涉及到的三个角色
1)抽象构件(Component)角色:这是一个抽象角色,它给参加组合的对象规定一个接口。这个角色给出共有的接口机器默认行为。
2)树叶构件(Leaf)角色:代表参加组合的树叶对象。一个树叶没有下级的子对象。定义出参加组合的原始对象的行为。
3)树枝构件(Composite)角色:代表参加组合的有子对象的对象,并给出树枝构件对象的行为。

2、合成模式的实现根据所实现接口的区别分为两种形式,分别称为安全式和透明式。虽然这是模式的实现问题,但是由于它影响到模式结构的细节
   合成模式可以不提供对服对象的管理方法,但是合成模式必须在合适的地方提供子对象的管理方法。
  
   1)透明方式
   作为第一种选择,在Compotent里面声明所有的用来管理子类对象的方法,包括add()、remove()、以及getChild()方法。
   这样做的好处是所有的构件类都有相同的接口。在客户端看来,树叶类对象与合成类对象的区别起码在接口层次上消失了,客户端
   可以同等地对待所有的对象。这就是透明形式的合成模式。
  
   这个选择的缺点是不够安全,因为树叶对象和组合类对象的在本质上是有区别的。树叶类对象不可能有下一个层次的对象,
   因此add() remove() getChild()方法没有意义,但是在编译时期不会出错,而只会在运行期出错。
  
   2)安全方式
   第二种选择是在Composite类里而声明所有的用来管理子类对象的方法。这样的做法是安全的做法。
   因为树叶类型的对象根本就没有管理子类对象的方法,因此,如果客户端对树叶类对象使用这些方法时,程序会在编译时期出错。
   编译通不过,就不会出现运行时期错误

这个方式的缺点就是不够透明,因为树叶类和合成类将具有不同的接口。

(安全式)这种形式涉及到三个角色;
1 ) 抽象构件角色:这是一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。
    合成对象通常把它所包含的子对象当作类型为Component的对象。
    在安全式的合成模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝构件对象给出。
2) 树叶构件角色:树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。
3) 树枝构件角色:代表参加组合的有下级子对象的对象。树枝构件类给出所有的管理子对象的方法,如add() remove()
    components()的声明。
抽象构件角色由一个java接口实现,它给出两个对所有的子类均有用的方法:getComposite() sampleOperation()
	   	
	   	//抽象构件角色Component的接口
	   	public interface Component{
	   		//返还自己的实例
	   		Composite getComposite();
	   		//某个商业方法
	   		void sampleOperation();
	   	}
	   	
	   	//树枝构件(Composite)类
	   	import java.util.Vector;
	   	import java.util.Enumeration;
	   	
	   	public class Composite implements Component{
	   		private Vector componentVector = new Vector();
	   		
	   		//返还自己的实例
	   		public Composite getComposite(){
	   			return this;
	   		}
	   		
	   		public void sampleOperation(){
	   			Enumeration enumeration = getChild();	//components()
	   			while(enumeration.hasMoreElement()){
	   				((Component)enumeration.nextElement()).sampleOperation();
	   			}
	   		}
	   		
	   		//聚集管理方法
	   		public void add(Component component){
	   			componentVector.addElement(component);
	   		}
	   		
	   		public void remove(Component component){
	   			componentVector.removeElement(component);
	   		}
	   		
	   		//聚集管理方法,返还聚集的Enumeration对象
	   		public Enumeration getChild(){
	   			return componentVector.elements();
	   		}
	   	}
	   	
	   	//树叶(Leaf)构件类
	   	import java.util.Enumeration;
	   	
	   	public class Leaf implements Component{
	   		public void sampleOperation(){
	   			//................
	   		}
	   		
	   		//返还自己的实例
	   		public Composite getComposite(){
	   			//.............
	   			return null;
	   		}
	   	}
	   	
	   (透明式)这种形式涉及到三个角色:
	   	1) 抽象构件角色:这是一个抽象角色,它给参加组合的对象规定一个就口,规范共有的接口及默认行为。这个接口可以用来
	   	    管理所有的子对象,要提供一个接口以规范取得和管理下层组件的接口,包括add() remove() getChild()之类的方法。
	   	   
	   	2) 树叶构件角色:代表参加组合的树叶对象,定义出参加组合的原始对象的行为。树叶类会给出add() remove() getChild()
	   	    之类的用来管理子类对象的方法的平庸实现。
	   	    
	   	3) 树枝构件角色:代表参加组合的有子对象的对象,定义出这样的对象的行为。
	   	
	   	//抽象构件角色接口
	   	import java.util.Enumeration;
	   	public interface Component{
	   		void sampleOperation();
	   		
	   		//返还自己的实例
	   		Composite getComposite();
	   		
	   		//聚集管理方法
	   		void add(Component component);
	   		
	   		void remove(Component component);
	   		
	   		Enumeration getChild();
	   	}
	   	
	   	//树枝构件类
	   	import java.util.Vector;
	   	import java.util.Enumeration;
	   	
	   	public class Composite implements Component{
	   		private Vector componentVector = new Vector();
	   		
	   		public Composite getComposite(){
	   			return this;
	   		}
	   		
	   		public void sampleOperation(){
	   			Enumeration enumeration = getChild();
	   			while(enumeration.hasMoreElement()){
	   				((Component)enumeration.nextElement()).sampleOperation();
	   			}
	   		}
	   		
	   		public void add(Component component){
	   			componentVector.addElement(component);
	   		}
	   		
	   		public void remove(Component component){
	   			componentVector.removeElement(component);
	   		}
	   		
	   		public Enumeration getChild(){
	   			return componentVector.elements();
	   		}
	   	}
	   	
	   	import java.util.Enumeration;
	   	
	   	public class Leaf implements Component{
	   		public void sampleOperation(){
	   			//..................
	   		}
	   		
	   		public void add(Component component){}
	   		
	   		public void remove(Component component){}
	   		
	   		public Composite getComposite(){
	   			return null;
	   		}
	   		
	   		public Enumeration getChild(){
	   			return null;
	   		}
	   	}

3、实现合成模式时,有几个可以考虑的问题:
1)明显地给出父类对象的引用。在子对象里面给出父对象的引用,这样可以很容易地遍历所有的父对象,管理合成结构。
   有了这个引用,可以很方便地应用责任链模式。
2) 在通常的系统里,可以使用亨元模式实现构件的共享,但是由于合成模式的对象经常要有对父类的引用,因此共享不
    容易实现
3)抽象构件类应当多“重”才算好。
4)有时候系统需要遍历过一个树枝构件的子构件很多次,这时候就可以把遍历子构件的结果暂时存放在父构件里面,作为缓存。
5)使用什么数据类型来存储子对象。可以使用Vector或者其他数组的聚集。
6)Composite向子类的委派。客户端不应当直接调用树叶类,应当由其父类向树叶类进行委派。这样可以增加代码的复用性
//抽象构件角色的实现
	   public abstract class Graphics{
	   	public abstract void draw();
	   }
	   
	   //树枝构件角色(Picture)
	   import java.util.Vector;
	   
	   public class Picture extends Graphics{
	   	private Vector list = new Vector(10);
	   	
	   	public void draw(){
	   		for(int i = 0; i < list.size(); i ++){
	   			Graphics g = (Graphics)list.get(i);
	   			g.draw();
	   		}
	   	}
	   	
	   	public void add(Graphics g){
	   		list.add(g);
	   	}
	   	
	   	public void remove(Graphics g){
	   		list.remove(s);
	   	}
	   	
	   	public void getChild(int i){
	   		return (Graphics)list.get(i);
	   	}
	   }
	   
	   //树叶构件角色(Line)
	   public class Line extends Graphics{
	   	public void draw(){
	   		//............
	   	}
	   }
	   
	   //树叶构件角色(Rectangle)
	   public class Rectangle extends Graphics{
	   	public void draw(){
	   		//..............
	   	}
	   }
	  
	   //树叶构件角色(Circle)
	   public class Circle extends Graphics{
	   	public void draw(){
	   		//...............
	   	}
	   }
	   


4、在下面的情况下应当考虑使用合成模式
   1)需要描述对象的部分和整体的等级结构。
   2)需要客户端忽略掉个体构件和组合构件的区别。客户端必须平等对待所有的构件,包括个体构件和组合构件。
  
  
   5、合成模式的优缺点
   1)优点:合成模式可以很容易地增加新种类的构件。
   使用合成模式可以使客户端变得很容易设计,因为客户端不需要知道构件是树叶构件还是树枝构件。
   2)缺点:使用合成模式后,控制树枝构件的类型就不太容易。
   用继承的方法来增加新的行为很困难
分享到:
评论

相关推荐

    Delphi模式编程第二分卷

    第2章 Delphi的模式编程机制 2.1 对象模型机制 2.1.1 对象模型 2.1.2 对象建模和模式编程 2.1.3 对象关系与复用 2.2 动态绑定机制 2.2.1 方法绑定 2.2.2 虚方法 2.2.3 多态 2.3 类型转换机制 ...

    Delphi模式编程第一分卷

    第2章 Delphi的模式编程机制 2.1 对象模型机制 2.1.1 对象模型 2.1.2 对象建模和模式编程 2.1.3 对象关系与复用 2.2 动态绑定机制 2.2.1 方法绑定 2.2.2 虚方法 2.2.3 多态 2.3 类型转换机制 2.3.1 类型 ...

    C#23种设计模式_示例源代码及PDF

    原始模型模式允许动态的增加或减少产品类, 产品 类不需要非得有任何事先确定的等级结构, 原始模型模式适用于任何的等级结构。 缺点是每 一个类都必须配备一个克隆方法。 5、 、 SINGLETON —俺有 6 个漂亮的...

    Delphi 深度探索(第二版)〖含随书光盘源代码〗

    6.2.2 合成模式(composite模式) 6.2.3 装饰模式(decorator模式) 6.2.4 门面模式(faqade模式) 6.2.5 桥模式(bridge模式) 6.2.6 代理模式(proxy) 6.2.7 享元模式(flyweight模式) 6.3 行为模式 ...

    java面试800题

    facade门面模式、proxy代理模式、adapter适配器(变压器)模式、composite合成模式、decorator装饰模式、bridge桥梁模式、flyweight享元模式 行为模式 template模板方法模式、memento备忘录模式、observer观察者模式...

    java 面试题 总结

    抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类...

    超级有影响力霸气的Java面试题大全文档

    抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承:  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承...

    Hibernate中文API大全

    注意:在Hibernate3中,第二个要求并非是Hibernate强制必须的。但最好这样做。 你不能使用一个IdentifierGenerator产生组合关键字。一个应用程序必须分配它自己的标识符。 使用&lt;composite-id&gt; 标签(并且内嵌元素...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    第二章 用户和权限 一、 用户介绍 ORACLE用户是学习ORACLE数据库中的基础知识,下面就介绍下类系统常用的默认ORACLE用户: 1. sys用户:超级用户,完全是个SYSDBA(管理数据库的人)。拥有dba,sysdba,sysoper等角色或...

Global site tag (gtag.js) - Google Analytics