分别用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;
}

哈哈,大功告成,撸这种在老板面前一文不值,自己却撸的很嗨的代码,还真是很开心的呢^^,也许这就是程序猿才能明白的快乐吧

 

posted @ 2018-06-21 15:54  骇客HK  阅读(325)  评论(1编辑  收藏  举报