zoukankan      html  css  js  c++  java
  • 设计模式->观察者模式

    观察者模式能很大的降低模块之前的耦合。详细的观察者模式,客官们能够去看《设计模式》或者《Head first设计模式》等之类的书。


    在java中,java.util库中封装了观察者模式。

    在C++中并没有这玩意。

    下面就是为了封装一个C++的观察者模式而写。


    观察者模式中。对于主题(subject)和观察者(observer)的接口能够是抽象出来的。而这些接口差点儿相同都是通用的。然后要用时仅仅要去继承这些接口。完毕对应的处理就可以。java中的实现也是一样的道理。


    观察者。非常明显是要去观察一样东西。可是。对于不同的详细实现,要观察的东西并不同啊!比方要实现一个天气预报的,我要观察温度、湿度等。要实现一个消息的显示程序。那么我要观察的就是消息了。对于不同的实现,有些要观察的不仅仅一个变量,有的仅仅有一个变量。在C++中。能够使用变长的參数表。可是,这种实现会带来非常多问题,比方类型安全等。还有什么办法能够处理不定个变量呢?眼下,我能想到的就仅仅实用类、结构体去封装了。

    那么要适应不同的类呢?那就要用到模板了。


    下面是初步的实现。


    subject类的设计例如以下:

    template <typename TContent>
    class Subject
    {
    public:
    	typedef TContent Content; 	///< 观察的内容类型
    	typedef Observer<Content> AbstractObserver; 	///< 观察者的抽象类型
    
    	void registerObserver(AbstractObserver *obs);
    
    	void unregisterObserver(AbstractObserver *obs);
    
    	void notifyObservers(TContent cnt);
    private:
    	typedef std::list<AbstractObserver*> ObserverList;
    	typedef typename ObserverList::iterator ObserverListIterator;
    	ObserverList _observers;
    
    };

    这里将要观察的内容设为TContent。假设要观察多个值的对象。能够封装一个struct。然后做为模板參数传进来。


    observer类的设计例如以下:

    template <typename TContent>
    class Observer
    {
    public:
    	typedef TContent Content;
    
    	/**
    	 * @brief update 当有新内容时会被调用
    	 *
    	 * 子类化此类,重写这个函数
    	 * @param cnt 将的内容通过这个參数传入
    	 */
    	virtual void update(TContent cnt) = 0;
    
    private:
    };

    详细的实现代码。能够參见我的github


    这样封装后。就能够非常方便使用了。下面是我使用的一个样例。

    class ConcreteSubject : public Subject<int>
    {
    public:
    	ConcreteSubject() : times(0)
    	{
    
    	}
    
    	void run()
    	{
    		this->notifyObservers(times);
    		++times;
    	}
    
    private:
    	int times;
    };
    
    class ConcreteObserver : public Observer<int>
    {
    public:
    	virtual void update(int cnt)
    	{
    		cout << cnt << endl;
    	}
    };


    測试例如以下:

    	ConcreteSubject subject;
    
    	ConcreteObserver obs1;
    	ConcreteObserver obs2;
    
    	subject.registerObserver(&obs1);
    	subject.registerObserver(&obs2);
    
    	for (int i=0; i<100; ++i)
    	{
    		subject.run();
    	}


    以上的測试写在了github的test(使用gtest进行測试)里面:https://github.com/tenghui0425/Common/blob/master/experiment/test/subject_observer_test.cpp


    转载请注明出处:http://blog.csdn.net/tenghui0425/article/details/24243475

  • 相关阅读:
    Java集合类的操作笔记
    Java一维数组转换二叉树结构
    Python学习记录(一)
    Android测试读写sd卡文件与写sd卡文件耗时
    如何高效地分析Android_log中的问题?——查看Android源码
    Java替换字符串中的占位符
    Android 编译错误——布局 Error parsing XML: not well-formed (invalid token)
    Android Studio工程引用第三方so文件
    设计模式——设计模式之禅的阅读笔记
    Android Studio的快捷键
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7115011.html
Copyright © 2011-2022 走看看