设计模式学习笔记:装饰器模式(Decorator)

如果你要做一件事,不要到处宣言自己的想法,只管安安静静地去做,值不值,时间是最好的证明,自己的人生,得自己负责。

一、装饰器模式介绍

装饰器模式是设计模式中结构型模式的一种。装饰器模式其实可以看作另一种方式的继承,使用装饰器模式可以向现有的类添加新功能,同时又不改变其结构。

例如:煎饼加上鸡蛋变成鸡蛋煎饼,再加上青菜就是青菜鸡蛋煎饼,煎饼就是被装饰的对象,鸡蛋和青菜就是装饰器。
在这里插入图片描述

二、装饰器模式代码演示

装饰器模式需要装饰者和被装饰者实现同样的接口或继承同样的父类,其中装饰者持有接口或父类的对象。

现有场景如下:早餐店卖饼,有油饼和煎饼,还有配料鸡蛋、青菜、海带,配料和饼可以自由组合成不同的早餐。

首先我们建一个接口 Cake :

import java.math.BigDecimal;

/**
 * 饼 的接口
 *
 * @author ZhengNC
 * @date 2020/7/2 10:41
 */
public interface Cake {

    BigDecimal getPrice();

    String getName();
}

然后是两种饼的类:

import java.math.BigDecimal;

/**
 * 煎饼
 *
 * @author ZhengNC
 * @date 2020/7/2 10:51
 */
public class BatterCake implements Cake {

    private BigDecimal price;

    private String name;

    public BatterCake() {
        price = new BigDecimal("2.0");
        name = "煎饼";
    }

    @Override
    public BigDecimal getPrice() {
        return price;
    }

    @Override
    public String getName() {
        return name;
    }
}
import java.math.BigDecimal;

/**
 * 油饼
 *
 * @author ZhengNC
 * @date 2020/7/2 10:48
 */
public class OilCake implements Cake{

    private BigDecimal price;

    private String name;

    public OilCake(){
        price = new BigDecimal("1.0");
        name = "油饼";
    }

    @Override
    public BigDecimal getPrice() {
        return price;
    }

    @Override
    public String getName() {
        return name;
    }
}

接下来是配料的类(装饰器):

import java.math.BigDecimal;

/**
 * 鸡蛋配料
 *
 * @author ZhengNC
 * @date 2020/7/2 10:55
 */
public class EggDecorator implements Cake {

    private Cake cake;

    private BigDecimal price;

    private String name;

    public EggDecorator(Cake cake){
        this.cake = cake;
        price = new BigDecimal("1.5");
        name = "鸡蛋";
    }

    @Override
    public BigDecimal getPrice() {
        return cake.getPrice().add(this.price);
    }

    @Override
    public String getName() {
        return this.name + cake.getName();
    }
}
import java.math.BigDecimal;

/**
 * 海带配料
 *
 * @author ZhengNC
 * @date 2020/7/2 11:05
 */
public class KelpDecorator implements Cake {

    private Cake cake;

    private BigDecimal price;

    private String name;

    public KelpDecorator(Cake cake) {
        this.cake = cake;
        price = new BigDecimal("1.0");
        name = "海带";
    }

    @Override
    public BigDecimal getPrice() {
        return cake.getPrice().add(this.price);
    }

    @Override
    public String getName() {
        return this.name + cake.getName();
    }
}
import java.math.BigDecimal;

/**
 * 青菜配料
 *
 * @author ZhengNC
 * @date 2020/7/2 11:01
 */
public class VegetableDecorator implements Cake {

    private Cake cake;

    private BigDecimal price;

    private String name;

    public VegetableDecorator(Cake cake) {
        this.cake = cake;
        price = new BigDecimal("0.5");
        name = "青菜";
    }

    @Override
    public BigDecimal getPrice() {
        return cake.getPrice().add(this.price);
    }

    @Override
    public String getName() {
        return this.name + cake.getName();
    }
}

最后是测试类(厨师):

/**
 * @author ZhengNC
 * @date 2020/7/2 11:07
 */
public class Test {

    public static void main(String[] args) {
        //要一个油饼,不要任何配料
        Cake cake1 = new OilCake();
        System.out.println(cake1.getName() + "\t" + cake1.getPrice() + "元");

        //要一个加鸡蛋的煎饼
        Cake cake2 = new EggDecorator(new BatterCake());
        System.out.println(cake2.getName() + "\t" + cake2.getPrice() + "元");

        //要一个加鸡蛋和海带的油饼
        Cake cake3 = new EggDecorator(new KelpDecorator(new OilCake()));
        System.out.println(cake3.getName() + "\t" + cake3.getPrice() + "元");

        //要一个加青菜和鸡蛋的煎饼
        Cake cake4 = new VegetableDecorator(new EggDecorator(new BatterCake()));
        System.out.println(cake4.getName() + "\t" + cake4.getPrice() + "元");

    }
}

出餐(运行结果):

油饼	1.0元
鸡蛋煎饼	3.5元
鸡蛋海带油饼	3.5元
青菜鸡蛋煎饼	4.0元
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值