装饰模式

定义

装饰模式是一种利用对象的关联关系来拓展对象功能的模式,并对外提供透明访问。由其名称中“装饰”两个字可知,该模式强调为对象添加职责,为了不违背单一职责原则,降低复杂度,所以提供装饰类对被装饰类加以修饰,这里称被装饰类为原始构件类,在每个装饰类中提供一个需要附加或添加的职责,所以一般需要一个抽象的装饰类。整个结构满足每个单独类都提供一个职责,通过装饰类对构件类进行包装来提供目标服务方法。

结构

由定义可知结构如下


结构中包含如下部分:

1、抽象构件类Component,声明目标服务方法

2、具体构件类Concrete_Component,提供原始功能

3、抽象装饰类Decorator,实现抽象构件类,并包含一个对抽象构件的引用,在实现方法中调用引用对象的实现

4、具体装饰类Concrete_Decorator,在重写的方法中添加职责,并调用原对象封装对象职责(这里说是原封装对象是因为可能进行了多层封装)

对比其他结构

拓展功能常使用继承方式,例如以animal作为抽象动物类,bird继承animal中的基本动物方法,并提供fly方法,fish继承animal中的基本动物方法,并提供swim方法,现在添加一个白鹭egret类,既需要实现fly方法,也需要实现swim方法,多继承的方式可能会造成使用方式受限(当然实际牵涉到动物类一般都是这种继承关系,此处只用来举例);


更常见的例子如对石块的操作可以包含两个步骤,雕刻(方式1、方式2、方式3。。。),上色(方式1、方式2、方式3。。。),如果使用继承的方式进行拓展,则可能存在一大堆的类,每个雕刻方式对应多个上色方式(看到这,其实最先想到的是之前的桥接模式,将雕刻和上色作为两个变化因素,进行分隔为两个继承体系,在抽象层建立关联关系,不过这里使用装饰模式,因为对于不同类型的石器材料有些可能只需要雕刻操作即可,即不需要提供上色步骤,装饰模式其实不光跟桥接模式接近,还有点像代理模式)。


由上面的继承结构可知,继承方式耦合性太强,扩展性不高,根据装饰模式定义,只需将carve方式作为原始构件类,上色操作作为装饰类提供附加职责即可。


在carve1、carve2中实现具体的雕刻操作,decorator用于代表需要额外添加的抽象上色操作。

参考代码

class t{
	public static void main(String[] args){
		stone c1=new carve1();
		stone d1=new color1(c1);
		stone d2=new color2(d1);
		d2.show();
	}
}
interface stone{//抽象构建类
	void show();
}
class carve1 implements stone{//原始职责的构建类
	public void show(){
		System.out.println("carve1 action.");
	}
}
class carve2 implements stone{//原始职责的构建类
	public void show(){
		System.out.println("carve2 action.");
	}
}
class decorator implements stone{//抽象装饰类
	private stone st;
	public decorator(stone st){
		this.st=st;
	}
	public void show(){
		st.show();
	}
}
class color1 extends decorator{//具体装饰类
	public color1(stone st){
		super(st);
	}
	public void show(){
		append_operation();//添加职责
		super.show();
	}
	public void append_operation(){
		System.out.println("color1 action append.");
	}
}
class color2 extends decorator{
	public color2(stone st){
		super(st);
	}
	public void show(){
		append_operation();
		super.show();
	}
	public void append_operation(){
		System.out.println("color2 action append.");
	}
}

总结

由装饰模式定义可知,该模式侧重于以透明方式对原始构件类,以关联关系而非继承的方式,添加额外的职责,当需要新添加一种职责时,只需要实现抽象装饰类即可。

这里有一种透明装饰模式和不透明装饰模式的差异:

上述定义操作,在满足抽象构件中声明的服务时,添加职责的方式对外界是透明的,即不可知的。如果在某种情形下,例如某位雕刻家走另类艺术,拿块石头不雕刻,喷上色就算完成了,即需要明确执行具体装饰类中添加的某项职责,此时定义具体装饰对象的引用变量类型不能为抽象构件类型stone,而必须是color1或者color2类型,即需要客户端做额外的执行职责,添加的功能对客户端不透明。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值