装饰器模式

属于结构型模式。目的是在不改变原有对象的基础上,将功能附加到对象上,提供了比继承更加有弹性的替代方案(拓展原有对象的功能)

示例

比如买煎饼这个事情,如果不使用装饰器,只是简单的使用继承,会需要用到很多类
纯煎饼类

如果不使用装饰器

/**
 * 煎饼类
 */
public class BetterCake {

    /**
     * 名字
     * @return String
     */
    protected String getMsg(){
        return "煎饼";
    }

    /**
     * 价格
     * @return int
     */
    public int price(){
        return 5;
    }
}

煎饼+一个鸡蛋

/**
 * 煎饼+鸡蛋
 */
public class BetterCakeWithEgg extends BetterCake {

    @Override
    protected String getMsg() {
        return super.getMsg()+"+1个鸡蛋";
    }

    /**
     * 加鸡蛋后。价格上涨1元
     * @return
     */
    @Override
    public int price() {
        return super.price()+1;
    }
}

煎饼+一个鸡蛋+一个香肠

/**
 * 煎饼+鸡蛋+香肠
 */
public class BetterCakeWithEggAndSausage extends BetterCakeWithEgg {

    @Override
    protected String getMsg() {
        return super.getMsg()+"+1个香肠";
    }

    /**
     * 加香肠后。价格再上涨2元
     * @return
     */
    @Override
    public int price() {
        return super.price()+2;
    }
}

测试

public static void main(String[] args) {
        //纯煎饼
        BetterCake betterCake = new BetterCake();
        System.out.println(betterCake.getMsg()+",价格:"+betterCake.price()+"元");

        //煎饼+鸡蛋
        BetterCake betterCakeWithEgg = new BetterCakeWithEgg();
        System.out.println(betterCakeWithEgg.getMsg()+",价格:"+betterCakeWithEgg.price()+"元");

        //煎饼+鸡蛋+香肠
        BetterCake betterCakeWithEggAndSausage = new BetterCakeWithEggAndSausage();
        System.out.println(betterCakeWithEggAndSausage.getMsg()+",价格:"+betterCakeWithEggAndSausage.price()+"元");
    }

结果
在这里插入图片描述
【缺点】此种方法过于死板,如果要添加多个鸡蛋或多个香肠(即需求发生变更时),都需要重新新建一个类,不便于管理。

使用装饰器

可以只创建一种菜,而后随意加多少数量。
准备一个煎饼模板

/**
 * 由于煎饼会经常变更,故不实现具体的类,而是定义一个抽象的煎饼类
 */
public abstract class BetterCake {
    /**
     * 名字-子类实现
     * @return String
     */
    protected abstract String getMsg();

    /**
     * 价格-子类实现
     * @return int
     */
    protected abstract int price();
}

准备一个煎饼的基础套餐–纯煎饼

/**
 * 基础套餐
 */
public class BaseBetterCake extends BetterCake {

    @Override
    protected String getMsg() {
        return "煎饼";
    }

    @Override
    protected int price() {
        return 5;
    }
}

准备一个装饰器,用来给煎饼添加菜,但是加什么还未定

/**
 * 煎饼包装器的抽象类
 */
public abstract class BaseBetterCakeDecorator extends BetterCake {
    /**
     * 需要包装的煎饼
     */
    private BetterCake betterCake;

    /**
     * 通过有参构造传入需要包装的煎饼
     * @param betterCake
     */
    public BaseBetterCakeDecorator(BetterCake betterCake) {
        this.betterCake = betterCake;
    }

    @Override
    protected String getMsg() {
        return this.betterCake.getMsg();
    }

    @Override
    protected int price() {
        return this.betterCake.price();
    }
}

添加鸡蛋的装饰:先传入原有的煎饼,而后返回加好鸡蛋的煎饼

/**
 * 鸡蛋的装饰
 */
public class EggDecorator extends BaseBetterCakeDecorator{
    /**
     * 通过有参构造传入需要包装的煎饼
     *
     * @param betterCake
     */
    public EggDecorator(BetterCake betterCake) {
        super(betterCake);
    }

    @Override
    protected String getMsg() {
        return super.getMsg()+"+一个鸡蛋";
    }

    @Override
    protected int price() {
        return super.price()+1;
    }
}

同理建立加香肠的类

/**
 * 加香肠装饰
 */
public class SausageDecorator extends BaseBetterCakeDecorator{
    /**
     * 通过有参构造传入需要包装的煎饼
     *
     * @param betterCake
     */
    public SausageDecorator(BetterCake betterCake) {
        super(betterCake);
    }

    @Override
    protected String getMsg() {
        return super.getMsg()+"+一个香肠";
    }

    @Override
    protected int price() {
        return super.price()+2;
    }
}

测试:

public static void main(String[] args) {
        //准备了一个煎饼的模板--静态代理
        BetterCake betterCake;
        //准备了一个煎饼的基础套餐
        betterCake= new BaseBetterCake();
        //加鸡蛋,得到一个加了鸡蛋后的煎饼
        betterCake = new EggDecorator(betterCake);
        //再加一个鸡蛋,得到一个加了2个鸡蛋的煎饼
        betterCake = new EggDecorator(betterCake);
        //再加一个香肠,得到一个加了2个鸡蛋和一个香肠的煎饼
        betterCake = new SausageDecorator(betterCake);

        //如果还需要加其他菜种,则新建这个种类的类,即可添加任意数量
        System.out.println(betterCake.getMsg()+",价格:"+betterCake.price()+"元");
    }

结果
在这里插入图片描述
类关系图
在这里插入图片描述
打开依赖显示:
在这里插入图片描述
装饰器模式与静态代理的区别:【is-a】父子关系
装饰器始终强调【is-a】,即最终还是这个对象,只是添加了一些新的东西。就算加上了蛋、香肠,但它依然是煎饼-BetterCake;(子类既可以纵向扩展父类的功能[即在基础套餐的基础上决定由多少种菜可以加],又很灵活,可以由用户决定要横向拓展多少[即每种菜加多少]),在功能上,要么是调用父类功能,要么是扩展新功能,要么是覆盖,不会对原有功能增强。
代理模式到了最后确有可能不再满足【is-a】了,而是变成了一个其他的对象【媒婆】。静态代理会做功能的增强,在原有方法的前后加入新的逻辑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值