装饰模式:动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类(继承)实现更灵活。
符合组合优于继承的设计原则。
这个模式是便于后期维护,前期开发和通过继承生成子类的代码量差不多。
装饰器模式的本质就是动态组合。
动态是手段,组合才是目的。
总之,装饰模式是通过把复杂的功能简单化,分散化,
然后在运行期间,根据需要来动态组合的一个模式。
- component: 抽象构建接口
- concretecomponentA, concretecomponentB: 具体构建类
- decorator: 装饰模式类
- concretedecoratorA, concretedecoratorB: 具体装饰模式类
#include
#include"component.hpp"
#include"decorator.hpp"
using namespace std;
void test(component* crt_comp) {
cout << "===============================" << endl;
concretedecoratorA* crt_dct_a = new concretedecoratorA(crt_comp);
crt_dct_a->operation();
cout << "===============================" << endl;
concretedecoratorB* crt_dct_b = new concretedecoratorB(crt_comp);
crt_dct_b->operation();
cout << "===============================" << endl;
delete crt_dct_a;
delete crt_dct_b;
}
int main() {
concretecomponentA* crt_comp_a = new concretecomponentA();
test(crt_comp_a);
delete crt_comp_a;
concretecomponentB* crt_comp_b = new concretecomponentB();
test(crt_comp_b);
delete crt_comp_b;
return 0;
}
3.2 构建: component.hpp
#ifndef COMPONENT_HPP
#define COMPONENT_HPP
#include
using namespace std;
// 抽象构建接口
class component
{
public:
virtual ~component(){};
virtual void operation(){};
};
// 具体构建A
class concretecomponentA: public component {
public:
void operation(){
cout << "concretecomponentA::operation" << endl;
}
};
// 具体构建B
class concretecomponentB: public component {
public:
void operation(){
cout << "concretecomponentB::operation" << endl;
}
};
#endif /* COMPONENT_HPP */
3.3 装饰: decorator.hpp
#ifndef DECORATOR_HPP
# define DECORATOR_HPP
#include
#include"component.hpp"
using namespace std;
// 装饰模式类
class decorator: public component
{
private:
component* m_component;
public:
decorator(component* component): m_component(component) {};
~decorator(){
// 析构函数中不能再对m_component进行delete,若此处delete就造成了double free
// 因为在释放具体构建类时,已经对m_component进行了析构,这里就不能对其析构了
// delete m_component;
};
void operation() {
if (!m_component) {
return;
}
m_component->operation();
}
};
// 具体装饰模式类A
class concretedecoratorA: public decorator{
public:
concretedecoratorA(component* component): decorator(component){};
void operation(){
add_behavior();
decorator::operation();
};
void add_behavior() {
cout << "concretedecoratorA::add_behavior" << endl;
}
};
// 具体装饰模式类B
class concretedecoratorB: public decorator{
public:
concretedecoratorB(component* component): decorator(component){};
void operation(){
add_behavior();
decorator::operation();
};
void add_behavior() {
cout << "concretedecoratorB::add_behavior" << endl;
}
};
#endif
3.4 执行结果:
===============================
concretedecoratorA::add_behavior
concretecomponentA::operation
===============================
concretedecoratorB::add_behavior
concretecomponentA::operation
===============================
===============================
concretedecoratorA::add_behavior
concretecomponentB::operation
===============================
concretedecoratorB::add_behavior
concretecomponentB::operation
===============================
4.模式对比:
这里对比主要是继承和关联之间的对比:
- 与继承关系相比,关联关系的主要优势在于不会破坏类的封装性,而且继承是一种耦合度较大的静态关系,无法在程序运行时动态扩展。
在软件开发阶段,关联关系虽然不会比继承关系减少编码量,但是到了软件维护阶段,由于关联关系使系统具有较好的松耦合性,因此使得系统更加容易维护。
当然,关联关系的缺点是比继承关系要创建更多的对象。
- 使用装饰模式来实现扩展比继承更加灵活,它以对客户透明的方式动态地给一个对象附加更多的责任。
装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。
车变机器人,增加说话技能;车变飞机,增加飞行技能。
func test_decorator() {
car := decorator.NewCar()
robot := decorator.NewRobot(car)
robot.Move()
airplane := decorator.NewAirplane(car)
airplane.Move()
}
5.2.2 构建接口+具体构建: transform.go
package decorator
import "fmt"
//====================================================
// 变形接口(抽象构建接口)
type ITransform interface{
Move()
}
//====================================================
// 具体构建类--车
type Car struct {}
func NewCar() *Car {
return &Car{}
}
func (c *Car) Move() {
fmt.Println("Car::Move")
}
//====================================================
5.2.3 装饰类+具体装饰 decorator.go
package decorator
import "fmt"
//====================================================
// 变形类(装饰类)
type Changer struct {
transform ITransform
}
func NewChanger(trans ITransform) Changer {
return Changer{
transform: trans,
}
}
func (ch *Changer) Move() {
ch.transform.Move()
}
//====================================================
// 飞机类--具体的装饰类增加飞行技能
type Airplane struct {
Ch Changer // go不支持继承,就用组合来代替
}
func NewAirplane(trans ITransform) *Airplane {
return &Airplane{
Ch: NewChanger(trans),
}
}
func (a *Airplane) Fly() {
fmt.Println("Airplane::fly")
}
func (a *Airplane) Move() {
a.Fly()
a.Ch.Move()
}
//====================================================
// 机器人类--具体的装饰类增加说话技能
type Robot struct {
Ch Changer // go不支持继承,就用组合来代替
}
func NewRobot(trans ITransform) *Robot {
return &Robot{
Ch: NewChanger(trans),
}
}
func (r *Robot) Say() {
fmt.Println("Robot::Say")
}
func (r *Robot) Move() {
r.Say()
r.Ch.Move()
}
//====================================================
5.2.4 执行结果
Robot::Say
Car::Move
Airplane::fly
Car::Move
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)