设计模式---装饰模式

设计模式---装饰模式,第1张

装饰模式 — Decorator 1.模式定义:

装饰模式:动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类(继承)实现更灵活。


符合组合优于继承的设计原则。

这个模式是便于后期维护,前期开发和通过继承生成子类的代码量差不多。


装饰器模式的本质就是动态组合。

动态是手段,组合才是目的。

总之,装饰模式是通过把复杂的功能简单化,分散化,
然后在运行期间,根据需要来动态组合的一个模式。

2.模式结构
  • component: 抽象构建接口
  • concretecomponentA, concretecomponentB: 具体构建类
  • decorator: 装饰模式类
  • concretedecoratorA, concretedecoratorB: 具体装饰模式类
3.C++代码实现: 3.1 main.cpp
#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.模式对比:

这里对比主要是继承和关联之间的对比:

  • 与继承关系相比,关联关系的主要优势在于不会破坏类的封装性,而且继承是一种耦合度较大的静态关系,无法在程序运行时动态扩展。

    在软件开发阶段,关联关系虽然不会比继承关系减少编码量,但是到了软件维护阶段,由于关联关系使系统具有较好的松耦合性,因此使得系统更加容易维护。

    当然,关联关系的缺点是比继承关系要创建更多的对象。

  • 使用装饰模式来实现扩展比继承更加灵活,它以对客户透明的方式动态地给一个对象附加更多的责任。

    装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。

5.具体实例:变形金刚

车变机器人,增加说话技能;车变飞机,增加飞行技能。

5.1 结构图

5.2 go代码实现: 5.2.1 main.go
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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/662376.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-18
下一篇 2022-04-18

发表评论

登录后才能评论

评论列表(0条)

保存