🍿*★,°*:.☆( ̄▽ ̄)/$:*.°★* 🍿 💥💥💥欢迎来到🤞汤姆🤞的csdn博文💥💥💥 💟💟喜欢的朋友可以关注一下,下次更新不迷路💟💟 😆😆😆私聊获取个人订阅号哦,欢迎订阅共同学习😆😆😆 💖💖💖💖可以加入大家庭群聊,一起学习天天有福利💖💖💖💖
🍬本文摘要
设计方法二十三式之装饰器模式
目录
- 🍬本文摘要
- 😉一、基础概念
- 🐱🐉二、装饰器模式实现
- 🎉三、模块之间的关系
- 🐱🚀四、注意事项
- 🎂五、使用场景
- 🍳参考文献
- 🧊文章总结
😉一、基础概念
装饰器模式是一种结构型设计模式,它通过动态的将责任附加到对象上来扩展对象的功能。换句话说,它提供了一种不通过子类化就能扩展对象功能的方式。装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。
在装饰器模式中,有一个基本的对象,称之为组件(component),它定义了一个共同的接口,可以被具体的组件或装饰器所实现。装饰器(decorator)会对组件进行包装,从而给组件增加新的功能。装饰器也实现了组件的接口,所以它们可以互相嵌套和组合,从而形成一个功能更加丰富的对象。
在代码实现上,装饰器模式使用一个装饰器类对组件进行包装,并将其传递给另一个装饰器,直到所有的装饰器都被执行完毕。这个过程中,每个装饰器都可以通过调用组件的方法来增加、修改或删除组件的行为。最终,得到的对象拥有了所有的装饰器所提供的功能。
所以,装饰器模式的优点在于:可以动态地给对象增加新的功能,而不需要修改原有的代码。缺点在于:装饰器的嵌套可能会导致复杂的代码结构,而且不正确地使用装饰器将使代码难以维护。
🐱🐉二、装饰器模式实现
首先,我们定义一个基础组件类Component和一个具体组件类ConcreteComponent:
class Component {
public:
virtual void operation() = 0;
};
class ConcreteComponent : public Component {
public:
virtual void operation() override {
std::cout << "ConcreteComponent operation.\n";
}
};
然后我们定义一个装饰器类Decorator,它继承自Component并持有一个指向Component对象的指针,以便在装饰过程中调用原对象的方法。Decorator还定义了一个名为addBehavior()的纯虚函数,用于在装饰过程中添加新功能。
class Decorator : public Component {
public:
Decorator(Component* component) : component_(component) {}
virtual void operation() override {
if (component_)
component_->operation();
}
virtual void addBehavior() = 0;
protected:
Component* component_;
};
接下来,我们定义两个具体装饰器类ConcreteDecoratorA和ConcreteDecoratorB,它们继承自Decorator并重写了operation()和addBehavior()方法,以实现自定义的装饰功能。
class ConcreteDecoratorA : public Decorator {
public:
ConcreteDecoratorA(Component* component) : Decorator(component) {}
virtual void operation() override {
Decorator::operation();
std::cout << "ConcreteDecoratorA operation.\n";
}
virtual void addBehavior() override {
std::cout << "ConcreteDecoratorA added behavior.\n";
}
};
class ConcreteDecoratorB : public Decorator {
public:
ConcreteDecoratorB(Component* component) : Decorator(component) {}
virtual void operation() override {
Decorator::operation();
std::cout << "ConcreteDecoratorB operation.\n";
}
virtual void addBehavior() override {
std::cout << "ConcreteDecoratorB added behavior.\n";
}
};
最后,我们可以在客户端代码中使用这些类来实现装饰器模式。我们首先创建一个具体组件对象ConcreteComponent,然后将其传递给ConcreteDecoratorA对象,并调用addBehavior()方法来添加新功能。随后,我们将ConcreteDecoratorA对象传递给ConcreteDecoratorB对象再次添加新功能,并调用operation()方法,输出所有添加的功能。
int main() {
Component* component = new ConcreteComponent();
ConcreteDecoratorA* decoratorA = new ConcreteDecoratorA(component);
decoratorA->addBehavior();
ConcreteDecoratorB* decoratorB = new ConcreteDecoratorB(decoratorA);
decoratorB->addBehavior();
decoratorB->operation();
delete decoratorB;
delete decoratorA;
delete component;
return 0;
}
输出结果如下:
ConcreteComponent operation.
ConcreteDecoratorA operation.
ConcreteDecoratorA added behavior.
ConcreteDecoratorB operation.
ConcreteDecoratorB added behavior.
🎉三、模块之间的关系
在装饰器模式中,有四个关键角色:抽象组件、具体组件、抽象装饰器和具体装饰器。
抽象组件是定义对象的接口,可以是抽象类或接口,具体组件是实现抽象组件的类,具体装饰器是实现抽象装饰器的类,抽象装饰器是定义装饰器的接口,可以是抽象类或接口。
这四个角色之间的关系是:抽象组件可以包含具体组件,抽象装饰器可以包含抽象组件,具体装饰器可以包含抽象装饰器,具体装饰器也可以包含具体组件,形成一个以抽象装饰器为根节点的装饰器链。通过这个链,每一个装饰器都可以动态地为组件添加新的功能。
当客户端想要使用某个具体组件时,可以使用抽象装饰器来对其进行装饰,不需要知道具体组件的实现细节,这样可以实现组件与装饰器的解耦。
🐱🚀四、注意事项
使用桥接模式时需要注意以下事项:
-
抽象部分与实现部分分离。在使用桥接模式时,需要将抽象部分与实现部分分离开来,确保它们可以独立进行变化。这有助于提高系统的灵活性和可扩展性。
-
接口细化。在设计抽象部分和实现部分的接口时,需要尽可能细化,以确保它们的功能可以清晰地描述。
-
优先使用对象组合。在实现桥接模式时,需要优先使用对象组合,而不是继承。如果使用继承,可能会引发类层次结构的剧增,导致系统难以维护。
-
不要滥用桥接模式。桥接模式并不是一种万能模式,使用时需要根据具体情况来决定是否使用。如果使用不当,可能会导致系统的复杂度增加,反而降低系统的可维护性和可扩展性。
-
安全性考虑。在使用桥接模式时,需要考虑安全性的问题。特别是在桥接的两端,需要确保数据的完整性和安全性。
🎂五、使用场景
桥接模式适用于以下场景:
1.抽象和实现部分具有平行的等级结构,需要在运行时动态组合它们。桥接模式能够使抽象和实现部分各自独立变化,且能够在运行时动态组合它们,因此能够很好地适应这种场景。
2.要求不同的抽象子类可以与不同的实现子类进行组合。桥接模式能够通过抽象角色和实现角色的分离,实现不同的抽象子类可以与不同的实现子类进行组合,从而可以灵活地处理不同的组合情况。
3.一个类存在多个独立变化的维度,需要支持动态组合。桥接模式能够将各个维度的变化分离,使得每个维度的变化可以独立地扩展,从而可以非常灵活地支持多维度的动态组合。
综上所述,桥接模式适用于具有多个独立变化维度的场景,能够很好地支持这种复杂度。但需要注意的是,若使用不当,桥接模式也可能带来额外的复杂度。因此,应在设计时慎重考虑是否真正需要使用桥接模式。
🍳参考文献
🧊文章总结
提示:这里对文章进行总结:
本文讲了关于桥接模式的知识。
更多好文推荐
🍸2021-4月Python 机器学习——中文新闻文本标题分类
🍹2021年4月-(计算机网络)小型校园网络模拟搭建,最全最准确版
🍺2022-10-31-基于用户的协同过滤推荐算法实现+MAE+RMSE
🍻2022-11-28-大数据可视化,特征维度大于50
🥂2023-3-9-一篇简短的文章把C++左右值关系讲的透透彻彻
上一篇 |
End
| 下一篇 |