设计模式——3.观察者模式

观察者模式(Observer)

观察者模式(Observer)简介:

定义一个一对多的依赖关系,让多个观察者对象监听某个主题对象,当主题对象的状态发生改变时,主题对象则通知所有的观察者对象,做出相应的反应,更新自己的状态等。

观察者模式结构图:

xEN2E0S.png

C++代码

Subject抽象类以及ConcreteSubject具体实现类:

//file: Subject.h#pragma once#include "Observer.h"#include <vector>using namespace std;class Subject{public:Subject();virtual ~Subject();void attach(Observer *pObserver);void detach(Observer *pObserver);void notify();virtual int getState() = 0;virtual void setState(int i) = 0;private:vector<Observer *> m_vtObj;};class ConcreteSubject : public Subject{public:ConcreteSubject();virtual ~ConcreteSubject();virtual int getState();virtual void setState(int i);private:int m_State;};
//file: Subject.cpp#include "pch.h"#include "Subject.h"//SubjectSubject::Subject() {}Subject::~Subject() {}void Subject::attach(Observer *pObserver){m_vtObj.push_back(pObserver);}void Subject::detach(Observer *pObserver){for (vector<Observer *>::iterator iter = m_vtObj.begin(); iter != m_vtObj.end(); iter++){if (*iter == pObserver){m_vtObj.erase(iter);return;}}}void Subject::notify(){for (vector<Observer *>::iterator iter = m_vtObj.begin(); iter != m_vtObj.end(); iter++){(*iter)->update(this);}}//ConcreteSubjectConcreteSubject::ConcreteSubject() {}ConcreteSubject::~ConcreteSubject() {}int ConcreteSubject::getState(){return m_State;}void ConcreteSubject::setState(int i){m_State = i;}

Observer抽象类以及ConcreteObserver具体观察者类:

//file: Observer.h#pragma once#include <string>using namespace std;class Subject;class Observer{public:Observer();virtual ~Observer();virtual void update(Subject *ps) = 0;};class ConcreteObserver : public Observer{public:ConcreteObserver(string pName);virtual ~ConcreteObserver();virtual void update(Subject *ps);private:string m_ObjName;int m_ObserverState;};
//file: Observer.cpp#include "pch.h"#include "Subject.h"#include "Observer.h"#include <iostream>using namespace std;//ObserverObserver::Observer() {}Observer::~Observer() {}//ConcreteOberverConcreteObserver::ConcreteObserver(string pName){m_ObjName = pName;}ConcreteObserver::~ConcreteObserver() {}void ConcreteObserver::update(Subject *ps){m_ObserverState = ps->getState();cout << "update observer " << m_ObjName << " to state " << m_ObserverState << " !" << endl;}

客户端代码:

//file: ObserverPattern.cpp : This file contains the 'main' function. Program execution begins and ends there.#include "pch.h"#include "Subject.h"int main(){Subject *sub = new ConcreteSubject();Observer *objA = new ConcreteObserver("A");Observer *objB = new ConcreteObserver("B");sub->attach(objA);sub->attach(objB);sub->setState(101);sub->notify();sub->detach(objB);sub->setState(102);sub->notify();delete sub;delete objA;delete objB;return 0;}

C#代码

观察者模式实现

Subject抽象类以及ConcreteSubject具体实现类:

public abstract class Subject{private List<Observer> objList = new List<Observer>();public int State { get; set; }public void Attach(Observer obj){objList.Add(obj);}public void Detach(Observer obj){objList.Remove(obj);}public void Notify(){foreach (Observer o in objList){o.Update(this);}}}public class ConcreteSubject : Subject{}

Observer抽象类以及ConcreteObserver具体观察者类:

public abstract class Observer{public abstract void Update(Subject sub);}public class ConcreteObserver : Observer{int m_State;string m_Name;public ConcreteObserver(string name){this.m_Name = name;}public override void Update(Subject sub){this.m_State = sub.State;Console.WriteLine("Update Observer {0} to state {1} .", m_Name, m_State);}}

客户端代码:

class Program{static void Main(string[] args){Subject sub = new ConcreteSubject();Observer objA = new ConcreteObserver("A");Observer objB = new ConcreteObserver("B");sub.Attach(objA);sub.Attach(objB);sub.State = 101;sub.Notify();sub.Detach(objB);sub.State = 102;sub.Notify();Console.ReadKey(false);}}

事件委托实现

抽象Subject类以及委托方法原型以及ConcreteSubject具体实现类:

public delegate void EventHander(Subject sub);public abstract class Subject{public int State { get; set; }public abstract void Notify();}public class ConcreteSubject : Subject{public event EventHander Update;public override void Notify(){if (Update != null)Update(this);}}

ConcreteObserverA/B具体实现类:

public class ConcreteObserverA{public int State { get; set; }public string Name { get; set; }public ConcreteObserverA(string name){Name = name;}public void FuncA(Subject sub){this.State = sub.State;Console.WriteLine("Update Observer {0} to state {1} .", Name, State);}public void FeatureA(Subject sub){this.State = sub.State;Console.WriteLine("Update Observer {0} to state {1} .", Name, State);}}public class ConcreteObserverB{public int State { get; set; }public string Name { get; set; }public ConcreteObserverB(string name){Name = name;}public void FuncB(Subject sub){this.State = sub.State;Console.WriteLine("Update Observer {0} to state {1} .", Name, State);}public void FeatureB(Subject sub){this.State = sub.State;Console.WriteLine("Update Observer {0} to state {1} .", Name, State);}}

客户端代码:

class Program{static void Main(string[] args){ConcreteSubject sub = new ConcreteSubject();ConcreteObserverA objA = new ConcreteObserverA("ConcreteObserverA");ConcreteObserverB objB = new ConcreteObserverB("ConcreteObserverB");sub.Update += objA.FuncA;sub.Update += objB.FeatureB;sub.State = 101;sub.Notify();sub.Update -= objB.FeatureB;sub.State = 102;sub.Notify();Console.ReadKey(false);}}

运行实例:

GLt9UES.png

REF

书籍:

设计模式与游戏开发、大话设计模式

GitHub:

https://github.com/me115/design_patterns

转载于:https://www.cnblogs.com/sylvan/p/9064150.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/251723.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 长按照片保存 工具类

2019独角兽企业重金招聘Python工程师标准>>> public class ImgUtils {public static void saveImageToGallery(Context context, Bitmap bmp) {final String[] items new String[] { "保存图片"};//图片转成Bitmap数组final Bitmap[] bitmap new Bitmap…

反爬机制

一.通过headers反爬虫&#xff1a; Basic Auth这是一种古老的、不安全的用户验证方式&#xff0c;一般会有用户授权的限制&#xff0c;会在headers的Autheration字段里要求加入用户名密码(明文)&#xff0c;如果验证失败则请求就会失败&#xff0c;现在这种认证方式正在被淘汰。…

knockout + easyui = koeasyui

在做后台管理系统的同学们&#xff0c;是否有用easyui的经历。虽然现在都是vue、ng、react的时代。但easyui&#xff08;也就是jquery为基础&#xff09;还是占有一席之地的。因为他对后端开发者太友好了&#xff0c;太熟悉不过了。要让一个后端开发者来理解vue或者是react的VN…

轻量社交APP系统ThinkSNS 简 权威发布 限时惠购

2019独角兽企业重金招聘Python工程师标准>>> 伴随国内外创业风潮、AI、区块链等互联网软件科技领域的高速发展&#xff0c;2019年&#xff0c;ThinkSNS软件品牌迎来十周年后的新纪元。作为下一个阶段的产品元年&#xff0c;官方于2019年5月正式发售轻量核心社交APP系…

linux下安装oracle sqlplus以及imp、exp工具

一、下载oracle 11g sqlplus软件 linux 64位操作系统&#xff0c;oracle安装包地址 http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html oracle-instantclient11.2-sqlplus-11.2.0.3.0-1.x86_64.rpm  oracle-instantclient11.2-basic-11.2.0.4.0-1.x86_6…

在operator =中要处理“自我赋值”

防止自我赋值很有必要 Widget w; w w; a[i] a[j]; //a[i]和a[j]实际上指向同一个元素 *pi *pj; //pi和pj实际上指向同一个元素 自我赋值的危害&#xff1a; Widget { private:Test *p; }; Widget &Widget::operator(const Widget &w) {delete p;p new int (*w.p);r…

新添加磁盘分区后,找不到新分区

问题&#xff1a;在Vcent中扩容磁盘容量&#xff0c;登录虚拟机fdisk /dev/sda分区后&#xff0c;找不到新分区。 lsblk或者 df -TH fdisk /dev/sda p 尝试解决办法&#xff1a; cd /sys/class/scsi_host/ ls echo "- - -" > /sys/class/scsi_host/host0/scan (中…

Linux一些指令

备忘。。 ~/.bashrc 环境变量文件 xshell5 与本机文件传输 rz接受 sz filename 传输 watch -n 2 nvidia-smi 监视gpu 状态wget 下载单个文件wget http://images.cocodataset.org/zips/train2014.zip给.sh文件添加x执行权限 比如以hello.sh文件为例&#xff0c;chmod ux hello…

C# 通过反射获取方法/类上的自定义特性

1.所有自定义属性都必须继承System.Attribute 2.自定义属性的类名称必须为 XXXXAttribute 即是已Attribute结尾 自定义属性QuickWebApi [AttributeUsage(AttributeTargets.Method, Inherited false, AllowMultiple true)]public class QuickWebApiAttribute: Attribute{publ…

Spring Cloud Zuul网关(快速搭建)

zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用。 在云平台上提供动态路由&#xff0c;监控&#xff0c;弹性&#xff0c;安全等边缘服务的框架。相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。主要功能是路由转发和过滤器。 Zuul可…

10.13 上午 考试

T1 直接二分就好了 #include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include <cstdlib> #include <algorithm> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) using namespace std;ll n; in…

前端安全之token

前端可以通过cookie以js的方式存取token&#xff0c;并且实现用户的登录登出以及token的超时操作&#xff0c;但这样做并不安全&#xff0c;无法避免跨站脚本的攻击&#xff0c;如果对项目的安全性要求比较高&#xff0c;应该在服务端开启http only为true&#xff0c;通过服务端…

gbk 转 UTF-8

iconv命令 gbk 转 UTF-8 -----linux gbk 转 UTF-8-------- iconv 用法 iconv -f "gbk" -t "utf-8" < infile > outfile 或者 piconv -f "gbk" -t "utf-8" < infile > outfile iconv -f utf-8 -t GBK 123456.txt 对传文件…

Mybatis中输入输出映射和动态Sql

一、输入映射我们通过配置parameterType的值来指定输入参数的类型&#xff0c;这些类型可以是简单数据类型、POJO、HashMap等数据类型1、简单类型2、POJO包装类型①这是单表查询的时候传入的POJO包装类型&#xff0c;即可以直接传入实体类&#xff0c;但是当多表查询的时候&…

css纯字母或者字母换行显示

white-space:normal; word-break:break-all;转载于:https://www.cnblogs.com/mmykdbc/p/7661009.html

javascript使用btoa和atob来进行Base64转码和解码

javascript中如何使用Base64转码 let str javascript;let btoaStr window.btoa(str); //转码结果 amF2YXNjcmlwdAconsole.log(btoaStr);console.log(window.atob(btoaStr)); //解码结果 javascriptBase64转码的对象只能是字符串, var str "China&#xff0c;中国"…

珠宝条码打印扫描解决方案

随着人们生活水平的逐步提高&#xff0c;珠宝消费日益增长&#xff0c;据统计&#xff0c;我国珠宝首饰零售规模超过7000亿&#xff0c;过去5年复合增长为15%&#xff0c;是规模增长最为迅速的可选消费品类之一。面对千亿级的消费市场&#xff0c;珠宝行业竞争激烈&#xff0c;…

课程作业1

1使用组合数公式利用n!来计算 a.设计思想 定义n和k&#xff0c;用递归函数表示出N!的阶乘结果&#xff0c;c(n,k)n!/(k!(n-k)!);调用函数求出c(n,k)的结果 b.源代码 package kecheng1; import java.util.Scanner; public class Test {public static void main(String[] args) {…

新手学Python推荐的四本书籍+2个资源网站

2019独角兽企业重金招聘Python工程师标准>>> 很多伙伴初学Python&#xff0c;会问到&#xff1a;有没有好的学习书籍推荐&#xff1f;有没有好的学习网站推荐&#xff1f; 针对这类伙伴的问题&#xff0c;小优给大家整理了学习Python的四本书籍2个资源网站&#xff…

【转】Linux系统编程---dup和dup2详解

正常的文件描述符&#xff1a; 在linux下&#xff0c;通过open打开以文件后&#xff0c;会返回一个文件描述符&#xff0c;文件描述符会指向一个文件表&#xff0c;文件表中的节点指针会指向节点表。看下图&#xff1a; 打开文件的内核数据结构 dup和dup2两个函数都可以用来复制…