实习技能记录【4】-----消息分发中的观察者模型

观察者

观察者模式(Observer Pattern)是一种行为型设计模式 ,主要用于定义对象之间的一对多依赖关系 ,让多个观察者对象能够同时监听某个主题对象的状态变化,并在主题对象状态改变时自动通知所有观察者对象。

参考b站博主代码:

cpp 复制代码
#include <list>
#include <iostream> 

struct Stock;


struct Observer {
  Stock* stock;
  Observer(Stock* stock);       //定义Observer的构造函数
  virtual ~Observer();          //虚析构函数
  virtual void update(int) = 0; //虚函数
};

//Monitor继承自Observer
struct Monitor : Observer {
    
  explicit Monitor(Stock* stock) : Observer(stock) {} //避免隐式转换,用传入monitor的stock初始化父类
  void print(int v) {
    std::cout << "Monitor: " << v;
  }
  void update(int v) override { //monitor子类覆写的update函数
    print(v);
  }
};

struct Billboard : Observer {
  explicit Billboard(Stock* stock) : Observer(stock) {}
  void display(int v) {
    std::cout << "Billboard: " << v;
  }
  void update(int v) override {
    display(v);
  }
};

struct Stock {
  int price = 0;
  std::list<Observer*> observerList;//创建一个observer类指针类型的指针列表
  void attach(Observer* o) {
    observerList.push_back(o);
  }
  void detach(Observer* o) { 
    observerList.remove(o); 
  }
  void notify(int v) {
    for (auto observer : observerList) {
      observer->update(v);
    }
  }
  void setPrice(int v) { 
    price = v;
    notify(v);
  }
};

Observer::Observer(Stock* stk) : stock(stk) {
  stock->attach(this);
}

Observer::~Observer() {
  stock->detach(this);
}

int main() {
  Stock stock;
  Monitor monitor { &stock };
  Billboard board { &stock };
  stock.setPrice(10);
}

ai修改的c语言版本

c 复制代码
typedef struct Stock Stock;
typedef struct Observer Observer;

// 定义Observer(相当于父类)
struct Observer {
    Stock* stock;
    void (*update)(Observer* self, int v); // 函数指针模拟虚函数
    Observer* next; // 简单链表
};

// 定义Stock
struct Stock {
    int price;
    Observer* observerList; // 单链表头
};

// 注册observer
void attach(Stock* stock, Observer* observer) {
    observer->next = stock->observerList;
    stock->observerList = observer;
}

// 注销observer
void detach(Stock* stock, Observer* observer) {
    Observer** current = &stock->observerList;
    while (*current) {
        if (*current == observer) {
            *current = observer->next;
            break;
        }
        current = &((*current)->next);
    }
}

// 通知所有观察者
void notify(Stock* stock, int v) {
    Observer* current = stock->observerList;
    while (current) {
        current->update(current, v);
        current = current->next;
    }
}

// 设置价格并通知
void setPrice(Stock* stock, int v) {
    stock->price = v;
    notify(stock, v);
}

// Monitor对象(子类)
typedef struct {
    Observer base; // 继承Observer
} Monitor;

// Monitor的update实现
void Monitor_update(Observer* self, int v) {
    printf("Monitor: %d\n", v);
}

// 创建Monitor
Monitor* Monitor_create(Stock* stock) {
    Monitor* monitor = (Monitor*)malloc(sizeof(Monitor));
    monitor->base.stock = stock;
    monitor->base.update = Monitor_update;
    monitor->base.next = NULL;
    attach(stock, (Observer*)monitor);
    return monitor;
}

// 销毁Monitor
void Monitor_destroy(Monitor* monitor) {
    detach(monitor->base.stock, (Observer*)monitor);
    free(monitor);
}

// Billboard对象(子类)
typedef struct {
    Observer base;
} Billboard;

// Billboard的update实现
void Billboard_update(Observer* self, int v) {
    printf("Billboard: %d\n", v);
}

// 创建Billboard
Billboard* Billboard_create(Stock* stock) {
    Billboard* board = (Billboard*)malloc(sizeof(Billboard));
    board->base.stock = stock;
    board->base.update = Billboard_update;
    board->base.next = NULL;
    attach(stock, (Observer*)board);
    return board;
}

// 销毁Billboard
void Billboard_destroy(Billboard* board) {
    detach(board->base.stock, (Observer*)board);
    free(board);
}

// 测试
int main() {
    Stock stock = { 0, NULL };

    Monitor* monitor = Monitor_create(&stock);
    Billboard* billboard = Billboard_create(&stock);

    setPrice(&stock, 10);

    // 销毁
    Monitor_destroy(monitor);
    Billboard_destroy(billboard);

    return 0;
}
相关推荐
LuckyRich13 分钟前
【cpp-httplib】 安装与使用
c++·http
中微子7 分钟前
从C++看JavaScript闭包:执行上下文与作用域的跨语言对比
前端·c++
希望_睿智20 分钟前
实战设计模式之建造者模式
c++·设计模式·架构
@曲终1 小时前
C++:栈帧、命名空间、引用
java·开发语言·c++·经验分享·笔记
強云1 小时前
原子操作(C++)
c++
敲代码的瓦龙2 小时前
C++?多态!!!
c语言·开发语言·c++·windows·后端
我不是程序猿儿2 小时前
【C++】C++面向对象设计的核心思想之一: 接口抽象、解耦和可扩展性
java·开发语言·c++
~山有木兮2 小时前
new和delete的理解
c++·算法
whoarethenext3 小时前
使用 C/C++ 和 OpenCV 调用摄像头
c语言·c++·opencv
Dovis(誓平步青云)3 小时前
探索C++标准模板库(STL):从容器到底层奥秘-全面解析String类高效技巧(上篇)
开发语言·c++·stl·string