-
- 一. 定义
- 二.应用场景
- 三.优缺点
- 四.模式结构
- 五.C语言实现
- 六.总结
观察者模式定义:当对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新,也可以称这种模式发布-订阅模式
二.应用场景应用场景:Excel 中的数据与折线图、饼状图、柱状图之间的关系;MVC 模式中的模型与视图的关系;事件模型中的事件源与事件处理者等等
三.优缺点主要优点有,降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系,目标与观察者之间建立了一套触发机制
当然也有缺点:当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率
所谓技术利弊两面,取决于具体应用需求
观察者模式的结构如下。
-
抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的集合和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
-
抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用
结构图如下:
五.C语言实现具体实现源码如下:源码github获取
#include
#include
#include
#include
#include
typedef struct Observer_t
{
char name[32];
bool (*adapter)(char *themeName);
bool (*update_proc)(struct Observer_t *observerObj, char *themeName);
}Observer_t;
typedef struct Subject_t
{
char name[32];
struct Observer_t *register_list[10];
bool (*add)(struct Subject_t *subjectobj, struct Observer_t * observerobj);
bool (*del)(struct Subject_t *subjectobj, struct Observer_t * observerobj);
bool (*notify)(struct Subject_t * subjectObj, char *event);
}Subject_t;
bool adapter(char *themeName)
{
if (0 == strcasecmp(themeName, "csdn-blog"))
return true;
else
return true;
}
bool update_proc(Observer_t *observerObj, char *themeName)
{
printf("[%s]收到[%s]主题跟新通知.....n", observerObj->name, themeName);
return true;
}
bool add(Subject_t *subjectObj, Observer_t *observerObj)
{
for(int i = 0; i < (sizeof(subjectObj->register_list)/sizeof(subjectObj->register_list[0])); i++)
{
if (subjectObj->register_list[i] == NULL)
{
subjectObj->register_list[i] = observerObj;
return true;
}
}
return false;
}
bool del(Subject_t * subjectObj, Observer_t *observerObj)
{
for (int i = 0; i< (sizeof(subjectObj->register_list)/sizeof(subjectObj->register_list[0])); i++)
{
if (subjectObj->register_list[i] == observerObj)
{
subjectObj->register_list[i] = NULL;
free(observerObj);
return true;
}
}
return false;
}
bool notify(Subject_t * subjectObj, char *event)
{
for(int i = 0; i< (sizeof(subjectObj->register_list)/sizeof(subjectObj->register_list[0])); i++)
{
if (NULL == subjectObj->register_list[i])
continue;
if (subjectObj->register_list[i]->adapter(event))
subjectObj->register_list[i]->update_proc(subjectObj->register_list[i],
subjectObj->name);
}
return true;
}
Observer_t* Observer_new(char *name)
{
Observer_t * p;
p = malloc(sizeof(*p));
if (!p)
return NULL;
memcpy(p->name, name, strlen(name));
p->adapter = adapter;
p->update_proc = update_proc;
return p;
}
Subject_t* Subject_new(char * name)
{
Subject_t * p;
p = malloc(sizeof(*p));
if (!p)
return NULL;
memset(p, 0x00, sizeof(*p));
memcpy(p->name, name, strlen(name));
p->add = add;
p->del = del;
p->notify = notify;
}
int main(void)
{
Subject_t *subject;
Observer_t *observerA;
Observer_t *observerB;
Observer_t *observerC;
printf("start to create subjecter and observer.....n");
// 创建一个主题
subject = Subject_new("creater");
//创建多个消费者
observerA = Observer_new("readerA");
observerB = Observer_new("readerB");
observerC = Observer_new("readerC");
// 添加消费者到观察者列表
subject->add(subject, observerA);
subject->add(subject, observerB);
subject->add(subject, observerC);
// 通知给所有读者
subject->notify(subject, "csdn-blog");
}
当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象有待改变的时候,应该考虑使用观察者模式,同时观察者模式所做的工作也是在解除耦合,各个对象互为独立工作。



