前端设计模式应用--装饰器模式

43 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天

介绍

  • 装饰器模式(Decorator Pattern) 也称为包装模式(Wrapper Pattern) 是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。装饰器模式的核心是功能扩展,使用装饰器模式可以透明且动态地扩展类的功能。
  • 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

使用场景

  • 扩展一个类的功能。为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

  • 动态增加功能,动态撤销。装饰器模式就是使用在对已有的目标功能存在不足,需要增强时,前提是目标存在抽象接口。

应用实践

职责明确

  • 抽象组件(Component): 可以是一个接口或者抽象类,其充当被装饰类的原始对象,规定了被装饰对象的行为;

  • 具体组件(ConcreteComponent): 实现/继承Component的一个具体对象,也即被装饰对象;

  • 抽象装饰器(Decorator): 通用的装饰ConcreteComponent的装饰器,其内部必然有一个属性指向Component抽象组件;其实现一般是一个抽象类,主要是为了让其子类按照其构造形式传入一个Component抽象组件;

  • 具体装饰器(ConcreteDecorator): Decorator的具体实现类,理论上,每个ConcreteDecorator都扩展了Component对象的一种功能;

实现

//抽象组件
abstract class Component {
    public abstract void execute();
}

//实体组件继承抽象组件(需要被装饰的组件)
class ConcreteComponent extends Component {
    constructor(name) {
        this.name = name;
    }

    execute() {
        console.log('我是一个纯纯的组件', this.name)
    }
}

//抽象装饰器
abstract class Decorator {
    private componentInstance
    constructor(component) {
        this.componentInstance = component;
    }
    execute() {
        this.componentInstance.execute()
    }

}

// 创建装饰器
class ConcreteDecorator extends Decorator {
    constructor(component) {
        super()
        this.componentInstance = component;
    }

    beforeMount() {
        console.log('组件执行前操作')
    }

    mount(
        console.log('组件执行完成')
    )

    execute() {
        beforeMount()
        this.componentInstance.execute()
        mount()

    }
}

//使用

const component = new ConcreteComponent()

const decoratorInstance = new ConcreteDecorator(component)

//执行调用
decoratorInstance.execute()

汇总

装饰器(修饰)模式,是面向对象程式领域中,一种动态地往一个类别中添加新的行为的设计模式。就功能而言,修饰模式相比生成子类别更为灵活,这样可以给某个对象而不是整个类别添加一些功能。

优点特性

  • 装饰器模式与继承关系的目的都是要扩展对象的功能,但是装饰器模式可以提供比继承更多的灵活性。当需要扩展多个功能时,装饰器模式只需要增加新的具体装饰类即可,而继承关系则需要继承原有类,再进行扩展,如果需要在不改变原有类的基础上继续扩展,则需要再次继承,这样代码耦合性比较高。

  • 可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的装饰器,从而实现不同的行为。

  • 通过使用不同的具体装饰器类以及这些装饰器类的排列组合,可以创建出很多不同的组合。可以使用多个具体装饰类来装饰同一个对象。

  • 具体构建类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰器类,在使用时再对其进行组合额,原有代码无线改变,符合“开闭原则”。

缺点弊端

  • 装饰器模式会增加许多子类,过度使用会增加程序得复杂性。装饰方式可能比较复杂,如果嵌套太多,容易造成代码可读性变差和出错。