作者:gfree.wind@gmail.com博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net
今天学习观察者模式。
观察者模式的定义:观察者模式定义了对象之间的一对多以来, 这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
观察者模式应用很广泛。在Linux内核中的notifier chain即可看作是观察者模式。那么下面就看看notifier chain的如何实现的观察者模式。
kernel中有很多模块都需要了解网络接口的状态,这时就是观察者模式大显身手的时候了。这里,网络接口就是观察者模式中的subject,而需要了解其状态变化的其它模块,即为设计模式中的observer。当网络接口状态发生变化时,由接口主动通知所有observer。对于网络接口来说,它不知道observer是谁,对于状态变化observer如何处理,它所要做的就是将状态变化信息通知observer。而observer可以任意加入或者离开subject,对于它来说,这个是自由的。它只需告诉subject,现在我要关心你的状态,有情况通知我。而离开时,则通知subject,不要再发消息给我。
下面就以网络接口状态这一情况,来说明一下kernel中的notifier chain是如何实现的。
首先需要为网络接口定义一个notifier head。
- static RAW_NOTIFIER_HEAD(netdev_chain);
其类型很简单
- struct raw_notifier_head {
-
struct notifier_block __rcu *head;
-
};
只是一个struct notifier_block的头结点。
节点的具体结构:
- struct notifier_block {
-
int (*notifier_call)(struct notifier_block *, unsigned long, void *);
-
struct notifier_block __rcu *next;
-
int priority;
-
};
从这个struct notifier_block可以看出,其为一个优先级单链表,而notifier_call为observer的回调函数。即观察者模式中observer的处理事件的函数。
以ARP模块为例,在ARP模块的初始化函数中arp_init中,它通过调用register_netdevice_notifier表示它对网络接口这个subject感兴趣,通过比较优先级,将arp_netdev_notifier作为一个节点挂在了netdev_chain的链表上。
那么当网络接口状态发生变化时,如网络接口变为UP状态时,就通过call_netdevice_notifiers(NETDEV_PRE_UP, dev);通知所有注册的observer,某个dev的发生NETDEV_PRE_UP的状态变化。
因为今天主要说的是设计模式,而非notifier chain的实现,所有具体代码还是请参考linux代码。这部分代码很简单,比较容易看懂。
Note:
对于设计模式,我一直认为不要去生搬硬套的去使用设计模式,更无需去记住哪个模式的名字是什么,特性是什么。无论是什么语言,我们只需记住封装变化,保持灵活。设计模式要信手拈来,领会思想,灵活使用。
参考:
1. 《设计模式——可复用面向对象软件的基础》
2. 《Head First 设计模式》
阅读(916) | 评论(0) | 转发(0) |