【软考】设计模式之装饰器模式

发布于:2024-05-23 ⋅ 阅读:(30) ⋅ 点赞:(0)

1. 说明
  • 1.动态地给一个对象添加一些额外的职责
  • 2.Decorator Pattern。
  • 3.就增加功能而言,装饰器模式比生成子类更加灵活。
  • 4.一种在不改变现有对象结构的情况下,动态地给对象增加一些职责(即增加额外功能)的设计模式。
  • 5.属于对象结构型模式。
2. 应用场景
  • 1.扩展功能:当需要给某个对象添加额外的功能,但又不想修改其源代码或结构时,可以使用装饰器模式。例如,在软件开发中,可以使用装饰器模式来扩展类的功能,而无需创建新的子类。
  • 2.动态代理:装饰器模式允许在运行时动态地给对象添加或撤销功能。这对于需要动态修改对象行为的场景非常有用。
  • 3.缓存功能:通过装饰器模式,可以为对象添加缓存功能,以提高系统的性能。例如,可以在数据访问层使用装饰器模式来缓存数据,减少对数据库的频繁访问。
  • 4.日志记录:在系统中,经常需要记录对象的操作历史或状态变化。通过装饰器模式,可以轻松地给对象添加日志记录功能,方便后续的调试和错误追踪。
  • 5.用户界面定制:在图形用户界面(GUI)设计中,可以使用装饰器模式来定制和扩展控件的功能。例如,可以为按钮添加动画效果、改变样式或添加额外的交互功能。
  • 6.文件处理:在处理文件时,可以使用装饰器模式来添加各种文件处理功能,如压缩、加密、解密等。这样,用户可以根据需要选择不同的装饰器来处理文件。
  • 7.网络请求:在发送网络请求时,可以使用装饰器模式来添加各种请求处理功能,如超时重试、身份验证、请求签名等。这些功能可以在不修改原始请求代码的情况下动态地添加到请求中。
  • 8.数据处理:在处理数据时,可以使用装饰器模式来添加各种数据处理功能,如排序、过滤、转换等。这些功能可以根据需要动态地添加到数据处理流程中。
3. 结构图

在这里插入图片描述

4. 构成
  • 1.Commponent(抽象组件):定义一个对象接口,可以给这些对象动态地添加职责。定义一个接口或抽象类,规定被装饰对象的行为。
  • 2.ConcreteComponent(具体组件):定义一个对象,可以给这个对象添加职责。实现抽象组件接口或继承抽象组件类,是装饰器模式中的原始对象。
  • 3.Decorator(抽象装饰器):维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。继承或实现抽象组件接口,并持有一个指向抽象组件的引用。抽象装饰器通常还包含一些用于增加额外功能的方法。
  • 4.ConcreteDecorator(具体装饰器):向组件添加职责。继承抽象装饰器类,并实现具体的额外功能。具体装饰器可以根据需要添加多个,以实现不同的效果。
5. 适用性
  • 1.在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 2.处理那些可以撤销的职责
  • 3.当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是,由于类定义被隐藏,或类定义不能用于生成子类。
6. 优点
  • 1.灵活性:装饰器是继承的有力补充,比继承更加灵活。它可以在不改变原有对象的情况下,动态地给一个对象扩展功能,实现即插即用。
  • 2.可扩展性:通过使用不同的装饰类以及这些装饰类的排列组合,可以实现不同的效果,满足不同的需求。
  • 3.遵循开闭原则:装饰器模式在扩展功能时,不需要修改原有类的代码,符合开闭原则(对扩展开放,对修改关闭)。
7. 缺点
  • 1.增加复杂性:装饰器模式会增加许多子类,过度使用会增加程序的复杂性。
  • 2.难以理解:如果装饰器类过多,可能会使代码变得难以理解和维护。
8. java示例
  • 1.抽象组件
package com.learning.decorator.person;

/**
 * 抽象组件
 * 定义一个人的接口
 * 获取人的描述
 */
public interface Person {
    String getDescription();  
}
  • 2.具体组件
package com.learning.decorator.person;

/**
 * 基础的人
 * 具体组件
 */
public class BasePerson implements Person {
    /**
     * 人的姓名
     */
    private String name;  
  
    public BasePerson(String name) {  
        this.name = name;  
    }  
  
    @Override  
    public String getDescription() {  
        return name;  
    }  
}
  • 3.抽象装饰器
package com.learning.decorator.person;

/**
 * 抽象装饰器
 * 衣服装饰器
 */
public abstract class ClothingDecorator implements Person {
    //被装饰的对象
    protected Person person;  
  
    public ClothingDecorator(Person person) {  
        this.person = person;  
    }  
  
    @Override  
    public String getDescription() {  
        return decorate(person.getDescription());  
    }  
  
    protected abstract String decorate(String description);  
}
  • 4.具体装饰器帽子装饰器
package com.learning.decorator.person;

/**
 * 具体装饰器
 * 帽子装饰器
 */
public class HatDecorator extends ClothingDecorator {
    public HatDecorator(Person person) {  
        super(person);  
    }

    /**
     * 帽子装饰,戴了一个帽子
     * @param description
     * @return
     */
    @Override  
    protected String decorate(String description) {  
        return description + "戴了一个帽子";
    }  
}
  • 5.具体装饰器围巾装饰器
package com.learning.decorator.person;

/**
 * 具体装饰器
 * 毛巾装饰器
 */
public class ScarfDecorator extends ClothingDecorator {
    public ScarfDecorator(Person person) {  
        super(person);  
    }

    /**
     * 覆盖父类的方法, 戴了一条围巾
     * @param description
     * @return
     */
    @Override  
    protected String decorate(String description) {  
        return description + "戴了一条围巾";
    }  
}
  • 6.客户端
package com.learning.decorator.person;

public class Client {
    public static void main(String[] args) {  
        Person person = new BasePerson("张三");
        System.out.println(person.getDescription());
  
        Person personWithHat = new HatDecorator(person);
        System.out.println(personWithHat.getDescription());
  
        Person personWithHatAndScarf = new ScarfDecorator(personWithHat);
        System.out.println(personWithHatAndScarf.getDescription());
  
    }
}
  • 7.示例截图
    在这里插入图片描述