当前位置: 首页 > news >正文

做网站顶部图片长度是多少广州百度网站推广

做网站顶部图片长度是多少,广州百度网站推广,北京医疗网站建设,一般纳税人注册公司流程接上篇,本篇将会介绍C设计模式中的Observer 观察者模式,和前2篇模板方法Template Method及Strategy 策略模式一样,仍属于“组件协作”模式。Observer 在某些领域也叫做 Event 。 文章目录 1. 动机( Motivation)2. 代码…

接上篇,本篇将会介绍C++设计模式中的Observer 观察者模式,和前2篇模板方法Template MethodStrategy 策略模式一样,仍属于“组件协作”模式。Observer 在某些领域也叫做 Event

文章目录

  • 1. 动机( Motivation)
  • 2. 代码演示Observer 观察者模式
    • 2.1 常用处理方法
      • 2.1.1 MainForm1.cpp
      • 2.1.2 FileSplitter1.cpp
    • 2.2 Observer 观察者模式
      • 2.2.1 FileSplitter2.cpp
      • 2.2.2 MainForm2.cpp
  • 3. 模式定义
  • 4. 结构( Structure)
  • 5. 要点总结
  • 6. 其他参考博文

1. 动机( Motivation)

  • 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。
  • 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。

2. 代码演示Observer 观察者模式

假设以下的场景需求:做一个文件的分割器。虽然现在文件分割器使用的比较少,但是在之前是使用很广泛的,因为当时还是一个3寸盘的时代,经常需要将大文件拷走,就需要将大的文件分隔为多个文件拷贝携带走。
下面是一个伪码,只会展示主干部分。

2.1 常用处理方法

首先需要一个界面,mainform就是一个windows界面,父类为Form,主要有两个控件txtFilePath(大文件的全路径)和txtFileNumber(希望分割的文件个数)(此处给出的是后期修改后的代码)。
Button1_Click函数中收集用户输入的2个参数信息,传递给FileSplitter splitter,splitter调用split()

2.1.1 MainForm1.cpp

class MainForm : public Form
{TextBox* txtFilePath;TextBox* txtFileNumber;ProgressBar* progressBar;public:void Button1_Click(){string filePath = txtFilePath->getText();int number = atoi(txtFileNumber->getText().c_str());FileSplitter splitter(filePath, number, progressBar);splitter.split();}
};

2.1.2 FileSplitter1.cpp

FileSplitter中放文件变量,m_filePath负责文件路径,m_fileNumber负责文件个数,通过构造器给这些成员变量赋值。

class FileSplitter
{string m_filePath;int m_fileNumber;ProgressBar* m_progressBar; //具体的通知控件public:FileSplitter(const string& filePath, int fileNumber, ProgressBar* progressBar) :m_filePath(filePath), m_fileNumber(fileNumber),m_progressBar(progressBar){}//伪代码void split(){//1.读取大文件//2.分批次向小文件中写入for (int i = 0; i < m_fileNumber; i++){//...float progressValue = m_fileNumber;progressValue = (i + 1) / progressValue;m_progressBar->setValue(progressValue);}}
};

上面代码就实现了在Button1_Click时的文件的分割功能。

假设有一个用户需求,希望进行文件分割时,如果文件特别大,需要分割很长时间,这个时候需要提供一个进度条,进行进度展示。
最朴素的想法就是在界面中提供一个ProgressBar* progressBar,并且在FileSplitter中提供方法,代码结果如上。

但是上面的实现方式是否违背了某一设计原则呢?即违背依赖倒置原则(DIP)

  • 高层模块(稳定)不应该依赖于低层模块(变化),二者都应该依赖于抽象(稳定) 。
  • 抽象(稳定)不应该依赖于实现细节(变化) ,实现细节应该依赖于抽象(稳定)。

需要注意:一般我们所讲的依赖就是编译式依赖(除非明确提出运行式依赖),例如A依赖B也就是A编译时B必须存在

上面实现中,FileSplitter中ProgressBar* progressBar就产生了编译式依赖,这个ProgressBar* progressBar就是依赖倒置原则(DIP)中讲到的实现细节(为什么说它是实现细节呢?因为进度的显示方式可能会有变化,这就带了实现细节层面变更的困扰)

2.2 Observer 观察者模式

需要对上面的代码进行重构分析,可以看到ProgressBar* progressBar实际扮演的是一个通知,可以使用一种抽象的方式来表达一个通知而不需要具体的控件表达通知。

2.2.1 FileSplitter2.cpp

class IProgress{
public:virtual void DoProgress(float value)=0;virtual ~IProgress(){}
};class FileSplitter
{string m_filePath;int m_fileNumber;List<IProgress*>  m_iprogressList; // 抽象通知机制,支持多个观察者,观察的就是分割的进度public:FileSplitter(const string& filePath, int fileNumber) :m_filePath(filePath), m_fileNumber(fileNumber){}void split(){//1.读取大文件//2.分批次向小文件中写入for (int i = 0; i < m_fileNumber; i++){//...float progressValue = m_fileNumber;progressValue = (i + 1) / progressValue;onProgress(progressValue);//发送通知}}//增加观察者void addIProgress(IProgress* iprogress){m_iprogressList.push_back(iprogress);}//移除观察者void removeIProgress(IProgress* iprogress){m_iprogressList.remove(iprogress);}protected://更新进度通知virtual void onProgress(float value){List<IProgress*>::iterator itor=m_iprogressList.begin();while (itor != m_iprogressList.end() )(*itor)->DoProgress(value); //更新进度条itor++;}}
};

2.2.2 MainForm2.cpp

C++中支持多继承,一般不推荐使用多继承的方式,可能会导致复杂的耦合性问题,但是C++推荐一种多继承的形式就是一个是主继承类(如public Form),其他是接口或者抽象基类(public IProgress)。

class MainForm : public Form, public IProgress
{TextBox* txtFilePath;TextBox* txtFileNumber;ProgressBar* progressBar;public:void Button1_Click(){string filePath = txtFilePath->getText();int number = atoi(txtFileNumber->getText().c_str());ConsoleNotifier cn;FileSplitter splitter(filePath, number);splitter.addIProgress(this); //订阅通知splitter.addIProgress(&cn)//订阅通知splitter.split();splitter.removeIProgress(this);}virtual void DoProgress(float value){progressBar->setValue(value);}
};class ConsoleNotifier : public IProgress {
public:virtual void DoProgress(float value){cout << ".";}
};

3. 模式定义

定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。 ——《设计模式》 GoF

4. 结构( Structure)

在这里插入图片描述

上图是《设计模式》GoF中定义的Observer 观察者模式的设计结构。结合上面的代码看图中最重要的是看其中稳定和变化部分,也就是下图中红框和蓝框框选的部分。

在这里插入图片描述

GoF的设计模式中建议将addIProgress,removeIProgress,onProgress放到父类中,让FileSplitter去继承父类。而此处我们的框架是将其直接写到FileSplitter中,不管是否提出Subject都是观察者模式,本博文重构的代码就没有提出Subject,其实是将Subject和ConcreteSubject合二为一。

个人结合结构对以上代码的理解:

IProgress的两个基类MainForm和ConsoleNotifier(虚函数多态,ConcreteObserver),通过FileSplitter splitter(ConcreteSubject)的addIProgress()方法都订阅了通知,在进行split()时,遍历ConcreteObserver,利用迭代器循环执行各自具体的DoProgress()。这样就实现多个ConcreteObserver观察同一ConcreteSubject,并且多个ConcreteObserver会根据ConcreteSubject变化执行各自的方法

5. 要点总结

  • 使用面向对象的抽象, Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。

代码中随便添加观察者,但是addIProgress,removeIProgress,onProgress保持复用性不变

  • 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。

onProgress(progressValue);//发送通知不知道谁是观察者,针对通知机制抽象通知

  • 观察者自己决定是否需要订阅通知,目标对象对此一无所知。

splitter.addIProgress(this); //订阅通知splitter.addIProgress(&cn); //订阅通知

  • Observer模式是基于事件的UI框架中非常常用的设计模式,也是MVC模式的一个重要组成部分。

Observer 观察者模式与模板方法Template Method是一样的常用。例如java中的listener就是观察者模式、C#中的Event也是观察者模式

Observer模式需要多思考,最关键的是抽象的通知依赖关系。

6. 其他参考博文

Observer 观察者模式

http://www.ds6.com.cn/news/41794.html

相关文章:

  • 用家里的路由器做网站专门培训seo的网站
  • 免费做思维导图的网站请简述网络营销的特点
  • 龙岗网站制作效果网络推广优化招聘
  • dw做网站 如何设置转动seo关键词排名如何
  • 三合一网站怎么做巨量关键词搜索查询
  • 网站转移空间以后ip会变化吗百度竞价广告推广
  • 如何降低网站的权重网站推广的方法有哪些
  • 建立个人网站视频教程职业培训机构排名
  • 镇江网站制作推客平台
  • 做土建资料有什么网站没站长统计网站大全
  • 建设工程合同纠纷司法解释seo关键词排名优化方法
  • 网页设计代码怎么写关键词如何优化排名
  • 房产网站排行榜东莞疫情最新通知
  • 合肥做网站加盟手机网页制作
  • 工信部网站icp备案查询网站建设与管理
  • 网站流量真难做营销推广app
  • 网站怎么做百度认证微信推广怎么弄
  • wordpress主题网seo排名优化哪家好
  • wordpress 翻译插件如何优化搜索引擎
  • 非自己的网站如何做二次跳转优化排名推广关键词
  • 深圳公司网站培训网站推荐
  • 网站开发数据库动态管理百度关键词排名十大排名
  • 创客贴设计网站官网app拉新项目推广代理
  • app开发公司招聘seo关键词如何设置
  • 做网站如何月入过万搜索引擎提交入口网址
  • 做网站费用可以看为广告费用吗搜索引擎快速优化排名
  • 跨境独立网站怎么建设网络营销是做什么的工作
  • 漳州微网站建设哪家好b2b采购平台
  • 与做网站有关的参考文献爱站网关键词长尾挖掘
  • 公众号开发者密码忘了怎么办温州企业网站排名优化