观察者模式


一、观察者模式:示例1

1.观察者(订阅者)

1.1 函数接口实现

void action1(char *str)
{
	printf("观察者1接收到消息:%s\n",str);
}

void action2(char *str)
{
	printf("观察者2接收到消息:%s\n",str);
}

void action3(char *str)
{
	printf("观察者3接收到消息:%s\n",str);
}

1.2 观察者接口

//观察者接口
typedef struct _Observer
{
	void (*action)(char *str);	//发现有动静,要做相应的行动
}Observer;

1.3 实例化具体观察者

//实例化具体观察者
Observer ObserverEXP1 =
{
	.action = action1,
};

Observer ObserverEXP2 =
{
	.action = action2,
};

Observer ObserverEXP3 =
{
	.action = action3,
};

1.4 采用链表的方式存储 观察者们

//采用链表的方式存储 观察者们
typedef struct _ObserverNode
{
    Observer *ob;
    struct _ObserverNode *next;
}ObserverNode;
ObserverNode *obHead = NULL;

//初始化链表
void observerInit()
{
	obHead = (ObserverNode *)malloc(sizeof(ObserverNode));
    obHead->ob = NULL;
    obHead->next = NULL;
}

2.被观察者(发布者)

2.1 函数接口实现

//函数接口实现
void AddObserver(Observer *pObserver)
{
    ObserverNode * node = (ObserverNode *)malloc(sizeof(ObserverNode));
    node->ob = pObserver;
    node->next = NULL;
	
    ObserverNode * current = obHead;
    while (current->next != NULL)
    {
        current = current->next;
    }
    current->next = node;	
}
 
void DelObserver(Observer *pObserver)
{
    ObserverNode * current = obHead;
	ObserverNode * lastNod = obHead;
    while (current != NULL)
    {	
        if(current->ob == pObserver)
        {
            if(current->next == NULL)
            {
				free(lastNod->next);
				lastNod->next = NULL;
				current = NULL;
            }
			else
			{
				free(lastNod->next);
				lastNod->next = lastNod->next->next;
				current = lastNod->next;
			}	
        }
		else
		{
			lastNod = current;
			current = current->next;
		}		
    }
}
 
void NotifyObserver(char *str)
{
    ObserverNode * current = obHead;
    while (current != NULL )
    {
        if(current->ob != NULL)
        {
            current->ob->action(str);
        }
        current = current->next;
    }
}

2.2 被观察者接口

//被观察者接口
typedef struct _Subject
{
	void (*addObserver)(Observer *pObserver);		//增加一个观察者
	void (*delObserver)(Observer *pObserver);		//删除一个观察者
	void (*notifyObserver)(char *str);				//通知观察者
}Subject;

2.3 实例化具体被观察者

//实例化具体被观察者
Subject SubjectEXP =
{
	.addObserver = AddObserver,
	.delObserver = DelObserver,
	.notifyObserver = NotifyObserver,
};

3.应用场景

void client()
{
	observerInit();
	SubjectEXP.addObserver(&ObserverEXP1);
	SubjectEXP.addObserver(&ObserverEXP2);
	SubjectEXP.addObserver(&ObserverEXP3);
	SubjectEXP.notifyObserver("干饭111");
	printf("<----------------------------------> \n");
	SubjectEXP.delObserver(&ObserverEXP3);
	SubjectEXP.delObserver(&ObserverEXP1);
	SubjectEXP.notifyObserver("干饭222");
}

4.运行效果

在这里插入图片描述

二、观察者模式:示例2

1.代码实现

/* 要知道羊肉价格的餐馆  */
void restaurant_1 (float MuttonPrice) //Observer 1
{
    printf("%s, MuttonPrice:%f \n",__FUNCTION__,MuttonPrice);
}

void restaurant_2 (float MuttonPrice) //Observer 2
{
    printf("%s, MuttonPrice:%f \n",__FUNCTION__,MuttonPrice);
}

/*  采用链表的方式存储 观察者们(餐馆) */
typedef void(*Observer)(float);

typedef struct _ObserverNode
{
    Observer ob;
    struct _ObserverNode *next;
}ObserverNode;
ObserverNode *obHead = NULL;

void init()
{
    obHead = (ObserverNode *)malloc(sizeof(ObserverNode));
    obHead->ob = NULL;
    obHead->next = NULL;
}

//添加观察者
void addObserver( Observer restaurant)
{
    ObserverNode * node = (ObserverNode *)malloc(sizeof(ObserverNode));
    node->ob = restaurant;
    node->next = NULL;
    
    ObserverNode * current = obHead;
    while (current->next != NULL)
    {
        current = current->next;
    }
    current->next = node;
}

//删除观察者
void releaseObserver(Observer restaurant)
{
    ObserverNode * current = obHead;
	ObserverNode * lastNod = obHead;
    while (current != NULL)
    {	
        if(current->ob == restaurant)
        {
            if(current->next == NULL)
            {
				free(lastNod->next);
				lastNod->next = NULL;
				current = NULL;
            }
			else
			{
				free(lastNod->next);
				lastNod->next = lastNod->next->next;
				current = lastNod->next;
			}	
        }
		else
		{
			lastNod = current;
			current = current->next;
		}		
    }
}

/* 羊肉价格变化通知 餐馆 */
void MuttonPriceChange (float MuttonPrice)
{
    ObserverNode * current = obHead;
    while (current != NULL )
    {
        if(current->ob != NULL)
        {
            current->ob(MuttonPrice);
        }
        current = current->next;
    }
}

2.应用场景

	init(); //初始化
	addObserver(restaurant_1); 				//添加观察者们(餐馆 1)
	addObserver(restaurant_2);				//添加观察者们(餐馆 2)
	MuttonPriceChange(12.4);				//羊肉价格变化通知餐馆们
	printf("<---------------------> \n");
	releaseObserver(restaurant_2);			//删除其中的一个观察者们(餐馆 1)
	MuttonPriceChange(9.4);					//羊肉价格变化通知餐馆们	

3.运行效果:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值