浅谈装饰者模式

装饰者模式的应用场景

装饰者模式是指在不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的替代策略。适用于以下场景:
1.用于扩展一个类的功能或给一个类添加附加职责。
2.动态的给一个对象添加功能,这些功能可以再动态的撤销。
下列以煎饼摊为例(继承模式实现):
煎饼类:

package decorator;

/**
 * Created by Lenovo on 2019-7-20.
 */
public class Battercake {
    protected String getMsg(){
        return "煎饼";
    }
    public int getPrice(){
        return 5;
    }
}

加鸡蛋:

package decorator;

/**
 * Created by Lenovo on 2019-7-20.
 */
public class BattercakeWithEgg extends Battercake {
    @Override
    protected String getMsg() {
        return super.getMsg()+"1个鸡蛋";
    }

    @Override
    public int getPrice() {
        return super.getPrice()+1;
    }
}

加鸡蛋加香肠

package decorator;

/**
 * Created by Lenovo on 2019-7-20.
 */
public class BattercakeWithEggAndSausage extends BattercakeWithEgg {
    @Override
    protected String getMsg() {
        return super.getMsg()+"一根香肠";
    }

    @Override
    public int getPrice() {
        return super.getPrice()+2;
    }
}

测试类

package decorator;

/**
 * Created by Lenovo on 2019-7-20.
 */
public class BattercakeTest {
    public static void main(String[] args){
        Battercake battercake=new Battercake();
        System.out.println(battercake.getMsg()+",总价格:"+battercake.getPrice());

        Battercake battercakeWithEgg=new BattercakeWithEgg();
        System.out.println(battercakeWithEgg.getMsg()+",总价格:"+battercakeWithEgg.getPrice());

        Battercake battercakeWithEggAndSausage=new BattercakeWithEggAndSausage();
        System.out.println(battercakeWithEggAndSausage.getMsg()+",总价格:"+battercakeWithEggAndSausage.getPrice());
    }
}

从以上例子可以发现,如果用户需要2个鸡蛋加一根香肠,那么我们用现有的类结构是创建不出来的,除非再定制化创建一个类,这样一直加定制显然是不科学的。那么下面我们就用装饰者模式来解决上面的问题。
煎饼抽象类

package decoratorV2;

/**
 * Created by Lenovo on 2019-7-20.
 */
public abstract class Battercake {
    protected abstract String getMsg();
    protected abstract int getPrice();
}

基本煎饼套餐

package decoratorV2;

/**
 * Created by Lenovo on 2019-7-20.
 */
public class BaseBattercake extends Battercake {
    @Override
    protected String getMsg() {
        return "煎饼";
    }

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

扩展套餐的抽象装饰者

package decoratorV2;

/**
 * Created by Lenovo on 2019-7-20.
 */
public abstract class BattercakeDecorator extends Battercake  {
    //静态代理,委派
    private Battercake battercake;

    public BattercakeDecorator(Battercake battercake) {
        this.battercake = battercake;
    }

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

    @Override
    protected int getPrice() {
        return this.battercake.getPrice();
    }
}

鸡蛋装饰者

package decoratorV2;

/**
 * Created by Lenovo on 2019-7-20.
 */
public class EggDecorator extends BattercakeDecorator {
    public EggDecorator(Battercake battercake) {
        super(battercake);
    }
    protected void doSomething(){
    }

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

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

香肠测试类

package decoratorV2;

/**
 * Created by Lenovo on 2019-7-20.
 */
public class SausageDecorator extends BattercakeDecorator {
    public SausageDecorator(Battercake battercake) {
        super(battercake);
    }
    protected void doSomething(){

    }

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

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

测试类

package decoratorV2;

/**
 * Created by Lenovo on 2019-7-20.
 */
public class BattercakeTest {
    public static void main(String [] args){
        Battercake battercake;
        //路边摊买一个煎饼
        battercake =new BaseBattercake();
        //加鸡蛋
        battercake=new EggDecorator(battercake);
        //加香肠
        battercake=new SausageDecorator(battercake);
        //跟静态代理最大的区别是职责不同
        //静态代理不一定要满足is-a的关系
        //静态代理会做功能代理,同一个职责变得不一样
        //装饰者更多考虑是扩展
        System.out.println(battercake.getMsg()+",总价:"+battercake.getPrice());
    }
}

相关的类图:
在这里插入图片描述
装饰者的优点:
1.装饰者是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象扩展功能,即插即用。
2.通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。
3.装饰者完全遵守开闭原则。
缺点:
1.会出现更多的代码,更多的类,增加程序复杂类。
2.动态装饰时,多层装饰时会更复杂。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值