装饰器模式,顾名思义起的是装饰的作用,就是在一个类上增加功能。如果通过继承来增加功能,在不修改代码的情况下,如果增加功能多的话,会使类的数量爆炸式增长,为管理带来巨大的麻烦。装饰器模式就比较好地解决了这一点。
以上为装饰器模式的通用类图:
我们以生产一件衣服为例,生产一件衣服本身是个很简单的过程,一块布料裁剪好了之后做出衣服的样子就可以了,但是这样的衣服是卖不出去的,因为毫无美感,我们需要通过一些装饰来使衣服变得好看。但是时代在变化,人们的审美也在变化,装饰总是不断在变的,所以我们就要有一个灵活机动的模式来修改装饰。
interface Clothes { public void makeClothes(); } class MakeClothes implements Clothes { @Override public void makeClothes() { System.out.println("制作一件衣服"); } }
话不多说,先来个衣服的最初成品,就是毫无美感的那种,那么如果现在要增加装饰,可以用一个类继承MakeClothes,然后增加里面makeClothes()方法,但是如果过几天装饰就变了,那么又要改动代码,而且如果装饰过多,这个类就显得很庞杂,不好维护,这个时候装饰器模式就来大显身手了。
class Decorator implements Clothes { private Clothes clothes; public Decorator(Clothes _clothes) { this.clothes = _clothes; } @Override public void makeClothes() { clothes.makeClothes(); } }
这就是一个装饰器,它有一个构造函数,参数是一个衣服类,同时它重载了makeClothes()方法,以便它的子类对其进行修改。下面是两个子类,分别对衣服进行了绣花和镂空:
class Embroidery extends Decorator { public Embroidery(Clothes _clothes) { super(_clothes); } public void embroidery() { System.out.println("给衣服绣花"); } public void makeClothes() { super.makeClothes(); this.embroidery(); } } class Hollow extends Decorator { public Hollow(Clothes _clothes) { super(_clothes); } public void hollow() { System.out.println("关键位置镂空"); } public void makeClothes() { super.makeClothes(); this.hollow(); } }
这两个子类的构造器都传入一个衣服模型,而且两个子类分别有各自的方法——绣花和镂空,但是他们均重写了makeClothes()方法,在制作衣服的过程中加入了绣花和镂空的操作,这样一来,我们只需要增删改这几个装饰器的子类,就可以完成各种不同的装饰,简洁明了,一目了然。下面测试一下:
public class TestDecorator { public static void main(String[] args) { Clothes clothes = new MakeClothes(); clothes = new Embroidery(clothes); clothes = new Hollow(clothes); clothes.makeClothes(); System.out.println("衣服做好了"); } }
测试打印结果如下:
制作一件衣服
给衣服绣花
关键位置镂空
衣服做好了
可见装饰的效果还是不错的,不过装饰器模式虽然好用,但是如果装饰层数过多,还是会影响到维护的,所以说设计模式虽好,还是需要灵活使用。