设计模式之观察者模式20170714

行为型设计模式之观察者模式:

一、含义

观察者模式也叫做发布订阅模式,定义对象间一种一对多的依赖关系,

每当一个对象改变状态(被观察者),则所有依赖于它的对象(观察者)都会得到通知并被自动更新

即被观察者对应状态产生时,会通知所有的观察者,同时观察者被自动更新。

二、代码说明

1.主要有两个角色

1)被观察者

它必须能够动态地增加、取消观察者,并且状态改变时会通知观察者(这三个个必须有的操作抽象出来),

同时被观察也有自己的业务逻辑,定义对哪些事件进行通知

2)观察者

观察者接收到消息后,即进行update(更新方法)操作(抽象出来),对接收到的信息进行处理。

每个观察者接收到消息后的处理反应是不同,各个观察这个有自己的处理逻辑

2.在用C实现过程中也是参考这种思想,不过由于C的局限,使用继承(覆写)代替实现两个接口更好。

以李斯观察韩非子为例,具体实现如下:

1)观察者模式使用场景:

 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     ObserverPatternUsage.c
 5 * Description        :     观察者模式的使用
 6 
 7 book@book-desktop:/work/projects/test/DesignPatterns/ObserverPattern$ gcc -o ObserverPatternUsage ObserverLisi.c  ObserverWangsi.c  ObserverPattern.c ObserverPatternUsage.c 
 8 book@book-desktop:/work/projects/test/DesignPatterns/ObserverPattern$ ./ObserverPatternUsage 
 9 韩非子:开始吃饭...
10 李斯:观察到韩非子活动,开始向秦老板汇报
11 李斯:报告,秦老板,韩非子有活动了-->韩非子在吃饭
12 李斯:汇报完毕...
13 王斯:观察到韩非子活动,自己也开始活动了...
14 王斯:因为韩非子在吃饭,所以我悲伤啊
15 王斯:哭死了...
16 韩非子:开始娱乐了...
17 李斯:观察到韩非子活动,开始向秦老板汇报
18 李斯:报告,秦老板,韩非子有活动了-->韩非子在娱乐
19 李斯:汇报完毕...
20 
21 * Created            :     2017.07.13.
22 * Author            :     Yu Weifeng
23 * Function List         :     
24 * Last Modified     :     
25 * History            :     
26 ******************************************************************************/
27 #include"stdio.h"
28 #include"malloc.h"
29 #include"stdlib.h"
30 #include"string.h"
31 #include"ObserverPattern.h"
32 
33 
34 
35 
36 /*****************************************************************************
37 -Fuction        : main
38 -Description    : 
39 -Input            : 
40 -Output         : 
41 -Return         : 
42 * Modify Date      Version         Author           Modification
43 * -----------------------------------------------
44 * 2017/07/13    V1.0.0         Yu Weifeng       Created
45 ******************************************************************************/
46 int main(int argc,char **argv)
47 {
48     T_Observer Lisi=newLisiObserver;
49     T_Observer Wangsi=newWangsiObserver;
50     
51     T_Observable tObserver=newHanfeiziObservable;
52     T_Hanfeizi Hanfeizi=newHanfeizi(&tObserver);
53 
54     Hanfeizi.ptObservable->AddObserver(&Lisi);
55     Hanfeizi.ptObservable->AddObserver(&Wangsi);
56     Hanfeizi.HaveBreakfast();
57 
58     Hanfeizi.ptObservable->DeleteObserver(&Wangsi);
59     Hanfeizi.HaveFun();
60 
61     
62     return 0;
63 }
ObserverPatternUsage.c

2)被调用者:

  1 /*****************************************************************************
  2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
  3 ------------------------------------------------------------------------------
  4 * File Module        :     ObserverPattern.c
  5 * Description        :     观察者模式
  6                         本文件是被观察者实现类
  7                         以韩非子的活动被李斯,王斯观察举例,显然
  8                         韩非子是被观察者
  9 * Created            :     2017.07.13.
 10 * Author            :     Yu Weifeng
 11 * Function List         :     
 12 * Last Modified     :     
 13 * History            :     
 14 ******************************************************************************/
 15 #include"stdio.h"
 16 #include"malloc.h"
 17 #include"stdlib.h"
 18 #include"string.h"
 19 #include"ObserverPattern.h"
 20 
 21 
 22 static T_Observer g_atObserver[MAX_OBSERVER_NUM]={NULL};
 23 static int g_iObserverLen=0;
 24 
 25 /*****************************************************************************
 26 -Fuction        : HanfeiziAddObserver
 27 -Description    : 公有函数
 28 -Input            : 
 29 -Output         : 
 30 -Return         : 
 31 * Modify Date      Version         Author           Modification
 32 * -----------------------------------------------
 33 * 2017/07/13      V1.0.0         Yu Weifeng       Created
 34 ******************************************************************************/
 35 int HanfeiziAddObserver(T_Observer *i_ptObserver)
 36 {
 37     int iRet=-1;
 38     if(g_iObserverLen>=MAX_OBSERVER_NUM)
 39     {
 40         printf("ObserverArray full!\r\n");
 41         iRet=-1;
 42     }
 43     else
 44     {
 45         memcpy(&g_atObserver[g_iObserverLen],i_ptObserver,sizeof(T_Observer));
 46         g_iObserverLen++;
 47         //printf("ObserverLen:%d\r\n",g_iObserverLen);
 48         iRet=0;
 49     }
 50     return iRet;
 51 }
 52 /*****************************************************************************
 53 -Fuction        : HanfeiziAddObserver
 54 -Description    : 公有函数
 55 -Input            : 
 56 -Output         : 
 57 -Return         : 
 58 * Modify Date      Version         Author           Modification
 59 * -----------------------------------------------
 60 * 2017/07/13      V1.0.0         Yu Weifeng       Created
 61 ******************************************************************************/
 62 int HanfeiziDeleteObserver(T_Observer *i_ptObserver)
 63 {
 64     int iRet=-1;
 65     int i;
 66     if(g_iObserverLen==0)
 67     {
 68         printf("ObserverArray empty!\r\n");
 69         iRet=-1;
 70     }
 71     else
 72     {
 73         for(i=0;i<g_iObserverLen;i++)
 74         {
 75             if(0==memcmp(&g_atObserver[i],i_ptObserver,sizeof(T_Observer)))
 76             {
 77                 break;
 78             }
 79             else
 80             {
 81             }
 82         }
 83         if(i>=g_iObserverLen)
 84         {
 85             printf("HanfeiziDeleteObserver err!\r\n");
 86             iRet=-1;
 87         }
 88         else
 89         {
 90             for(;i<g_iObserverLen-1;i++)
 91             {
 92                 memcpy(&g_atObserver[i],&g_atObserver[i+1],sizeof(T_Observer));
 93             }
 94             g_iObserverLen--;
 95             iRet=0;
 96         }
 97     }
 98     return iRet;
 99 }
100 
101 /*****************************************************************************
102 -Fuction        : HanfeiziNotifyObservers
103 -Description    : 公有函数
104 -Input            : 
105 -Output         : 
106 -Return         : 
107 * Modify Date      Version         Author           Modification
108 * -----------------------------------------------
109 * 2017/07/13      V1.0.0         Yu Weifeng       Created
110 ******************************************************************************/
111 void HanfeiziNotifyObservers(char *i_strContext)
112 {
113     int i;
114     for(i=0;i<g_iObserverLen;i++)
115     {//通知所有观察这
116         g_atObserver[i].Update(i_strContext);
117     }
118 }
119 
120 
121 /*****************************************************************************
122 -Fuction        : HanfeiziHaveBreakfast
123 -Description    : 公有函数
124 -Input            : 
125 -Output         : 
126 -Return         : 
127 * Modify Date      Version         Author           Modification
128 * -----------------------------------------------
129 * 2017/07/13      V1.0.0         Yu Weifeng       Created
130 ******************************************************************************/
131 void HanfeiziHaveBreakfast()
132 {
133     printf("韩非子:开始吃饭...\r\n");
134     //通知所有观察者
135     HanfeiziNotifyObservers("韩非子在吃饭");
136 }
137 
138 /*****************************************************************************
139 -Fuction        : HanfeiziHaveFun
140 -Description    : 公有函数
141 -Input            : 
142 -Output         : 
143 -Return         : 
144 * Modify Date      Version         Author           Modification
145 * -----------------------------------------------
146 * 2017/07/13      V1.0.0         Yu Weifeng       Created
147 ******************************************************************************/
148 void HanfeiziHaveFun()
149 {
150     printf("韩非子:开始娱乐了...\r\n");
151     //通知所有观察者
152     HanfeiziNotifyObservers("韩非子在娱乐");
153 }
ObserverPattern.c
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     ObserverPattern.h
 5 * Description        :     观察者模式
 6                                     
 7 * Created            :     2017.07.13.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #ifndef OBSERVER_PATTERN_H
14 #define OBSERVER_PATTERN_H
15 
16 #define MAX_OBSERVER_NUM    5
17 typedef struct Observer
18 {
19     void (*Update)(char *i_strContext);
20 }T_Observer;//抽象出观察者
21 
22 typedef struct Observable
23 {
24     int (*AddObserver)(T_Observer *i_ptObserver);//传参,接口,也就是抽象耦合
25     int (*DeleteObserver)(T_Observer *i_ptObserver);
26     void (*NotifyObservers)(char *i_strContext);
27 }T_Observable;//抽象出被观察者
28 
29 typedef struct Hanfeizi//C的局限,使用继承(覆写)代替实现两个接口更好
30 {//(少定义一个实现类,封装性也更好)
31     T_Observable *ptObservable;
32     void (*HaveBreakfast)();
33     void (*HaveFun)();
34 }T_Hanfeizi;
35 
36 
37 int HanfeiziAddObserver(T_Observer *i_ptObserver);
38 int HanfeiziDeleteObserver(T_Observer *i_ptObserver);
39 void HanfeiziNotifyObservers(char *i_strContext);
40 void HanfeiziHaveBreakfast();
41 void HanfeiziHaveFun();
42 #define newHanfeiziObservable {HanfeiziAddObserver,HanfeiziDeleteObserver,HanfeiziNotifyObservers}
43 #define newHanfeizi(Observable) {Observable,HanfeiziHaveBreakfast,HanfeiziHaveFun}
44 
45 
46 void LisiUpdate(char *i_strContext);
47 #define newLisiObserver {LisiUpdate}
48 
49 void WangsiUpdate(char *i_strContext);
50 #define newWangsiObserver {WangsiUpdate}
51 
52 
53 #endif
ObserverPattern.h
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     ObserverLisi.c
 5 * Description        :     观察者李斯
 6                         本文件是观察者实现类李斯的动作
 7 * Created            :     2017.07.13.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #include"stdio.h"
14 #include"malloc.h"
15 #include"stdlib.h"
16 #include"string.h"
17 #include"ObserverPattern.h"
18 
19 /*****************************************************************************
20 -Fuction        : LisiReportToQinshihuang
21 -Description    : 私有函数
22 -Input            : 
23 -Output         : 
24 -Return         : 
25 * Modify Date      Version         Author           Modification
26 * -----------------------------------------------
27 * 2017/07/13      V1.0.0         Yu Weifeng       Created
28 ******************************************************************************/
29 static void LisiReportToQinshihuang(char *i_strContext)
30 {
31     printf("李斯:报告,秦老板,韩非子有活动了-->%s\r\n",i_strContext);
32 }
33 
34 /*****************************************************************************
35 -Fuction        : LisiUpdate
36 -Description    : 公有函数
37 -Input            : 
38 -Output         : 
39 -Return         : 
40 * Modify Date      Version         Author           Modification
41 * -----------------------------------------------
42 * 2017/07/13      V1.0.0         Yu Weifeng       Created
43 ******************************************************************************/
44 void LisiUpdate(char *i_strContext)
45 {
46     printf("李斯:观察到韩非子活动,开始向秦老板汇报\r\n");
47     LisiReportToQinshihuang(i_strContext);
48     printf("李斯:汇报完毕...\r\n");
49 }
ObserverLisi.c
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     ObserverWangsi.c
 5 * Description        :     观察者王斯
 6                         本文件是观察者实现类王斯的动作
 7 * Created            :     2017.07.13.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #include"stdio.h"
14 #include"malloc.h"
15 #include"stdlib.h"
16 #include"string.h"
17 #include"ObserverPattern.h"
18 
19 /*****************************************************************************
20 -Fuction        : WangsiCry
21 -Description    : 私有函数
22 -Input            : 
23 -Output         : 
24 -Return         : 
25 * Modify Date      Version         Author           Modification
26 * -----------------------------------------------
27 * 2017/07/13      V1.0.0         Yu Weifeng       Created
28 ******************************************************************************/
29 static void WangsiCry(char *i_strContext)
30 {
31     printf("王斯:因为%s,所以我悲伤啊\r\n",i_strContext);
32 }
33 
34 /*****************************************************************************
35 -Fuction        : WangsiUpdate
36 -Description    : 公有函数
37 -Input            : 
38 -Output         : 
39 -Return         : 
40 * Modify Date      Version         Author           Modification
41 * -----------------------------------------------
42 * 2017/07/13      V1.0.0         Yu Weifeng       Created
43 ******************************************************************************/
44 void WangsiUpdate(char *i_strContext)
45 {
46     printf("王斯:观察到韩非子活动,自己也开始活动了...\r\n");
47     WangsiCry(i_strContext);
48     printf("王斯:哭死了...\r\n");
49 }
ObserverWangsi.c

3)执行结果:

book@book-desktop:/work/projects/test/DesignPatterns/ObserverPattern$ gcc -o ObserverPatternUsage

ObserverLisi.c  ObserverWangsi.c  ObserverPattern.c ObserverPatternUsage.c

book@book-desktop:/work/projects/test/DesignPatterns/ObserverPattern$ ./ObserverPatternUsage

韩非子:开始吃饭...

李斯:观察到韩非子活动,开始向秦老板汇报

李斯:报告,秦老板,韩非子有活动了-->韩非子在吃饭

李斯:汇报完毕...

王斯:观察到韩非子活动,自己也开始活动了...

王斯:因为韩非子在吃饭,所以我悲伤啊

王斯:哭死了...

韩非子:开始娱乐了...

李斯:观察到韩非子活动,开始向秦老板汇报

李斯:报告,秦老板,韩非子有活动了-->韩非子在娱乐

李斯:汇报完毕...

 

4)详细代码:

https://github.com/fengweiyu/DesignThinking/tree/master/DesignPatterns/BehavioralDesignPatterns/ObserverPattern

 

三、使用场景

1.关联行为场景,

需要注意的是,关联行为是可拆分的,而不是"组合"关系

2.时间多级触发场景

3.跨系统的消息交换场景,如消息队列的处理机制

4.一个地方监视另外一个地方的处理情况,但又不想让监视方与被监视方之间相互依赖的时候

四、优点

1.观察者和被观察者之间是抽象耦合

2.建立了一套触发机制

 

五、缺点

1.一个被观察者,多个观察者,开发和调试就会比较复杂,在这种情况下,一般考虑采用异步的方式(考虑线程安全和队列的问题)。

多级触发时的效率更是让人担忧,大家在设计时注意考虑。

2.一个被观察者,多个观察者,观察者如何快速响应问题,两个办法:

1)采用多线程技术,

无论是被观察者启动线程还是观察者启动线程,都可以跳高系统性能,这也就是大家通常说的异步架构

2)缓存技术,

即准备好足够的资源,以保证快速响应,代价就是开发难度大,压力测试要足够充分,这种方法也就是大家说的同步架构

2.广播链问题

一个观察者可以有双重身份,既是观察者也是被观察者,这就会形成一个触发链。这样逻辑就比较复杂,可维护性非常差,在一个观察者模式中最多出现一个对象既是观察者也是被观察者,也就是说消息最多转发一次(传递两次)才比较好控制。

注意:它和责任链模式最大的区别是,观察者模式是相邻两个结点结构,即处理完返回时也是返回到上一个结点。而责任链处理完后可以直接返回到最初的结点即根节点。

 

转载于:https://www.cnblogs.com/yuweifeng/p/7171477.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值