装饰模式
定义
装饰模式允许你再不改变原有对象的前提下,为对象增加新的行为功能。
示例分析
平时我们购买礼物的之后,会将礼物进行打包之后送出去。有时候直接装到纸盒子、有时候装到塑料盒子、有时候装到塑料盒子之后再装到纸盒子等。这里所说的“礼物”就是我们定义中的“原对象”,“打包”就是给对象新增的功能。
下面用代码来进行描述:
首先,我们先定义礼物的抽象类,包含礼物的描述信息 getDesc()
,该方法由子类实现
public abstract class AbstractGift { abstract String getDesc(); }
然后,我们定义具体的礼物(玩具汽车),并实现 getDesc()
public class ToyCarGift extends AbstractGift { @Override public String getDesc() { return "玩具汽车礼物"; } }
接下来,定义礼物装饰类的抽象类。该抽象类需要继承礼物的抽象类,以保证和被装饰的礼物有共同的行为。
public abstract class AbstractGiftWrapper extends AbstractGift { // 被装饰的礼物对象 protected AbstractGift gift; protected AbstractGiftWrapper(AbstractGift gift) { this.gift = gift; } }
然后,定义具体的礼物装饰类对礼物进行装饰。此处我们定义了塑料盒装饰类 和 纸盒装饰类。此处通过对被装饰的描述信息加以描述,以表示礼物被哪个类进行装饰。
public class PlasticGiftWrapper extends AbstractGiftWrapper{ protected PlasticGiftWrapper(AbstractGift gift) { super(gift); } @Override String getDesc() { return "用塑料箱子包装的 [" + gift.getDesc() + "]"; } } public class CartonGiftWrapper extends AbstractGiftWrapper { protected CartonGiftWrapper(AbstractGift gift) { super(gift); } @Override String getDesc() { return "用纸箱子包装的 [" + gift.getDesc() + "]"; } }
最后,我们通过Client来看看调用结果。里面可以对礼物进行任意的装饰,以及装饰的多层嵌套
public class Client { public static void main(String[] args) { // 定义玩具汽车礼物 AbstractGift toyCar = new ToyCarGift(); // 只用塑料盒包装礼物 AbstractGiftWrapper plasticWrapper = new PlasticGiftWrapper(toyCar); System.out.println(plasticWrapper.getDesc()); System.out.println(); // 只用纸盒包装礼物 AbstractGiftWrapper cartonWrapper = new CartonGiftWrapper(toyCar); System.out.println(cartonWrapper.getDesc()); System.out.println(); // 先用纸盒,再用塑料盒包装 AbstractGiftWrapper multiWrapper1 = new PlasticGiftWrapper( new CartonGiftWrapper( toyCar ) ); System.out.println(multiWrapper1.getDesc()); System.out.println(); // 先用塑料盒包装,再用纸盒包装 AbstractGiftWrapper multiWrapper2 = new CartonGiftWrapper( new PlasticGiftWrapper( toyCar ) ); System.out.println(multiWrapper2.getDesc()); } }
优缺点
优点
- 无需创建子类,即可拓展对象的行为。
- 装饰可以进行嵌套,可以用多个装饰类进行多种装饰操作
缺点
- 在多个装饰类嵌套的情况,需要额外考虑嵌套顺序的情况,