首页 > 其他分享 >设计模式-装饰模式

设计模式-装饰模式

时间:2023-09-03 22:01:40浏览次数:39  
标签:component Component 模式 public 组件 operation 设计模式 装饰



文章目录

  • 一、简介
  • 二、基本概念
  • 三、装饰模式的结构和实现
  • 类图解析:
  • 装饰器的实现方式
  • 继承实现:
  • 组合实现:
  • 继承和组合对比
  • 四、装饰模式的应用场景
  • 五、与其他模式的关系
  • 六、总结


一、简介

装饰模式是一种结构型设计模式,它允许动态地向对象添加额外的功能。

二、基本概念

设计模式-装饰模式_装饰模式

  1. 装饰模式定义:在不改变原有对象结构的情况下,通过对其进行包装拓展,以达到增强功能的目的。
  2. 装饰器角色:负责给组件对象附加额外的功能,实现了与组件具有相同接口的装饰器类。
  3. 组件角色:拥有核心功能的原始对象。
  4. 抽象组件角色:定义了组件对象的接口,可以是抽象类或接口。
  5. 具体组件角色:实现了抽象组件角色的具体对象。

三、装饰模式的结构和实现

类图解析:

// 抽象组件角色
public interface Component {
    void operation();
}

// 具体组件角色
public class ConcreteComponent implements Component {
    public void operation() {
        // 实现核心功能
        System.out.println("这是具体组件角色的核心功能");
    }
}

// 装饰器角色
public abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    public void operation() {
        component.operation();
    }
}

// 具体装饰器角色
public class ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }

    public void operation() {
        // 添加额外功能代码
        System.out.println("具体装饰器角色:"+"执行核心组件的功能前111");
        super.operation();
        // 添加额外功能代码
        System.out.println("具体装饰器角色:"+"执行核心组件的功能后2222");
    }
}
  1. 客户端代码示例:
Component component = new ConcreteComponent(); // 创建具体组件对象
component.operation(); // 调用核心功能

Component decoratedComponent = new ConcreteDecorator(component); // 使用具体装饰器装饰组件
decoratedComponent.operation(); // 调用增强功能

设计模式-装饰模式_装饰模式_02

装饰器的实现方式

继承实现:

具体装饰器继承装饰器抽象类,通过重写父类方法实现功能拓展
  1. 继承实现方式:
// 抽象组件角色
interface Component {
    void operation();
}

// 具体组件角色
class ConcreteComponent implements Component {
    public void operation() {
        // 执行核心功能
        System.out.println("执行核心功能");
    }
}

// 抽象装饰器角色
abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    public void operation() {
        component.operation();
    }
}

// 具体装饰器角色
class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        // 添加额外的功能代码
        System.out.println("添加额外的功能代码A");
    }
}

class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        // 添加额外的功能代码
        System.out.println("添加额外的功能代码B");
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        // 创建具体组件对象
        Component component = new ConcreteComponent();

        // 创建具体装饰器对象,并包装组件对象
        Component decoratorA = new ConcreteDecoratorA(component);
        Component decoratorB = new ConcreteDecoratorB(decoratorA);

        // 调用装饰器的操作方法,实现功能的拓展
        decoratorB.operation();
    }
}

组合实现:

具体装饰器持有装饰器抽象类的实例,通过调用实例方法实现功能拓展。
2. 组合实现方式:

// 抽象组件角色
interface Component {
    void operation();
}

// 具体组件角色
class ConcreteComponent implements Component {
    public void operation() {
        // 执行核心功能
        System.out.println("执行核心功能");
    }
}

// 装饰器角色
class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    public void operation() {
        component.operation();
    }
}

// 具体装饰器角色
class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        // 添加额外的功能代码
        System.out.println("添加额外的功能代码A");
    }
}

class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        // 添加额外的功能代码
        System.out.println("添加额外的功能代码B");
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        // 创建具体组件对象
        Component component = new ConcreteComponent();

        // 创建具体装饰器对象,并包装组件对象
        Component decoratorA = new ConcreteDecoratorA(component);
        Component decoratorB = new ConcreteDecoratorB(decoratorA);

        // 调用装饰器的操作方法,实现功能的拓展
        decoratorB.operation();
    }
}

这两个示例中,都有一个抽象的组件角色(Component),一个具体的组件角色(ConcreteComponent),以及几个具体的装饰器角色(ConcreteDecorator)。具体装饰器角色在构造函数中接收一个组件对象,并在自身的 operation() 方法中调用组件对象的 operation() 方法,并添加额外的功能代码。

在使用示例中,我们创建了具体组件对象和具体装饰器对象,并将它们进行组合,最后调用装饰器的 operation() 方法来实现功能的拓展。

继承和组合对比

在装饰器模式中,继承实现和组合实现是两种常见的方式。它们在实现装饰器功能时略有不同:
继承实现:

  • 优点:
  • 简单直接:通过继承抽象装饰器类,具体装饰器可以直接重写方法并添加额外功能。
  • 可复用性高:可以轻松地创建多个具体装饰器,并进行组合拓展。
  • 缺点:
  • 类爆炸:每个具体装饰器都需要创建一个新的类,当装饰器数量增多时,类的数量也会大量增加。
  • 静态结构:类的组合和功能拓展是在编译时静态决定的,无法动态地改变组合方式。

组合实现:

  • 优点:
  • 灵活组合:具体装饰器持有抽象装饰器对象,可以在运行时动态地组合不同的装饰器对象,实现不同的功能拓展组合。
  • 类结构简单:相对于继承实现,不需要创建过多的具体装饰器类,类结构相对简单。
  • 缺点:
  • 代码复杂度较高:需要在具体装饰器中额外处理抽象装饰器对象的方法调用。可能需要在抽象装饰器中定义一些默认实现,以避免空指针异常。

根据具体需求和设计考虑,可以选择适合的实现方式。继承实现适用于静态且数量有限的装饰器组合,而组合实现适用于动态和灵活的装饰器组合。两种实现方式都能实现装饰器模式的基本功能,只是在代码结构和使用方式上略有差异。

四、装饰模式的应用场景

  1. 动态添加功能:当需要在不修改现有代码的情况下,动态地给对象添加新功能时,装饰模式可以很好地满足这一需求。
  2. 避免子类爆炸:利用装饰模式,可以避免通过创建大量子类来实现各种功能组合的问题。
  3. 透明性 vs. 安全性:装饰模式中的装饰器和组件具有相同的接口,使得对于客户端而言,无需关心具体是使用了原始组件还是装饰器对象,实现了透明性。

五、与其他模式的关系

  1. 装饰模式 vs. 适配器模式:装饰模式侧重于给对象动态添加功能,而适配器模式则是为了让不兼容的类能够协同工作。
  2. 装饰模式 vs. 组合模式:装饰模式和组合模式都采用了递归组合的思想,但装饰模式着重于给对象添加功能,而组合模式着重于构建对象的树形结构。
  3. 装饰模式 vs. 桥接模式:桥接模式将抽象部分和实现部分解耦,而装饰模式则是在不改变对象结构的基础上,拓展其功能。

六、总结

装饰模式通过包装对象实现功能的动态拓展,使得系统具有更高的灵活性和可扩展性。它应用广泛,在动态添加功能、避免子类爆炸等场景都很有价值。同时,要注意使用装饰模式时,保持透明性和安全性的平衡,确保装饰器和组件具有一致的接口。


标签:component,Component,模式,public,组件,operation,设计模式,装饰
From: https://blog.51cto.com/u_15918766/7343560

相关文章

  • 设计模式-迭代器
    文章目录1.引言1.1概述1.2设计模式1.3迭代器模式的应用场景1.4迭代器模式的作用2.基本概念2.1迭代器Iterator2.2聚合Aggregate2.3具体聚合ConcreteAggregate3.Java实现迭代器模式3.1Java集合框架3.2Java迭代器接口3.3Java迭代器模式实现示例4.迭代器模式的优......
  • Go 设计模式中策略模式
    鱼弦:全栈领域创作新星创作者、51CTO(Top红人+专家博主)、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen)  在Go设计模式中,策略模式是一种行为型模式,用于在运行时选择算法的行为。策略模式将不同的算法封装成各自的策略对象,并使得这些策略对象......
  • Go 设计模式中访问者模式
    鱼弦:全栈领域创作新星创作者、51CTO(Top红人+专家博主)、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen)在Go设计模式中,访问者模式(VisitorPattern)是一种行为型模式,用于将算法与数据结构分离,使得算法可以独立地操作数据结构的不同元素,同时遵循......
  • c++单例模式总结
    分类懒汉式:实例对象在第一次被使用时才进行初始化。饿汉式:实例在定义时就被初始化。特点1、构造函数和析构函数私有化,不允许外部创建实例对象。2、拷贝构造函数和复制运算符重载被delete,不允许产生新的实例。3、内部定义一个私有的静态数据成员,该成员为本类的实例化对象。4......
  • 基于状态模式: 没有实践,再多的理论都是扯淡!!!
    基于状态模式:没有实践的理论都是扯淡!!!定义状态模式是一种面向对象的设计模式,它允许一个对象在其内部状态改变时改变它对应的行为。状态模式的关键在于如何区分事物内部的状态,事物内部状态的改变往往会带来事物的行为的改变。通常我们谈到封装,一般都会优先封装对象的行为(比如,某个函......
  • 设计模式:通俗易懂版
    ......
  • 两个例子理解js设计模式中的【适配器模式】
    适配器模式的精髓:如果现有的接口已经能够正常工作,那我们就永远不会用上适配器模式。适配器模式是一种“亡羊补牢”的模式,没有人会在程序的设计之初就使用它。因为没有人可以完全预料到未来的事情,也许现在好好工作的接口,未来的某天却不再适用于新系统,那么我们可以用适配器模式把旧......
  • mongodb副本集(仲裁模式)修改各节点ip(update方式)
    环境:OS:Centos7mongodb:5.0当前的ip  变更后的ip192.168.1.105192.168.1.108PRIMARY192.168.1.106192.168.1.109SECONDARY192.168.1.107192.168.1.110ARBITER 1.查看当前的集群登录一个节点......
  • @Configuration 注解的 Full 模式和 Lite 模式!
    @Configuration注解相信各位小伙伴经常会用到,但是大家知道吗,这个注解有两种不同的模式,一种叫做Full模式,另外一种则叫做Lite模式。准确来说,Full模式和Lite模式其实Spring容器在处理Bean时的两种不同行为。这两种不同的模式在使用时候的表现完全不同,今天松哥就来和各位小......
  • javaee spring注解设置单例模式和懒加载模式
    @Lazy懒加载@Scope(scopeName=“prototype”)设置多例模式,不加默认单例模式@Lazy@Component@Scope(scopeName="prototype")publicclassDrink{@Value("橙汁")privateStringname;@Value("半糖")privateStringsugar;@Value(&quo......