装饰模式

定义

装饰模式允许你再不改变原有对象的前提下,为对象增加新的行为功能。

示例分析

图片说明
平时我们购买礼物的之后,会将礼物进行打包之后送出去。有时候直接装到纸盒子、有时候装到塑料盒子、有时候装到塑料盒子之后再装到纸盒子等。这里所说的“礼物”就是我们定义中的“原对象”,“打包”就是给对象新增的功能。
下面用代码来进行描述:
首先,我们先定义礼物的抽象类,包含礼物的描述信息 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());
    }
}

优缺点

优点

  1. 无需创建子类,即可拓展对象的行为。
  2. 装饰可以进行嵌套,可以用多个装饰类进行多种装饰操作

缺点

  1. 在多个装饰类嵌套的情况,需要额外考虑嵌套顺序的情况,
全部评论

相关推荐

头像
04-26 15:00
已编辑
算法工程师
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务