学习笔记-设计模式之装饰器模式

一、概念

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

简言之:大桶套小桶

二、实现

 需求:现在有人在路边卖煎饼,原价5元,加1个鸡蛋1元,加1个香肠2元,要求给顾客做两个煎饼:

第一个加一个鸡蛋,第二个加一个鸡蛋一个香肠。

首先创建煎饼类

 1 public class BatterCake {
 2 
 3     protected String getMsg(){
 4         return "煎饼";
 5     }
 6 
 7     public int getPrice(){
 8         return 5;
 9     }
10 
11 }

getMsg方法返回当前煎饼信息,getPrice返回当前煎饼价格。

创建加一个鸡蛋的煎饼

 1 public class BatterCakeWithEgg extends BatterCake {
 2 
 3     protected String getMsg() {
 4         return super.getMsg() + "+1 个鸡蛋";
 5     }
 6 
 7     //加一个鸡蛋加 1 块钱
 8     public int getPrice() {
 9         return super.getPrice() + 1;
10     }
11 }

这里通过继承的方式来实现,同理创建加一个鸡蛋一个香肠煎饼

 1 public class BatterCakeWithEggAndSausage extends BatterCakeWithEgg {
 2     @Override
 3     protected String getMsg() {
 4         return super.getMsg() + "+1 根香肠";
 5     }
 6 
 7     @Override
 8     //加一个香肠加 2 块钱
 9     public int getPrice() {
10         return super.getPrice() + 2;
11     }
12 
13 }

测试类

 1 public class BatterCakeTest {
 2 
 3     public static void main(String[] args) {
 4         BatterCake battercake = new BatterCake();
 5         System.out.println(battercake.getMsg() + ",总价格:" + battercake.getPrice());
 6 
 7         BatterCake batterCakeWithEgg = new BatterCakeWithEgg();
 8         System.out.println(batterCakeWithEgg.getMsg() + ",总价格:" + batterCakeWithEgg.getPrice());
 9         BatterCake batterCakeWithEggAndSausage = new BatterCakeWithEggAndSausage();
10         System.out.println(batterCakeWithEggAndSausage.getMsg() + ",总价格:" + batterCakeWithEggAndSausage.getPrice());
11     }
12 }

输出

煎饼,总价格:5
煎饼+1 个鸡蛋,总价格:6
煎饼+1 个鸡蛋+1 根香肠,总价格:8

虽然实现了基本的业务需求,但是,当用户需要加两个鸡蛋两根香肠的煎饼,或者是一个鸡蛋两根香肠的煎饼时都需要新增一个类。增加了系统复杂度。

下面看看用装饰器实现。

创建煎饼接口

1 public interface BatterCake {
2 
3     String getMsg();
4 
5     int getPrice();
6 }

创建鸡蛋装饰类

public class EggDecorator implements BatterCake {
    private BatterCake battercake;

    public EggDecorator(BatterCake battercake) {
        this.battercake = battercake;
    }

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

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

创建香肠装饰类

 1 public class SausageDecorator implements BatterCake {
 2     private BatterCake battercake;
 3 
 4     public SausageDecorator(BatterCake battercake) {
 5         this.battercake = battercake;
 6     }
 7 
 8     @Override
 9     public String getMsg() {
10         return battercake.getMsg() + "+1根香肠";
11     }
12 
13     @Override
14     public int getPrice() {
15         return battercake.getPrice() + 2;
16     }
17 }

测试类

 1 public class BatterCakeTest {
 2 
 3     public static void main(String[] args) {
 4         BatterCake battercake = new BaseCake();
 5         // 加一个鸡蛋
 6         BatterCake cakeWithOneEgg = new EggDecorator(battercake);
 7         System.out.println();
 8         // 加两个鸡蛋
 9         BatterCake cakeWithTowEgg = new EggDecorator(new EggDecorator(battercake));
10         // 加两个鸡蛋两根香肠
11         BatterCake cakeWithTowEggAndTowSausage = new SausageDecorator(new SausageDecorator(new EggDecorator(new EggDecorator(battercake))));
12         System.out.println(cakeWithTowEggAndTowSausage.getMsg() + ",总价:" + cakeWithTowEggAndTowSausage.getPrice());
13     }
14 }

这样,无论用户需要多少个鸡蛋,多少根香肠都能轻松实现。

posted @ 2020-08-16 16:52  落雨有清·风  阅读(203)  评论(0编辑  收藏  举报