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

观察者

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

参考b站博主代码:

#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语言版本

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值