Observer(观察者模式)

来源:互联网 发布:消防系统模拟软件 编辑:程序博客网 时间:2024/06/05 23:07

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 8struct 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;}