设计模式学习(一)结构型模式——装饰模式

(一)装饰模式(包装模式)

  1. 解决什么问题

    1. 向要对一个类进行多种组合方式的扩展,继承的话每种组合都是一个子类,而装饰者模式则可以每一个添加项是一个子类,根据需要对子类们所包含的功能进行随意的组合。

    2. 装饰品和被装饰者要继承同一个接口,不同的装饰品之间也要继承同一个抽象类,才能满足随意扩展的需求

比如说一杯奶茶(被装饰着),5种小料,包括奶盖,芋圆,珍珠,椰果和奥利奥(饰品),如果想要喝到不同种类组合的奶茶(不同结果类),且在小料种类增加时不更改原有菜单(原有代码)怎么办?

如果将组合列举出来(普通继承),将会有上百种组合(全部列出来会有几百个类);但如果我们可以以小料为单位(每一个装饰品实现一个装饰类,且全部与被装饰者继承同一个类),奶茶作为成员变量,需要什么小料就加什么小料就可以了(将原有类传进去,并在此基础上添加新功能)

最终呈现的是一个链式的,递进的对对象的封装。

2. 结构

3. 实现代码

//抽象构件
public interface Beverage {
    int price();
    String describe();
}
//具体构件
public class MilkTea implements Beverage {
    @Override
    public int price() {
        return 10;
    }
​
    @Override
    public String describe() {
        return "奶茶";
    }
}
//抽象装饰
public abstract class Flavour implements Beverage {
    private Beverage baseDrink;
​
    public Beverage getBaseDrink() {
        return baseDrink;
    }
​
    public void setBaseDrink(Beverage baseDrink) {
        this.baseDrink = baseDrink;
    }
}
//具体装饰1
public class CheeseDrink extends Flavour {
    public CheeseDrink(Beverage beverage){
        setBaseDrink(beverage);
    }
    @Override
    public String describe() {
        return getBaseDrink().describe()+" +芝士奶盖";
    }
​
    @Override
    public int price() {
        return getBaseDrink().price()+3;
    }
}
//具体装饰2
public class OreoDrink extends Flavour {
    public OreoDrink(Beverage beverage){
        setBaseDrink(beverage);
    }
    @Override
    public String describe() {
        return getBaseDrink().describe()+" +奥利奥碎";
    }
​
    @Override
    public int price() {
        return getBaseDrink().price()+7;
    }
}
//具体装饰3
public class PearlDrink extends Flavour {
    public PearlDrink(Beverage b){
        this.setBaseDrink(b);
    }
    @Override
    public String describe() {
        return getBaseDrink().describe()+" +珍珠";
    }
​
    @Override
    public int price() {
        return getBaseDrink().price()+5;
    }
}
public static void main(String[] args){
        Beverage a = new MilkTea();
        System.out.println(a.describe());
        System.out.println(a.price());
        Flavour b = new PearlDrink(a);
        System.out.println(b.describe());
        System.out.println(b.price());
        Flavour c = new CheeseDrink(b);
        System.out.println(c.describe());
        System.out.println(c.price());
        Flavour d = new OreoDrink(b);
        System.out.println(d.describe());
        System.out.println(d.price());
    }

输出:

4. 缺点

  • 每一种饰品单独声明一个类,当饰品种类特别多时,装饰者类就会特别多

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值