设计模式-结构型-装饰者模式

描述

  • 在不改变原有类对象结构的情况下,动态给该对象增加一些额外的功能

角色

  • 抽象目标对象
  • 目标实现对象
  • 抽象装饰:
  • 具体装饰:

实现

public class Test {
    public static void main(String[] args) {
        BlackTea blackTea = new BlackTea();
        System.out.println(blackTea.getName() +blackTea.cost());
        Pearl pearl = new Pearl(blackTea);
        // 类似套娃,子类装饰父类,父类装饰父类的父类
        System.out.println(pearl.getName() +pearl.cost());
        Pearl pearl2 = new Pearl(pearl);
        System.out.println(pearl2.getName() +pearl2.cost());
        Coconut coconut = new Coconut(pearl2);
        System.out.println(coconut.getName() +coconut.cost());

    }
}

// 奶茶店,抽象目标对象
abstract class MilkTeaShop {
    private double price;
    private String name;

    MilkTeaShop(double price, String name) {
        this.price = price;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }

    // 计算
    abstract double cost();
}

// 红茶 具体对象
class BlackTea extends MilkTeaShop {

    BlackTea() {
        super(9.5, "红茶");
    }

    @Override
    double cost() {
        return getPrice();
    }
}

// 配料 抽象装饰类 要装饰哪个对象。继承它。然后拿自己去装饰它
abstract class MixedIngredients extends MilkTeaShop {

    private MilkTeaShop milkTeaShop;

    MixedIngredients(MilkTeaShop milkTeaShop, double price, String name) {
        super(price, name);
        this.milkTeaShop = milkTeaShop;
    }

    public MilkTeaShop getMilkTeaShop() {
        return milkTeaShop;
    }
}

// 珍珠 具体装饰者
class Pearl extends MixedIngredients {

    Pearl(MilkTeaShop milkTeaShop) {
        super(milkTeaShop, 2.0, "珍珠");
    }

    @Override
    double cost() {
        return super.getPrice() + getMilkTeaShop().cost();
    }

    @Override
    public String getName() {
        return super.getName() + getMilkTeaShop().getName();
    }
}

// 椰果 具体装饰者
class Coconut extends MixedIngredients {

    Coconut(MilkTeaShop milkTeaShop) {
        super(milkTeaShop, 1.5, "椰果");
    }

    @Override
    double cost() {
        return super.getPrice() + getMilkTeaShop().cost();
    }

    @Override
    public String getName() {
        return super.getName() + getMilkTeaShop().getName();
    }
}

// 绿茶 具体目标
class GreenTea extends MilkTeaShop {
    GreenTea() {
        super(10.0, "绿茶");
    }

    @Override
    double cost() {
        return getPrice();
    }
}

优点

  • 在继承的基础上进行扩展,灵活,良好的扩展性。
  • 使用更加方便,可动态的扩展功能, 遵循开闭原则。
  • 装饰者和目标对象,可以独立扩展,不会相互耦合。

使用场景

  • 当不能采用或不好采用 继承 的方式对系统进行扩充时。
  • 如:final修饰的类。
  • 如:当有大量子类时,要对每一个子类进行扩展,子类数据呈现爆炸性增长。
  • 在不影响其它子类的情况下,以动态,透明的方式对当前对象扩展。

JDK中的使用

  • IO流的 Buffered系列
  • 如BufferedWriter
public class Test {
    public static void main(String[] args) throws IOException {

        FileWriter fw = new FileWriter("");
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write("abc");
        bw.close();
   }
}
// BufferedWriter对Writer进行了装饰者模式的增强(增加了缓冲区)(继承,聚合Writer)
public class BufferedWriter extends Writer {

    private Writer out;
    
    public BufferedWriter(Writer out) {
        this(out, defaultCharBufferSize);
    }

静态代理和装饰者模式的区别

相同点

  • 都要实现目标对象相同的业务接口
  • 都声明了目标对象
  • 都可以在不修改目标对象的前提下增强目标方法
    不同点:
  • 目的不同,装饰者是为了增强;而代理对象是为了隐藏
  • 构建不同,装饰者是由外界传递进来,聚合,增强;静态代理是内部创建,组合隐藏对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值