zoukankan      html  css  js  c++  java
  • <C++ 实现设计模式> 观察者模式

    观察者模式,又称公布--订阅,mvc模式等. 通俗点讲,比方股票来说,非常多人关注一支股票,派一个人去观察股票的情况,一有变化(观察),就通知全部的预定这个消息的人.  

    而我们常见的mvc模式,v是指view-视图,m指model-模型,有点类似观察者模式,模型中的数据,一有变化就通知相关联的视图. 这样非常方便地隔离开了模型和视图.

    这里使用的样例是关于博客的订阅. 博客属于被观察的对象,订阅者属于观察者. 订阅者先订阅(注冊)博客,博客一有更新,就会遍历注冊表,给订阅者推送更新的博客.

    自己画UML图,,,我是自己画的,UML图对于敲代码确实非常有帮助.  以下直接给出对应代码:

    observer.h:

    #ifndef OBSERVER_H
    #define OBSERVER_H
    #include<string>
    #include "subject.h"
    
    using namespace std;
    class Blog;
    class BlogCSDN;
    class Observer
    {
    	public:
    		Observer() {}
    		virtual ~Observer() {}
    		virtual void Update() {}
    };
    
    class ObserverBlog : public Observer
    {
    	private:
    		string m_name; //观察者名称
    		Blog *m_blog; //观察的博客,以链表的形式更好,能够观察多个博客
    	public:
    		ObserverBlog(string name, Blog *blog): m_name(name), m_blog(blog) {}
    		~ObserverBlog() {}
    		void Update();
    };
    
    
    #endif


    observer.cpp

    #include "observer.h"
    #include<iostream>
    
    using namespace std;
    
    void ObserverBlog::Update()
    {
    	string status = m_blog->GetStatus();
    	cout << m_name << "-------" << status << endl;
    }


    subject.h

    #ifndef SUBJECT_H
    #define SUBJECT_H
    #include<list>
    #include "observer.h"
    using namespace std;
    class Observer;
    class Blog
    {
    	private:
    		list<Observer *> m_observers; //观察者列表
    	protected:
    		string m_status; //状态
    	public:
    		Blog() {}
    		virtual ~Blog() {}
    		void Attach(Observer *observer);   //加入观察者
    		void Remove(Observer *observer);	//移除观察者
    		void Notify();	//通知观察者
    		virtual void SetStatus(string s);	//设置状态
    		virtual string GetStatus();	//获得状态
    };
    
    class BlogCSDN : public Blog
    {
    	private:
    		string m_name; //博主名字
    	public:
    		BlogCSDN(string name) : m_name(name) {}
    		~BlogCSDN() {}
    
    		void SetStatus(string s);
    		string GetStatus();
    
    };
    #endif


    subject.cpp

    #include "subject.h"
    
    void Blog::Attach(Observer *observer)
    {
    	m_observers.push_back(observer);
    }
    
    void Blog::Remove(Observer *observer)
    {
    	m_observers.remove(observer);
    }
    
    void Blog::Notify()
    {
    	list<Observer *>::iterator iter = m_observers.begin();
    	for(; iter != m_observers.end(); iter++) {
    		(*iter)->Update();
    	}
    }
    
    void Blog::SetStatus(string s)
    {
    	m_status = s;
    }
    
    string Blog::GetStatus()
    {
    	return m_status;
    }
    
    
    
    void BlogCSDN::SetStatus(string s)
    {
    	m_status = "csdn通知: " +m_name + s;
    }
    
    string BlogCSDN::GetStatus()
    {
    	return m_status;
    }


    main.cpp

    #include "observer.h"
    #include "subject.h"
    
    int main()
    {
    	Blog *blog = new BlogCSDN("zy416548283");
    	Observer *observer = new ObserverBlog("tutupig", blog);
    	blog->Attach(observer);
    	blog->SetStatus("发表观察者模式实现的文章");
    	blog->Notify();
    	delete blog;
    	delete observer;
    	return 0;
    }


    编译执行:

    zy@zyPc:~/code/Cplus/designPattern/observer$ ./a.out 
    tutupig-------csdn通知: zy416548283发表***文章
    


    假设自己敲代码遇到交叉引用的问题(头文件相互引用,又调用了类中的方法之类的),能够參考帖子:点击打开链接 ,也能够看看我的提问:点击打开链接

    PS:

    參考博客:点击打开链接

    參考书籍:<23种设计模式-C++> ,<易学设计模式>




  • 相关阅读:
    vuecli3title标签中的htmlWebpackPlugin.options.title
    vuecli3根据不同环境配置axios的baseUrl
    处理uniapp(同理小程序)开发中使用richtext富文本解析,图片未自适应宽度问题(图片显示不全)
    echart相关
    uniapp richtext图片自适应处理
    app云端打包失败 云端服务器返回错误
    [Violation] Added nonpassive event listener to a scrollblocking 'mousewheel' event.
    elinput textarea autosize 的坑
    iOS手机上input输入框无法输入bug
    ttf转eot
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4342074.html
Copyright © 2011-2022 走看看