zoukankan      html  css  js  c++  java
  • 分别用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;
    }

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

  • 相关阅读:
    关于 语文物理 和 数学物理
    黎耀天 共量子 我拍了 几张照片 给你们 当 素材
    看了 陈记抄 同学 的 《随便聊聊之量子力学中的散射理论》
    极坐标系 下的 牛顿第二定律
    jQuery 工具类库集锦
    Javascript跨域问题解决方案
    js禁止从浏览器缓存读取消息
    关于双击事件.MouseEvent.DOUBLE_CLICK
    div的打开与关闭js
    利用通道完成文件的复制 (非直接缓存区)
  • 原文地址:https://www.cnblogs.com/ruanraun/p/9209465.html
Copyright © 2011-2022 走看看