1、定义
定义对象间的一种一对多的关系的依赖关系,但对象状态发生变化时,所依赖该对象的所有对象都会得到通知,并自动被更新。
2、结构
3、协作角色
Subject:主题对象,负责管理观察者
Observer: 观察者的接口,
concreteSubject 具体目标,事件触发者,
concreteObserver 具体观察者,
协作图如下
4、适用性:
1、当一个对象改变影响未知数的对象
2、一对象改变要通知的其他对象,而又不知道是谁时。
5、实例:
1、需求,嵌入式设备,尤其是手持设备对续航能力都有很高的要求,所以会在适当的时候进入休眠,如果一个个设备调用,显然很不合适。
2、解决,设备向设备管理程序注册自己,当有休眠等事件触发时方便通知。
3、实现,下面代码是模拟,实际上要比这要复杂。
suspend.h
#ifndef __SUSPEND_H__
#define __SUSPEND_H__
typedef void (*suspend) (void);
#define DEVICE_NAME_LEN 8
struct suspend_list {
struct suspend_list *next;
suspend nofity;
char name[DEVICE_NAME_LEN];
};
int suspend_init();
int device_attach(char *name, suspend func);
int device_detach(char *name);
int device_notify();
#endif
suspend.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "suspend.h"
struct suspend_list suspend_head;
int suspend_init()
{
memset((void *)&suspend_head, 0, sizeof(suspend));
return 0;
}
int device_attach(char *name, suspend func)
{
int name_len;
struct suspend_list *observer = (struct suspend_list *)malloc(sizeof(struct suspend_list));
if(observer == NULL)
return -1;
observer->nofity = func;
name_len = strlen(name);
if((name != NULL)&&(name_len < DEVICE_NAME_LEN))
{
memcpy(observer->name,name,strlen(name));
}
else
{
free(observer);
return -1;
}
observer->next = suspend_head.next;
suspend_head.next = observer;
return 0;
}
int device_detach(char *name)
{
int name_len;
struct suspend_list *pre = NULL;
struct suspend_list *cur = NULL;
name_len = strlen(name);
pre = &suspend_head;
cur = suspend_head.next;
if((name != NULL)&&(name_len < DEVICE_NAME_LEN))
{
while(cur)
{
if(memcmp(name, cur->name,name_len) == 0)
{
pre->next = cur->next;
free(cur);
return 0;
}
pre = cur;
cur = cur->next;
}
}
return -1;
}
int device_notify()
{
struct suspend_list *cur;
cur = suspend_head.next;
while(cur)
{
if(cur->nofity)
cur->nofity();
cur = cur->next;
}
return 0;
}
nand.c
#include <stdio.h>
#include "suspend.h"
#define DEVICE_NAME "nand"
void nand_update()
{
printf("nand update\n");
}
void nand_suspend_register()
{
device_attach(DEVICE_NAME,nand_update);
}
void nand_suspend_remove()
{
device_detach(DEVICE_NAME);
}
screen.c
#include <stdio.h>
#include "suspend.h"
#define DEVICE_NAME "screen"
void screen_update()
{
printf("sreen update\n");
}
void screen_suspend_register()
{
device_attach(DEVICE_NAME,screen_update);
}
void screen_suspend_remove()
{
device_detach(DEVICE_NAME);
}
client.c
#include <stdio.h>
#include "suspend.h"
int main()
{
screen_suspend_register();
nand_suspend_register();
device_notify();
screen_suspend_remove();
device_notify();
return 0;
}