装饰者设计模式
什么是装饰者设计模式
装饰者设计模式(Decorator Pattern)将某个方法进行增强,可以在被装饰的方法执行前后加上想要的逻辑处理进行增强,又可以不改变现有的结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供额外的功能。
使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。
注意事项:可代替继承
实战
我们利用女孩化妆来演示装饰者设计模式,首先我们定义一个接口,拥有展示的行为:
public interface Showable {
void show();
}
当然女友会这门功夫了,所以实现了此行为并施展其“美丽的脸庞”了,但此时只是原生态的素颜。
public class Girl implements Showable {
@Override
public void show() {
System.out.print("女孩的素颜");
}
}
没什么复杂的,直接调用的话会是素面朝天直面惨淡的人生,这样当然达不到美颜效果了,何以一顾倾城。那么接下来要进行化妆了,这里必须依靠一种神秘而又昂贵的东西,化妆品登场了,它同样实现了Showable接口。
public class Decorator implements Showable {
/**
* 拥有某个善于展示的对象
*/
private Showable showable;
public Decorator(Showable showable){
this.showable = showable;
}
@Override
public void show() {
System.out.print("化妆(");
showable.show();
System.out.println(")");
}
}
我们可以发现,在构造化妆品类的时候可以把女孩给注入进来,目的在于调用女孩的show方法,但对于其原本的具体行为装饰器一无所知,并且没有加入任何逻辑限制,它所做的无非是“画龙点睛”,“锦上添花”。接下来我们来运行一下看结果:
public class TestShowable {
public static void main(String[] args) {
//将需要被加强的对象传递给装饰类
new Decorator(new Girl()).show();
//结果:打扮(女孩的素颜)
}
}
我们可以看到,只需要新建装饰器的时候把女孩给包装进去就得到了粉饰过的美颜,是不是非常简单?然而此时有女朋友会嫌弃了,“只是打粉底这么简单吗?眼霜呢?口红呢……”。
好吧,为了满足女友的要求,我们得再多一些设计。想想看这些化妆品,不管是什么都有共同的特性,也就是说他们统统都可以装饰原生态的素颜展示方法show,那我们何不把这些特性抽象出来呢?开始行动,修改我们的装饰类
public abstract class Decorator implements Showable {
/**
* 拥有某个善于展示的对象
*/
protected Showable showable;
public Decorator(Showable showable){
this.showable = showable;
}
public void show() {
//直接调用,不加任何装饰
showable.show();
}
}
我们把化妆品类给改成抽象类,重写show方法,但不做任何粉饰了,这里我们留给子类具体的某个化妆品去做装饰吧。化妆首先第一步一定要打底了,这里我们首先加入一个口红类:
public class Lipstick extends Decorator{
public Lipstick(Showable showable) {
//调用父类构造赋值给成员属性
super(showable);
}
@Override
public void show() {
System.out.print("涂口红(");
showable.show();
System.out.print(")");
}
}
涂完口红,最后再喷点香水吧。同样的,我们再定义一个香水类:
public class Perfume extends Decorator {
public Perfume(Showable showable) {
super(showable);
}
@Override
public void show() {
System.out.println("喷香水(");
showable.show();
System.out.println(")");
}
}
最后,我们把女友、口红、香水层层包裹起来并运行,结果如愿以偿。
public class TestShowable {
public static void main(String[] args) {
//将需要被加强的对象传递给装饰类,层层包裹起来,每一层都多了一些功能
new Perfume(new Lipstick(new Girl())).show();
//结果: 喷香水(涂口红(女孩的素颜))
}
}
如果女友对这种淡妆效果还是不满意,我们可以继续添加化妆品类,睫毛膏、眼线、眉笔、腮红等等等等,只需要层层包裹起来,最终实现女友浓妆艳抹的梦想。
我们观察这种装饰器模式结构,是不是似曾相识呢?没错,其实装饰器模式在JDK里就有很多应用,比如Java IO包里的众多流处理类。
new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
当然,流处理类当然要比我们的例子复杂的多,但其基本思想和我们去繁就简的例子异途同归,这些对象就好像是俄罗斯套娃一样层层包裹,层层装饰,每套一层就会多出一些功能出来,我们更可以自由搭配,实现不同的组合功能。