设计模式——装饰者模式

更多内容,前往 IT-BLOG

现实生活中常常需要给某类产品动态增加新的功能,如:给面条各种调味品。在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成一些核心功能。但在不改变其架构的情况下,可以动态地扩展其功能。所以这些都可以采用装饰模式来实现。

一、装饰者定义

【1】装饰者模式: 动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则。
【2】设计模式属于结构型模式。
【3】这种模式创建一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
【4】优点: 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
【5】缺点: 多层装饰比较复杂。

二、装饰者类图

在这里插入图片描述

三、案例代码分析

【1】定义一个装饰者和被装饰者都需要集成的抽象类(Food 食物)

public abstract class Food {
   
    private String des;
    private Double price;
 
    //其他类需要实现的抽象方法
    public abstract double cost();
        //get/set方法省略
}

【2】被装饰者需要继承的类(Noodles 面条)

public class Noodles extends Food{
   
    //这里获取到的价格是子类实现时设置的价格
    @Override
    public double cost() {
   
        return super.getPrice();
    }
}

【3】被装饰者具体的实现类之一(ChineseNoodles 中式面条)

public class ChineseNoodles extends Noodles{
   
    //构造器中只需要定义该产品的价格和描述,因为它是被装饰者,与平常类一样
    public ChineseNoodles() {
   
        setDes("中式面条");
        setPrice(25.00);
    }
}

【4】装饰者类都需要集成的公共类

public class Decorator extends Food{
   
    //将被装饰者组合进来
    private Food desFood;
    //构造器将其引入
    public Decorator(Food desFood) {
   
        this.desFood = desFood;
    }
    //将自己的价格与被装饰者价格进行成绩
    @Override
    public double cost() {
   
        System.out.println(desFood.getDes() +"价格:"+desFood.getPrice()+ "配料如下:"
                +super.getDes()+"价格:"+this.getPrice()+"总价"+(super.getPrice()+desFood.cost()) );
        //价格总计
        return super.getPrice()+desFood.cost();
    }
}

【5】装饰者实现类之一

//孜然类
public class Cumin extends Decorator{
   
    //构造器
    public Cumin(Food desFood) {
   
        super(desFood);
        setDes("孜然");
        setPrice(2.00);
    }
}

【6】客户端调用: 优点,一个产品可以被多个装饰者装饰,同时装饰者和被装饰者扩展时都非常灵活,只需要扩展自己的类即可,无需修改其他类。

public class Client {
   
    public static void main(String[] args) {
   
        //先定义一个被装饰者,返回对象要为最顶层的对象,这样被装饰者才能接受
        Food noodles = new ChineseNoodles();
        //定义一个装饰者对象
        Food cumin = new Cumin(noodles);
        //输出为:中式面条价格:25.0配料如下:孜然价格:2.0
        cumin.cost();
 
        //再定义一个装饰者 Pepper辣椒类
        Food pepper = new Pepper(cumin);
        //输出为:中式面条价格:25.0配料如下:孜然价格:2.0配料如下:辣椒价格:1.0总价28.0
        pepper.cost();
    }
}

四、装饰者模式在JDK应用的源码分析

【1】JDK 中流的使用用到了装饰者模式。从下面的客户端使用能够得出 FileInputStream 是被装饰者,DataInputStream 是装饰者类的一个实现类,下面就进入 FileInputStream 中查看源代码:

public class Decorator {
   
    public static void main(String[] args) throws Exception{
   
        DataInputStream dis = new DataInputStream(new FileInputStream("d:\\a.txt"));
    }
}

【2】FileInputStream 继承了 InputStream ,也就是上面提到的 Food 类及 ChineseNoodles 之间的关系。

public class FileInputStream extends InputStream{
     
    ......  
}

【3】进入 DataInputStream 装饰者类的实现类

public class DataInputStream extends FilterInputStream implements DataInput {
   
 
    /**
     * 构造器,将顶层接口 进行组合,父类装饰类的重写
     */
    public DataInputStream(InputStream in) {
   
        super(in);
    }
}

【4】最重要的部分:装饰者类 FilterInputStream 继承和组合了 InputStream 接口,被装饰者也实现了此接口。

//集成最顶层 InputStream 接口,被装饰者也集成的接口,因为此类的返回值要与被装饰类类型相同
public class FilterInputStream extends InputStream {
   
    /**
     * 组合 被装饰者类
     */
    protected volatile InputStream in;
 
    /**
     * 构造器
     */
    protected FilterInputStream(InputStream in) {
   
        this.in = in;
    }
}

【5】源码类图如下:与装饰者类的类图一致,易理解。

在这里插入图片描述

相关推荐

  1. 装饰模式设计模式

    2024-01-21 20:04:02       3 阅读
  2. 装饰设计模式总结

    2024-01-21 20:04:02       35 阅读
  3. 设计模式装饰模式

    2024-01-21 20:04:02       38 阅读
  4. 设计模式装饰模式

    2024-01-21 20:04:02       38 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-21 20:04:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-21 20:04:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-21 20:04:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-21 20:04:02       20 阅读

热门阅读

  1. Python输入输出流学习笔记

    2024-01-21 20:04:02       31 阅读
  2. C Primer Plus(第六版)13.10 复习题 第5题

    2024-01-21 20:04:02       32 阅读
  3. Python求解特殊回文数

    2024-01-21 20:04:02       33 阅读
  4. MySQL中的加密函数

    2024-01-21 20:04:02       39 阅读
  5. Docker:容器的两种运行模式(Foreground、Detached)

    2024-01-21 20:04:02       33 阅读
  6. C语言中的递归过程和递归工作栈

    2024-01-21 20:04:02       37 阅读
  7. 计算机网络(第六版)复习提纲6

    2024-01-21 20:04:02       36 阅读
  8. 【笔记】Helm-3 主题-9 Helm高级技术

    2024-01-21 20:04:02       34 阅读