分别用C/C++ 和 C#实现简单的观察者模式
网上找了很多关于观察者模式的代码例子和文章,都写的比较复杂,我个人还是喜欢从易到难,今天自己参考网上资料,也写了一个简单观察者模式的例子,简单的复习了一下Observer 模式,Observer 模式使用一对多的方式,可以让多个观察者同时关注同一个事物,并作出不同的响应。
例如下面的例子,Manager的底薪为基本工资的1.6倍,Employee的底薪为基本工资的1.2倍。Observer 类的Attach方法与Detach方法可以用于注册和注销观察者,最后执行Execute方法可以对多个已注册的观察者同时输入参数。
开发 Observer 模式时借助委托,可以进一步简化开发的过程。由于委托对象支持多路广播,在Observer 类中建立了一个委托对象wageHandler,通过Attach与Detach方法可以分别加入或取消委托。如果观察者想对事物进行监测,只需要加入一个委托对象即可。然后委托的GetInvodationList方法能获取多路广播委托列表,在Execute方法中,就是通过去多路广播委托列表去判断所绑定的委托数量是否为0。
public delegate double Handler(double wages); public class Manager { public double GetWages(double basicWages) { double totalWages = 1.6 * basicWages; Console.WriteLine("Manager's wages is : " + totalWages); return totalWages; } } public class Employee { public double GetWages(double basicWages) { double totalWages = 1.2 * basicWages; Console.WriteLine("Employee's wages is : " + totalWages); return totalWages; } } public class Observe { public Handler WageHandler { get; set; } //通过GetInvodationList方法获取多路广播委托列表,如果观察者数量大于0即执行方法 public void Execute(double basicWages) { if (WageHandler != null) if (WageHandler.GetInvocationList().Count() > 0) WageHandler(basicWages); } } class Program { static void Main(string[] args) { Observe wageManager = new Observe(); //加入Manager观察者 wageManager.WageHandler += new Handler(new Manager().GetWages); //加入Employee观察者 wageManager.WageHandler += new Handler(new Employee().GetWages); //同时加入底薪3000元,分别进行计算 wageManager.Execute(3000); Console.ReadKey(); } }
执行结果:
然后为了加大难度,又用C++编写了一个类似例子来实现观察者模式,当然C++编写起来相对C#会复杂一些,而且最终实现效果没有C#好,但是一切都是为了更好的学习和理解语言,这波还是不亏的,C++里面有个和委托类似的东西,它的名字叫函数指针,然后用set存放函数指针,遍历执行
#include "stdafx.h" using namespace std; typedef double(*Handler)(double wages);//定义函数指针,功能和C#中的委托类似 class Manager { public: static double GetWages(double basicWages) { double totalWages = 1.6*basicWages; cout << "Manager's wages is : " << totalWages << endl; return totalWages; } }; class Employee { public: static double GetWages(double basicWages) { double totalWages = 1.2*basicWages; cout << "Employee's wages is : " << totalWages << endl; return totalWages; } }; class Observe { public: set<Handler> set; //加入观察者 void Attach(Handler wageHandler1) { set.insert(wageHandler1); } //删除观察者 void Detach(Handler wageHandler1) { set.erase(wageHandler1); } void Execute(double basicWages) { if (NULL != &set) { if (set.size() > 0) { typename std::set<Handler>::iterator it;//list<T>前面需要用typename限定一下,因为编译器不知道list<T>::iterator是代表一个类型。list<T>::iterator iter; 改为 typename std::list<T>::iterator iter; for (it = set.begin(); it != set.end(); it++) { (*it)(basicWages); } } } } }; int main() { Manager man; Employee emp; Observe observe; //加入Manager观察者 Handler managerHandler = &(man.GetWages); observe.Attach(managerHandler); //加入Employee观察者 Handler employeeHandler = &(emp.GetWages); observe.Attach(employeeHandler); //同时加入底薪3000元,分别进行计算 observe.Execute(3000); system("pause"); return 0; }
哈哈,大功告成,撸这种在老板面前一文不值,自己却撸的很嗨的代码,还真是很开心的呢^^,也许这就是程序猿才能明白的快乐吧
付伤年华的技术分享