装饰器模式学习笔记

2 篇文章 0 订阅
1 篇文章 0 订阅

参考链接1:http://www.cnblogs.com/god_bless_you/archive/2010/06/10/1755212.html

参考链接2:http://www.cnblogs.com/ASPNET2008/archive/2008/06/15/1222724.html

定义

装饰器模式:在不改变原类和不生成子类的情况下,动态为对象添加额外的职责。其比继承更灵活、更具弹性。

设计原理

不改变原类扩展功能,符合开闭原则(对修改关闭,对新增开放);

不通过子类扩展功能,可以让类设计更灵活。因为继承实现子类行为,编译是静态的;而用组合扩展功能,则可以在程序运行时动态扩展。

类图


在客户端中对ConcreteComponent进行装饰的语句就为:

AbstractDecorator decorator = newConcreteDecorator2(new ConcreteComponent());

decorator实例接口与被装饰者接口(operator())保持一致,但客户端通过装饰器示例调用operator()方法时,功能已可以被动态增加。

组成要素

1)  抽象角色(IComponent):给出一个抽象接口,以规范准备接受附加职能的对象。

2)  具体角色(ConcreteComponent):被装饰者,其实现接口与抽象角色保持一致。

3)  抽象装饰角色(AbstractDecorator):装饰器,实现并聚合了抽象角色。实现抽象角色是为了装饰者与被装饰者保持相同的对外接口;聚合了一个抽象角色,是为了通过此角色,在运行时动态调用某一具体角色。

4)  具体装饰角色(ConcreteDecorator):需要扩展功能的动态实现,具体的装饰器。

常见例子

1) servlet中的装饰器HttpServletRequestWrapper。HttpServletRequest类的getParameter()方法:装饰前调用此方法,只是简单返回参数值,而不会对此参数做任何处理;用HttpServlertRequestWrapper装饰后,重写getParameter()方法,可以对参数值进行trim()操作。

2) IO操作之一:BufferedInputStream对FileInputStream装饰:

BufferedInputStream buf = new BufferedInputStream(newFileInputStream(“filePath”));

类图如下:FilterInputStream相当于抽象装饰器角色,FileInputStream是被装饰的角色,InputStream抽象类是装饰器与被装饰器共同的规范,BufferedInputStream则是具体的装饰实现。换句话说,这里的BufferedInputStream是对FileInputStream装饰了缓冲区功能,若实际需求中你对FileInputStream现有功能不满,你可以自定FilterInputStream的子类,实现自己的装饰器。


代码示例

举例实现三个装饰器,每个扩展一个功能,在客户端调用装饰器时,对其进行了三次装饰,那么装饰器示例三个功能都具备。

1)  抽象角色:

public interface ISource {
       public void operatrion();
}

2)  具体角色:

public class SourceImpl implements ISource {
	public void operatrion() {
		System.out.println("*****装饰器原始类,原始功能调用*****");
	}
}

3)  抽象装饰角色:

public abstract class AbstractDecoratorSource implements ISource {
          
        private ISource source;
          
        public AbstractDecoratorSource(ISource source){
             this.source =source;
        }          
        public void operatrion(){
             source.operatrion();
        }
}

4)  具体装饰角色,A、B、C:

public class DecoratorSourceA extends AbstractDecoratorSource {<span style="white-space:pre">		</span>//装饰A
	public DecoratorSourceA(ISource source){
		super(source);
	}
	
	@Override
	public void operatrion() {
		System.out.println("装饰器A前");
		super.operatrion();
		System.out.println("装饰器A后");
	}
}
public class DecoratorSourceB extends AbstractDecoratorSource {<span style="white-space:pre">		</span>//装饰B
	public DecoratorSourceB(ISource source){
		super(source);
	}
	
	@Override
	public void operatrion() {
		System.out.println("装饰器B前");
		super.operatrion();
		System.out.println("装饰器B后");
	}
}
public class DecoratorSourceC extends AbstractDecoratorSource {<span style="white-space:pre">		</span>//装饰C
	public DecoratorSourceC(ISource source){
		super(source);
	}
	
	@Override
	public void operatrion() {
		System.out.println("装饰器C前");
		super.operatrion();
		System.out.println("装饰器C后");
	}
}

5)  客户端调用测试

public class Test {
	public static void main(String[] args){
		ISource source = new SourceImpl();
		//可以多次装饰,每次装饰都可以为前一个基础类添加新的功能
		source = new DecoratorSourceC(		//一次装饰
					new DecoratorSourceB(	//二次装饰
							new DecoratorSourceA(source)));//三次装饰
		source.operatrion();
	}
}

6)  输出结果:







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值