设计模式:装饰器模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

上一篇《桥接模式》                                                               下一篇《迭代器模式》

简介:

装饰器模式,它是一种结构型模式,它通过将一个对象封装在一个装饰器对象中,使得你可以通过改变装饰器对象来改变原始对象的行为。
装饰器模式通常涉及到四种角色:
1、抽象构件角色,定义了一个接口,规范了准备接收附加责任的对象。
2、具体构件角色,实现了抽象构件角色,并通过装饰角色为其添加一些职责。
3、抽象装饰角色,继承了抽象构件角色,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
4、具体装饰角色,实现了抽象装饰的相关方法,并给具体构件对象添加附加的责任。

装饰器模式可以避免继承带来的类膨胀问题,因为你可以通过组合装饰器对象来扩展对象的行为,而不是通过继承来添加新的功能。此外,装饰器模式还提供了更好的灵活性,因为你可以在运行时动态地组合和替换装饰器对象,从而改变对象的行为。

但是,使用装饰器模式也需要注意一些问题。首先,使用装饰器模式会增加系统中类的数量,这可能会增加复杂度和理解难度。其次,如果使用不当,可能会导致过多嵌套或产生大量小粒度对象,这会使得代码变得难以维护。因此,在使用装饰器模式时需要谨慎考虑设计是否合适。

总之,装饰器模式是一种非常实用的设计模式,它可以在不修改原始对象结构的情况下,动态地给对象添加额外的职责,使得你可以更加灵活地扩展对象的行为。

装饰器模式的使用场景:
1、需要扩展一个类的功能或给一个类添加附加职责,且不能采用生成子类的方法进行扩充。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。
2、需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰器模式却很好实现。
3、对象的功能要求可以动态地添加,也可以再动态地撤销。

装饰器模式的创建步骤:
1、创建接口:首先定义一个接口,该接口规范了对象的基本行为。
2、创建实现接口的实体类:创建一个或多个实体类来实现接口,这些实体类将作为被装饰的对象。
3、创建实现Shape接口的抽象装饰类:创建一个抽象装饰类,该类继承了接口并提供了添加额外职责的方法。
4、创建具体装饰类:创建一个或多个具体装饰类,它们继承了抽象装饰类并实现了添加额外职责的方法。
5、使用装饰器模式:通过将对象封装在装饰器对象中,可以在运行时动态地给对象添加额外的职责。

装饰器模式的优点,主要包括:
1、灵活性:装饰器模式可以以动态的方式在运行时给对象增加额外的职责,而不需要在编译时决定添加哪些功能。通过使用装饰器模式,可以在不改变原始对象结构的情况下,根据需要灵活地扩展对象的行为。
2、可插拔:通过使用装饰器模式,可以将功能分解成一系列的装饰器类,使得代码更加模块化和易于维护。可以在运行时动态地组合和替换装饰器对象,从而改变对象的行为。
3、可扩展性:装饰器模式可以避免继承带来的类膨胀问题,因为你可以通过组合装饰器对象来扩展对象的行为,而不是通过继承来添加新的功能。
4、符合开闭原则:装饰器模式完全遵守开闭原则,即对扩展开放,对修改封闭。通过使用装饰器模式,可以方便地添加新的装饰器类来扩展对象的行为,而不需要修改原始对象的代码。

装饰器模式的缺点,主要包括:
1、代码量增加:装饰器模式需要创建很多小类,即使只添加一个功能,也要额外创建一个类,这会使得程序更复杂。
2、增加代码复杂度:使用装饰器模式不但需要实例化组件,还要把组件包装到装饰者中,这会增加代码的复杂度。
3、设计难度高:装饰器模式需要对系统进行全面理解,设计出结构良好的装饰器类和被装饰类,才能够达到预期的效果。
4、性能问题:由于装饰器模式需要在运行时动态地创建对象和调用方法,这可能会导致性能上的问题。

注意:过度使用装饰器模式可能会导致程序变得复杂,增加系统中类的数量,并可能产生大量小粒度对象,使得代码变得难以维护。因此,在使用装饰器模式时需要谨慎考虑设计是否合适。

示例:

一、C#装饰器模式

以下是一个示例,展示了如何在C#中实现装饰器模式:

//定义一个接口
public interface IMyService  
{  
    void DoSomething();  
}
//创建一个实现该接口的具体类
public class MyService : IMyService  
{  
    public void DoSomething()  
    {  
        Console.WriteLine("Doing something in MyService.");  
    }  
}
//创建一个实现IMyService接口的抽象装饰类
public abstract class MyServiceDecorator : IMyService  
{  
    protected IMyService decoratedMyService;  
  
    public MyServiceDecorator(IMyService myService)  
    {  
        decoratedMyService = myService;  
    }  
  
    public virtual void DoSomething()  
    {  
        decoratedMyService.DoSomething();  
    }  
}
//创建具体装饰类,它们继承自抽象装饰类并实现了添加额外职责的方法
public class MyServiceDecoratorA : MyServiceDecorator  
{  
    public MyServiceDecoratorA(IMyService myService) : base(myService) { }  
  
    public override void DoSomething()  
    {  
        base.DoSomething(); // 调用原始方法。  
        Console.WriteLine("Doing something extra in MyServiceDecoratorA."); // 添加新的功能。  
    }  
}
//实例应用
class Program  
{  
    static void Main(string[] args)  
    {
        IMyService myService = new MyService(); // 创建具体对象。  
        IMyService decoratorA = new MyServiceDecoratorA(myService); // 创建具体装饰类对象并将具体对象作为被装饰对象传入构造函数。  
        decoratorA.DoSomething(); // 调用具体装饰类中的方法,扩展具体对象的行为。
    }
}

二、java装饰器模式

装饰器模式通常通过以下方式实现:

//定义一个接口
public interface Component {  
    void operation();  
}
//创建一个实现该接口的具体类
public class ConcreteComponent implements Component {  
    public void operation() {  
        System.out.println("具体对象操作");  
    }  
}
//创建一个实现IMyService接口的抽象装饰类
public abstract class Decorator implements Component {  
    protected Component component;  
  
    public Decorator(Component component) {  
        this.component = component;  
    }  
  
    public void operation() {  
        component.operation(); // 先调用原始对象的方法。  
        decorate(); // 再添加新的功能。  
    }  
  
    public abstract void decorate(); // 抽象方法,用于添加新的功能。  
}
//创建具体装饰类,它们继承自抽象装饰类并实现了添加额外职责的方法
public class ConcreteDecorator extends Decorator {  
    public ConcreteDecorator(Component component) : super(component) { }  
  
    public void decorate() {  
        System.out.println("具体装饰器添加的功能"); // 添加新的功能。  
    }  
}
//实例应用
public class Main {  
    public static void main(String[] args) {  
        Component c = new ConcreteComponent(); // 创建具体对象。  
        Decorator decorator = new ConcreteDecorator(c); // 创建具体装饰类对象并将具体对象作为被装饰对象传入构造函数。  
        decorator.operation(); // 调用具体装饰类中的方法,扩展具体对象的行为。输出:具体对象操作 具体装饰器添加的功能。
    }
}

三、javascript装饰器模式

在JavaScript中,装饰器实现方式如下:

//定义一个接口
const Component = {  
  methods: {  
    operation() {  
      console.log('Component operation');  
    }  
  }  
};
//创建一个实现了该接口的具体类
const ConcreteComponent = {  
  ...Component,  
  constructor() {  
    this.operation();  
  }  
};
//创建一个实现了该接口的抽象装饰器类
const Decorator = {  
  methods: {  
    operation() {  
      this.component.operation();  
      this.decorate();  
    },  
    decorate() {  
      console.log('Decorator decorate');  
    }  
  }  
};
//创建具体装饰类,它们继承自抽象装饰器类并实现了添加额外职责的方法
const ConcreteDecoratorA = {  
  ...Decorator,  
  constructor(component) {  
    this.component = component;  
  },  
  decorate() {  
    console.log('ConcreteDecoratorA decorate');  
  }  
};

在这个示例中,我们创建了一个具体装饰器类ConcreteDecoratorA,它继承自抽象装饰器类并添加了一个新的方法decorate,这个方法会在调用被装饰组件的operation方法后被调用,从而添加新的功能。

四、C++装饰器模式

以下是在C++中实现装饰器模式:

//首先,定义一个接口类:
class IComponent {  
public:  
  virtual void operation() = 0;  
};
//接着,创建一个实现了该接口的具体类:
class ConcreteComponent : public IComponent {  
public:  
  void operation() override {  
    cout << "ConcreteComponent operation" << endl;  
  }  
};
//然后,创建一个实现了该接口的抽象装饰器类:
class IDecorator : public IComponent {  
protected:  
  IComponent* component;  
public:  
  IDeveloper(IComponent* component) : component(component) {}  
  virtual void operation() override {  
    component->operation();  
    decorate();  
  }  
  virtual void decorate() = 0;  
};
//最后,创建具体装饰类,它们继承自抽象装饰器类并实现了添加额外职责的方法:
class ConcreteDecoratorA : public IDecorator {  
public:  
  ConcreteDecoratorA(IComponent* component) : IDecorator(component) {}  
  void decorate() override {  
    cout << "ConcreteDecoratorA decorate" << endl;  
  }  
};

五、python装饰器模式

在Python中,装饰器模式是通过装饰器函数实现的。装饰器函数是一个接受函数作为参数的可调用对象,并返回一个包装后的函数。
下面是一个简单的Python装饰器模式的示例代码:

def my_decorator(func):  
    def wrapper():  
        print("Before the function is called.")  
        func()  
        print("After the function is called.")  
    return wrapper  
  
@my_decorator  
def say_hello():  
    print("Hello!")  
  
say_hello()

六、go装饰器模式

以下是一个示例,展示了如何在go中实现装饰器模式:

package main  
  
import "fmt"  
  
// 原始函数  
func sayHello() {  
    fmt.Println("Hello!")  
}  
  
// 装饰器函数  
func myDecorator(f func()) {  
    fmt.Println("Before the function is called.")  
    f()  
    fmt.Println("After the function is called.")  
}  
  
func main() {  
    // 使用装饰器函数包装原始函数  
    myDecorator(sayHello)  
}

七、PHP装饰器模式

在PHP装饰器模式中,我们创建一个装饰器类,它实现与目标类相同的接口,并在内部维护一个对目标对象的引用。装饰器类可以添加新的方法或覆盖目标类的方法,以实现动态地扩展目标对象的功能。

下面是一个简单的PHP装饰器模式的示例代码:

<?php  
  
// 目标类  
class Target {  
    public function operation() {  
        echo "Target operation";  
    }  
}  
  
// 装饰器类  
class Decorator extends Target {  
    private $target;  
  
    public function __construct(Target $target) {  
        $this->target = $target;  
    }  
  
    public function operation() {  
        echo "Decorator operation before";  
        $this->target->operation();  
        echo "Decorator operation after";  
    }  
}  
  
// 使用装饰器模式  
$target = new Target();  
$decorator = new Decorator($target);  
$decorator->operation();


《完结》

上一篇《桥接模式》                                                                     下一篇《迭代器模式》​​​​​​​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值