个人理解,如有错误,请大家指正,谢谢。
什么是装饰者模式?
定义:装饰着模式动态地将责任附加到对象上,若要扩展功能,装饰着提供了比继承更有弹性的替代方案。
怎么理解呢?比如说,我们想建立一个洋娃娃类,娃娃可以穿衣服、裤子、裙子、以及同时穿裤子和衣服......
有几种实现方案:
version1:
娃娃作为父类,芭比娃娃作为子类,芭比娃娃的子类有:穿衣服的芭比娃娃、穿裤子的芭比娃娃、穿裙子的芭比娃娃、同时穿衣服和裤子的芭比娃娃......是不是太多类了?除此之外,如果我们新研发出一种噼啪娃娃,那么将会......
这样的代码想一想就很恶心对不对?我们是负责任的开发人员,当然不愿写出这样不易扩展、难以维护的代码。
那么应该怎么办呢?
version2:
那么可否在Doll类中加上各种衣服的属性?先不忙着写代码,我们想一想这样会出现什么问题。
问题一:如果由新制造了一款不需要穿衣服的呱唧娃娃,那么呱唧娃娃类继承Doll,也会继承到对它来说毫无意义的各种衣服属性。
问题二:如果某个娃娃比较有个性,非要同时穿两件一样的衣服,应该怎么实现?
看来,这种方案也并不合适。
version3:装饰者模式:
我们可以用Skirt把BaBi Doll包一层,再用Pants把穿了裙子的Babi Doll包一层。
不知道我有没有说清楚,大家请看一下UML图:
我们可以看到,装饰者继承了被装饰者,因此他们是一样的类型。装饰者模式中,继承的目的是为了达到“类型匹配”,而不是获得”行为“,”行为“来自装饰者和基础组件,基础组件也可能是其他装饰者。这里不理解的同学可以继续往下看,将我们的测试类代码看完之后,再回味一下这里。
好了,下面我们来写代码。
我们先写Doll类,这是一个抽象类:
public abstract class Doll {
protected String name;
public String getName() {
return name;
}
}
Doll的子类,芭比娃娃类:
public class Babi extends Doll {
public Babi() {
name = "a babi doll";
}
}
装饰者抽象类:
public abstract class Decorator extends Doll {
public abstract String getName();
}
Skirt类:
public class Skirt extends Decorator {
private Doll doll;
public Skirt(Doll doll) {
this.doll = doll;
}
@Override
public String getName() {
return doll.getName() + " with skirt";
}
}
Pants类:
public class Pants extends Decorator {
private Doll doll;
public Pants(Doll doll) {
this.doll = doll;
}
@Override
public String getName() {
return doll.getName() + " with pants";
}
}
大功告成!下面是我们的测试类:
public class Test {
public static void main(String[] args) {
Doll doll = new Babi();
System.out.println(doll.getName());
doll = new Skirt(doll);
System.out.println(doll.getName());
doll = new Pants(doll);
System.out.println(doll.getName());
}
}
写到这里,我们仔细的看一下测试类,就会发现,最后doll由最初的Doll类变成了Pants类,用装饰者包装,会造成类型的改变。因此,依赖于具体组件类型的代码不适用于装饰者模式,而装饰者模式适用于依赖抽象组件类型的代码。