设计模式之观察者模式(C语言)

介绍:

观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。


问题:

​ 假如顾客对某个特定的产品非常感兴趣 , 而该产品很快将会在商店里出售。顾客可以每天来商店看看产品是否到货。但如果商品尚未到货时,顾客就会空手而归。另一方面,每次新产品到货时,商店可以向顾客发送邮件。这样,顾客就无需反复前往商店了,但这样同时也可能会惹恼对新产品没有兴趣的其他顾客。

​ 所以我们似乎遇到了一个矛盾:要么让顾客浪费时间检查产品是否到货, 要么让商店浪费资源去通知没有需求的顾客。

解决方法:

​ 让对产品有需求的的顾客订阅这个商店的消息,当商店有新产品的时候,就会向订阅了消息的顾客发送相应的邮件,这样就不会浪费资源通知没有需求的顾客,顾客也无需每次都要去店里看看是否到货;


类比:

​ 如果你订阅了一份杂志或报纸, 那就不需要再去报摊查询新出版的刊物了。 出版社 (即应用中的 “发布者”) 会在刊物出版后 (甚至提前) 直接将最新一期寄送至你的邮箱中。


整体代码如下:

.h文件

#ifndef __MSG_SUBSCRIBE_H_
#define __MSG_SUBSCRIBE_H_

/*消息的类型都在这个枚举里*/
typedef enum
{
    ON_OFF_STATE,
    LIGHTNESS,
    WORK_MODE,
    TOPIC_MAX
}topic_e;

typedef void (*observer_handle)(void* msg);

typedef struct
{
    observer_handle func;
    topic_e topic;
}observer_t;

/*消息订阅并将回调注册进去*/
int topic_subscribe(observer_t *observer);
/*消息通知*/
int msg_notify(topic_e topic, void *msg);

#endif /* __MSG_SUBSCRIBE_H_ */

.c文件

#include <stdio.h>
#include "msg_subscribe.h"

typedef struct _Link_List
{
    observer_handle func;
    struct _Link_List* next;
}Observer_Node;

Observer_Node* func_head_node[TOPIC_MAX] = {NULL};

int topic_subscribe(observer_t* observer)
{
    assert(observer->topic >= TOPIC_MAX || observer->func == NULL || observer == NULL);

    Observer_Node* func_link_tail = func_head_node[observer->topic];
    if(func_link_tail != NULL)
    {
        while(func_link_tail->next != NULL)
        {
            func_link_tail = func_link_tail->next;
        }
    }

    Observer_Node* observer_node = (Observer_Node*)malloc(sizeof(Observer_Node));
    assert(observer_node == NULL)
        
    observer_node->func = observer->func;
    observer_node->next = NULL;

    if(func_link_tail == NULL)
    {
        func_head_node[observer->topic] = observer_node;
    } 
    else
    {
        func_link_tail->next = observer_node;
    }
    return 0;
}


int msg_notify(topic_e topic, void* msg)
{
    assert(topic >= TOPIC_MAX);

    Observer_Node* cur_node = func_head_node[topic];
    printf("Msg notify %d\r\n", topic);

    while(cur_node != NULL)
    {
        assert(cur_node->func == NULL);
        cur_node->func(msg);
        cur_node = cur_node->next;
    }
    return 0;
}

上一篇:Lifecycle的原理


下一篇:设计模式--观察者模式笔记