论坛首页 Java企业应用论坛

了解装饰模式

浏览 4410 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (1) :: 隐藏帖 (4)
作者 正文
   发表时间:2008-12-03   最后修改:2008-12-05

装饰模式:动态给一个对象添加一些额外的职责,使用Decorator模式比用生成子类方法达到功能的扩充更为灵活

为什么使用:通常使用继承来实现功能扩展,如果扩展的功能种类繁多,会生成很多子类,增加系统的复杂性。使用继承实现扩展必须预见性,在编译前已确定,是静态的。

例如要去商店买肉,首先定义买的接口

public interface Shop {
   public void buy();
}

 

下面我要买肉,继而实现此接口

public class BuyMeat implements Shop{

	public void buy() {
		System.out.println("买肉");
	}

}

 一般客户要买什么,就实例这个实现类,就ok了。如果我买肉之前或之后想买点蔬菜或者点心等等,但是从上面可以看出,没有实现买蔬菜及点心的接口,怎么办?这就是上面所说的预见性。

这样我们就可以通过装饰模式来实现。

public class Decorator implements Shop{

	private Shop shop;
	
//	额外干的任务
	private ArrayList others = new ArrayList(); 
	
	public Decorator(Shop shop){
		this.shop = shop;
		others.add("买蔬菜");
		others.add("买点心");
	}
	public void buy() {
		newMethod();
	}
	
	public void newMethod(){
		otherMethod();
		shop.buy();
	}


	public void otherMethod(){
		ListIterator listIterator = others.listIterator();
		while(listIterator.hasNext()){
			System.out.println("+++++++++"+listIterator.next().toString());
		}
	}

}

 

我可以将我要干的事情统一起来,最后一起进行,这样就可以实现上述需求。

 

我们通过测试看下

public class Client {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
	      Shop	buyMeat = new BuyMeat();
	      Shop decorator = new Decorator(buyMeat);
	      decorator.buy();
	}
}

 

这个测试,可以看出应该将一些列的对象都转换为接口对象。这也正是一步步的装饰,事实它们的根源也都是接口对象。

测试结果

+++++++++买蔬菜
+++++++++买点心
买肉

在买肉之前买了蔬菜,和点心。

此贴仅是个人初步学习理解,如果有错误或不对的地方请大家批评

   发表时间:2008-12-03  
如果我买肉之前或之后想买点蔬菜或者点心等等,但是从上面可以看出,没有实现买蔬菜及点心的接口,怎么办?这就是上面所说的预见性。

感觉不对吧。难道你这样处理买菜和点心就不是预见性么?

装饰是对子类的扩张,在继承或重载父类的方法时增加额外的处理吧。
0 请登录后投票
   发表时间:2008-12-03  
lz可以看看这个文章

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

很不错。这个才是装饰模式(一层一层进行包装)
0 请登录后投票
   发表时间:2008-12-03  
hanjs 写道

lz可以看看这个文章 http://www.iteye.com/topic/220230 很不错。这个才是装饰模式(一层一层进行包装)

谢谢,你发的这个帖子的确很透彻,我会继续学习
0 请登录后投票
   发表时间:2008-12-03  
Decorator模式在原来很常用,经常用到连接池等,后来被1.4之后的动态代理替换了。
0 请登录后投票
   发表时间:2009-02-18  
wangchao_17915566 写道

装饰模式:动态给一个对象添加一些额外的职责,使用Decorator模式比用生成子类方法达到功能的扩充更为灵活

为什么使用:通常使用继承来实现功能扩展,如果扩展的功能种类繁多,会生成很多子类,增加系统的复杂性。使用继承实现扩展必须预见性,在编译前已确定,是静态的。

例如要去商店买肉,首先定义买的接口

public interface Shop {
   public void buy();
}

 

下面我要买肉,继而实现此接口

public class BuyMeat implements Shop{

	public void buy() {
		System.out.println("买肉");
	}

}

 一般客户要买什么,就实例这个实现类,就ok了。如果我买肉之前或之后想买点蔬菜或者点心等等,但是从上面可以看出,没有实现买蔬菜及点心的接口,怎么办?这就是上面所说的预见性。

这样我们就可以通过装饰模式来实现。

public class Decorator implements Shop{

	private Shop shop;
	
//	额外干的任务
	private ArrayList others = new ArrayList(); 
	
	public Decorator(Shop shop){
		this.shop = shop;
		others.add("买蔬菜");
		others.add("买点心");
	}
	public void buy() {
		newMethod();
	}
	
	public void newMethod(){
		otherMethod();
		shop.buy();
	}


	public void otherMethod(){
		ListIterator listIterator = others.listIterator();
		while(listIterator.hasNext()){
			System.out.println("+++++++++"+listIterator.next().toString());
		}
	}

}

 

我可以将我要干的事情统一起来,最后一起进行,这样就可以实现上述需求。

 

我们通过测试看下

public class Client {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
	      Shop	buyMeat = new BuyMeat();
	      Shop decorator = new Decorator(buyMeat);
	      decorator.buy();
	}
}

 

这个测试,可以看出应该将一些列的对象都转换为接口对象。这也正是一步步的装饰,事实它们的根源也都是接口对象。

测试结果

+++++++++买蔬菜
+++++++++买点心
买肉

在买肉之前买了蔬菜,和点心。

此贴仅是个人初步学习理解,如果有错误或不对的地方请大家批评

 

0 请登录后投票
   发表时间:2009-02-18  
代理模式和装饰模式的区别主要体现在哪里?我觉得这更像是代理模式
0 请登录后投票
   发表时间:2009-02-25  
LZ的这个例子,估计不太典型,瞧不出模式的特点
0 请登录后投票
   发表时间:2009-07-24  
这是静态代理。。
0 请登录后投票
   发表时间:2009-09-01  
这样貌似也不能算是动态的吧
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics