观察者模式(大话设计模式)C/C++版本

观察者模式

在这里插入图片描述

扩展:观察者模式——委托

C++

参考:https://www.cnblogs.com/Galesaur-wcy/p/15905936.html

#include <iostream>
#include <list>
#include <memory>
#include <string>
using namespace std;

// Observer类 抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口要做更新接口。
// 观察者一般用一个抽象类或者接口实现,更新接口通常包含一个Update()方法 这个方法叫做更新方法。
class Observer
{
public:
    virtual void Update(int) = 0;
    virtual ~Observer() = default;
    virtual void SetName(const string &observerName) final
    {
        m_observerName = observerName;
    }
    virtual string GetName() const final
    {
        return m_observerName;
    }

protected:
    string m_observerName;
};

// Subject类 可翻译为主题或抽象通知者 一般用一个抽象类或者一个接口实现。他把所有对观察者对象的引用保存
// 在一个聚集里,每个主题都可以又任何数量的观察者。抽象主题提供一个接口,可增加或者删除观察者对象
class Subject
{
public:
    virtual void Attach(shared_ptr<Observer>) = 0;
    virtual void Detach(shared_ptr<Observer>) = 0;
    virtual void Notify() = 0;
};

// ConcreteObserver 具体观察者 实现抽象观察角色所要求的更新接口,以便使本身的状态与主题的状态相协调.
// 具体观察者角色可以保存一个指向具体主题对象的引用.具体观察者校色通常用一个具体子类实现
class ConcreteObserver : public Observer
{
public:
    ConcreteObserver(shared_ptr<Subject> pSubject, const string &observerName)
        : m_pSubject(pSubject)
    {
        m_observerName = observerName;
    }
    void Update(int value) override
    {
        cout << "   ConcreteObserver " << m_observerName << " gets the update. New State: " << value << endl;
    }

private:
    shared_ptr<Subject> m_pSubject;
};

class ConcreteObserver2 : public Observer
{
public:
    ConcreteObserver2(shared_ptr<Subject> pSubject, const string &observerName)
        : m_pSubject(pSubject)
    {
        m_observerName = observerName;
    }
    void Update(int value) override
    {
        cout << "   ConcreteObserver2 " << m_observerName << " gets the update. New State: " << value << endl;
    }

private:
    shared_ptr<Subject> m_pSubject;
};

// ConcreteSubject类,叫做具体主题或者具体通知者..将有关状态存入具体观察者对象;在具体主题内部状态改变时...给所有登记过的观察者发出通知.
// 具体主题对象通常用一个具体子类实现.
class ConcreteSubject : public Subject
{
public:
    void Attach(shared_ptr<Observer> pObserver)
    {
        m_ObserverList.push_back(pObserver);
    }
    void Detach(shared_ptr<Observer> pObserver)
    {
        m_ObserverList.remove_if([=](const shared_ptr<Observer> &observer)
                                 { return observer == pObserver; });
    }
    void Notify()
    {
        for (const auto &observer : m_ObserverList)
        {
            cout << "   Notifying -> " << observer->GetName() << endl;
            observer->Update(m_iState);
        }
    }

    void SetState(int state)
    {
        cout << "State changed to " << state << endl;
        m_iState = state;
    }

private:
    list<shared_ptr<Observer>> m_ObserverList;
    int m_iState;
};

int main()
{
    auto pSubject = make_shared<ConcreteSubject>();

    auto pObserver = make_shared<ConcreteObserver>(pSubject, "observer1");
    auto pObserver2 = make_shared<ConcreteObserver2>(pSubject, "observer2");

    pSubject->Attach(pObserver);
    pSubject->Attach(pObserver2);

    pSubject->SetState(2);
    pSubject->Notify();
    cout << endl;

    pSubject->Detach(pObserver);

    pSubject->SetState(3);
    pSubject->Notify();
    cout << endl;

    return 0;
}

C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

typedef struct Subject Subject;
typedef struct Observer
{
    char *name;
    void (*update)(struct Subject *, int, void *);
} Observer;

typedef struct Subject
{
    struct Observer **observers;
    size_t observer_count;
    int state;
} Subject;

void ConcreteObserverUpdate(struct Subject *subject, int value, void *data)
{
    printf("   ConcreteObserver get the update. New State: %d\n", value);
}

void ConcreteObserver2Update(struct Subject *subject, int value, void *data)
{
    printf("   ConcreteObserver2 get the update. New State: %d\n", value);
}

void attach(struct Subject *subject, Observer *observer)
{
    Observer **newObservers = realloc(subject->observers, sizeof(Observer *) * (subject->observer_count + 1));
    if (newObservers == NULL)
    {
        fprintf(stderr, "Memory allocation failed.\n");
        exit(EXIT_FAILURE);
    }
    newObservers[subject->observer_count++] = observer;
    subject->observers = newObservers;
}

void detach(struct Subject *subject, Observer *observer)
{
    bool removed = false;
    int i;
    for (i = 0; i < subject->observer_count; ++i)
    {
        if (subject->observers[i] == observer)
        {
            subject->observer_count--;
            removed = true;
            int j;
            for (j = i; j < subject->observer_count; ++j)
            {
                subject->observers[j] = subject->observers[j + 1];
            }
            break;
        }
    }
    if (!removed)
    {
        fprintf(stderr, "Observer not found.\n");
    }
}

void notify(struct Subject *subject)
{
    int i;
    for (i = 0; i < subject->observer_count; ++i)
    {
        printf("   Notifying -> %s\n", subject->observers[i]->name);
        subject->observers[i]->update(subject, subject->state, subject->observers[i]);
    }
}

void setState(struct Subject *subject, int state)
{
    printf("state changed......\n");
    subject->state = state;
}

void safe_free(void *ptr)
{
    if (ptr)
        free(ptr);
}

int main()
{
    Subject *pSubject = (Subject *)malloc(sizeof(Subject));
    pSubject->observers = NULL;
    pSubject->observer_count = 0;
    pSubject->state = 0;

    Observer observer1 = {
        .name = strdup("observer1"),
        observer1.update = ConcreteObserverUpdate,
    };

    Observer observer2 = {
        .name = strdup("observer2"),
        .update = ConcreteObserver2Update,
    };

    attach(pSubject, &observer1);
    attach(pSubject, &observer2);

    setState(pSubject, 2);
    notify(pSubject);
    printf("\n");

    detach(pSubject, &observer1);

    setState(pSubject, 3);
    notify(pSubject);
    printf("\n");

    safe_free(observer1.name);
    safe_free(observer2.name);
    safe_free(pSubject->observers);
    safe_free(pSubject);

    return 0;
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值