您现在的位置是:首页 >其他 >常用的设计模式之二(行为型模式)网站首页其他

常用的设计模式之二(行为型模式)

ZHAOCHENHAO- 2023-07-13 04:00:02
简介常用的设计模式之二(行为型模式)

观察者模式

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有观察者都会收到通知并进行相应的处理。

观察者模式包含以下几个角色:

  • 抽象主题(Subject):定义了被观察的对象接口,它可以增加和删除观察者对象,以及通知观察者对象。
  • 具体主题(ConcreteSubject):实现了抽象主题接口,它具有添加、删除观察者对象的功能。通常是被观察的对象。
  • 抽象观察者(Observer):定义了观察者接口,它具有更新数据的方法,当接收到主题通知时被调用。
  • 具体观察者(ConcreteObserver):实现了观察者接口,它保存一个指向具体主题对象的引用,实现了更新数据的方法,以便自身状态与主题状态协调。

观察者模式的核心思想是:当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。这种模式的优点是将观察者和被观察者解耦,使得程序的扩展性和复用性更加容易,可以动态地添加和删除观察者,从而避免了代码的臃肿和复杂性。

观察者模式在实际应用中非常常见,例如在图形界面开发中,窗口、按钮等组件就可以作为被观察者,而事件监听器就可以作为观察者。此外,观察者模式还可以用于日志记录、消息队列等领域。

下面是一个C++实现的简单观察者模式案例:

#include <iostream>
#include <vector>

using namespace std;

// 抽象主题类
class Subject {
public:
    virtual void attach(class Observer* observer) = 0;
    virtual void detach(class Observer* observer) = 0;
    virtual void notify() = 0;
};

// 具体主题类
class ConcreteSubject : public Subject {
public:
    void attach(Observer* observer) override {
        observers.push_back(observer);
    }

    void detach(Observer* observer) override {
        for (auto it = observers.begin(); it != observers.end(); ++it) {
            if (*it == observer) {
                observers.erase(it);
                break;
            }
        }
    }

    void notify() override {
        for (auto observer : observers) {
            observer->update();
        }
    }

    void setState(int state) {
        this->state = state;
        notify();
    }

    int getState() const {
        return state;
    }

private:
    vector<Observer*> observers;
    int state;
};

// 抽象观察者类
class Observer {
public:
    virtual void update() = 0;
};

// 具体观察者类
class ConcreteObserver : public Observer {
public:
    ConcreteObserver(ConcreteSubject* subject) : subject(subject) {
        subject->attach(this);
    }

    ~ConcreteObserver() override {
        subject->detach(this);
    }

    void update() override {
        cout << "Observer received notification: " << subject->getState() << endl;
    }

private:
    ConcreteSubject* subject;
};

int main() {
    ConcreteSubject subject;

    // 添加两个观察者
    ConcreteObserver observer1(&subject);
    ConcreteObserver observer2(&subject);

    // 改变主题状态,触发通知
    subject.setState(1);

    // 移除一个观察者
    subject.detach(&observer2);

    // 再次改变主题状态,触发通知
    subject.setState(2);

    return 0;
}

这个示例中,Subject 定义了主题类的接口,包括添加、删除观察者和通知观察者的方法, ConcreteSubject 继承了 Subject,并实现了具体的主题类,其中 setState 方法改变主题的状态,并调用 notify 方法通知所有观察者;Observer 定义了观察者类的接口,包括更新数据的方法; ConcreteObserver 继承了 Observer,并实现了具体的观察者类,它保存了一个指ConcreteSubject 的引用,当 ConcreteSubject 的状态发生改变时,会自动更新。

在 main 函数中,我们创建了一个 ConcreteSubject 对象,并添加了两个观察者,然后改变主题状态,触发通知。接着,我们移除了一个观察者,并再次改变主题状态,验证只有一个观察者收到了通知。

模板模式

模板模式(Template Pattern)是一种行为设计模式,它定义了一个算法的骨架,而将某些步骤延迟到子类中实现。模板模式使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

模板模式的核心思想是定义一个抽象基类,其中包含了一些算法的共性,以及一些抽象方法,这些抽象方法会在具体子类中实现。然后定义一个模板方法,其中包含了一个算法的骨架,它通过调用基类中的方法来实现算法的各个步骤。具体子类可以通过重写基类中的抽象方法来实现算法的个性化定制。

以下是一个简单的 C++ 实现示例:

#include <iostream>

using namespace std;

// 抽象类
class AbstractClass {
public:
    virtual void primitiveOperation1() = 0;
    virtual void primitiveOperation2() = 0;

    void templateMethod() {
        primitiveOperation1();
        primitiveOperation2();
    }
};

// 具体类A
class ConcreteClassA : public AbstractClass {
public:
    void primitiveOperation1() override {
        cout << "ConcreteClassA::primitiveOperation1()" << endl;
    }

    void primitiveOperation2() override {
        cout << "ConcreteClassA::primitiveOperation2()" << endl;
    }
};

// 具体类B
class ConcreteClassB : public AbstractClass {
public:
    void primitiveOperation1() override {
        cout << "ConcreteClassB::primitiveOperation1()" << endl;
    }

    void primitiveOperation2() override {
        cout << "ConcreteClassB::primitiveOperation2()" << endl;
    }
};

int main() {
    AbstractClass* a = new ConcreteClassA;
    a->templateMethod();

    AbstractClass* b = new ConcreteClassB;
    b->templateMethod();

    return 0;
}

在这个示例中,AbstractClass 是抽象基类,其中包含了一个模板方法 templateMethod,它通过调用两个抽象方法 primitiveOperation1 和 primitiveOperation2 实现算法的骨架。ConcreteClassA 和 ConcreteClassB 继承自 AbstractClass,并分别实现了自己的具体算法,即实现 primitiveOperation1 和 primitiveOperation2。

在 main 函数中,我们先创建了一个 ConcreteClassA 对象,并调用了其 templateMethod 方法,它的具体算法是先执行 primitiveOperation1,然后执行 primitiveOperation2。接着,我们创建了一个 ConcreteClassB 对象,同样调用了其 templateMethod 方法,其具体算法和 ConcreteClassA 有所不同。

模板模式的优点在于它使得算法的框架和具体实现分离,降低了实现算法的难度和维护成本,并且可以在不改变算法结构的情况下,方便地扩展和修改算法的具体实现。模板模式还可以提高代码的复用性,避免了代码重复。

模板模式的缺点在于它需要定义抽象类和具体类,这样就增加了代码的复杂度和阅读难度。此外,模板模式还可能导致类的层次结构变得更加复杂,需要进行仔细的设计。

总的来说,模板模式适用于需要实现一些具体算法,但是算法中的某些步骤可能存在差异,需要在子类中进行定制的情况。它可以让代码更加简洁,易于维护,同时提高代码的复用性和扩展性。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。