本文参考文献::GeekBand课堂内容,授课老师:李建忠

:网络资料: http://blog.csdn.net/hguisu/article/details/7556625

本文仅作为自己的学习笔记,不代表权威,因为是初学,有错误烦请大家指正,谢谢。

1、什么是观察者模式,应用场所有哪些?

观察者模式(有时又被称为发布-订阅Subscribe>模式、模型-视图View>模式、源-收听者Listener>模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

--------360百科定义

2、结构

3、通过代码分析,模式的组成

如上图所示:观察者模式包含如下角色:

目标(Subject): 目标知道它的观察者。可以有任意多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。

//目标: 目标知道它的观察者。可以有任意多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。
Class Form
{
public:
virtual void Attach(FileSpliter* observer);//注册观察者
virtual void Detach(FileSpliter* observer);//释放观察者
virtual void Notify();//通知所有注册的观察者 interface SplObserver
{
virtual void Update(Form *) = ; //观察者进行更新状态
};
}

具体目标(ConcreteSubject): 将有关状态存入各ConcreteObserver对象。

//具体目标(MainForm):  将有关状态存入各MainForm对象

class MainForm : public Form
{
public:
/**
* 释放观察者
*/
virtual void Attach(FileSpliter* observer)
{
_observers->Append(observer);
}
/**
* 注册观察者
*/
virtual void Detach(FileSpliter* observer) //
{
_observers->Remove(observer);
}; /**
* 通知所有观察者
*/
virtual void Notify()
{
for obs in _observers //遍历
{
if (observers->getState() == this->State)
{
obs->Update(this);
}
}
}; //设置状态
void Button1_Click(bool State)
{
this->State = State; //状态改变
Notify();
} protected:
MainForm() {}
private:
TestBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar;
List<FileSpliter*> *_observers;
};

观察者(Observer): 为那些在目标发生改变时需获得通知的对象定义一个更新接口。当它的状态发生改变时, 向它的各个观察者发出通知。

/**
* 抽象观查者
*
*/
class FileSplitter
{
public: virtual void Split() = ;
virtual void Update(MainForm*) = ;
virtual ~FileSplitter() {} protected:
virtual void onProgress(float value)
{ List<FileSpliter*>::iterator itor = _observers.begin(); while (itor != _observers.end())
(*itor)->DisplayProgress(value); //更新进度条
itor++;
}
void DisplayProgress(int value)
{
progressBar->setValue(value);
}
}
private:
string filePath;
int fileNumber;
bool State;
};

具体观察者(ConcreteObserver): 维护一个指向ConcreteSubject对象的引用。存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。

//具体观察者1
class Spliter1 : public FileSplitter
{ public:
Spliter1(MainForm* mf)
{
_subject = mf;
_subject->State = true;
_subject->Attach(this);
}
virtual ~Spliter1()
{
_subject->State = false
_subject->Detach(this);
}
virtual void Update(MainForm *mf)
{
_subject->State = true;
if (mf == _subject)
{
Split()
}
}
virtual void Split()
{
//1、打开文件filePath
//2、把文件分割成fileNumber个文件
//3、DisplayProgress重载,以1的方式更新进度(如进度条)
DisplayProgress(value);
} private:
bool State;
MainForm* _subject;
}; //具体观察者2
class Spliter2 : public FileSplitter
{ public:
Spliter2(MainForm* mf)
{
_subject = mf;
_subject->State = true;
_subject->Attach(this);
}
virtual ~Spliter2()
{
_subject->State = false;
_subject->Detach(this);
}
virtual void Update(MainForm *mf)
{
_subject->State = true;
if (mf == _subject) {
Split()
}
}
virtual void Split()
{
//1、打开文件filePath
//2、把文件分割成fileNumber个文件
//3、DisplayProgress重载,以2的方式更新进度(如控制台...)
DisplayProgress(value); private:
MainForm* _subject;
bool State;
}; //具体观察者3
class Spliter3 : public FileSplitter
{ public:
Spliter3(MainForm* mf)
{
_subject = mf;
_subject->State = true;
_subject->Attach(this);
}
virtual ~Spliter3()
{
_subject->State = false;
_subject->Detach(this);
}
virtual void Update(MainForm *mf)
{
_subject->State = true;
if (mf == _subject)
{
Split()
}
}
virtual void Split()
{
//1、打开文件filePath
//2、把文件分割成fileNumber个文件
//3、DisplayProgress重载,以3的方式更新进度(如百分比)
DisplayProgress(value);
}
private:
MainForm* _subject;
bool State;
};

main函数

nt main()
{
MainForm* mf = new MainForm();
Spliter1* sp1 = new Spliter1(mf);
Spliter2* sp2 = new Spliter2(mf);
Spliter3* sp3 = new Spliter3(mf);
return ;
}

4、总结

1、通过Observer模式,把一对多对象之间的通知依赖关系的变得更为松散,大大地提高了程序的可维护性和可扩展性,也很好的符合了开放-封闭原则。

2、观察者模式符合开闭原则,开闭原则是指一个软件实体应该对扩展开放,对修改关闭。也就是说软件实体必须是在不被修改的情况下被扩展。模板方法模式意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用。

3、

模板方法模式与对象的封装性,面向对象的三大特性:继承,封装,多态。
  对象有内部状态和外部的行为。封装是为了信息隐藏,通过封装来维护对象内部数据的完整性。使得外部对象不能够直接访问一个对象的内部状态,而必须通过恰当的方法才能访问。在C++中,采用给对象属性和方法赋予指定的修改符(public、protected、private)来达到封装的目的,使得数据不被外部对象恶意的访问及方法不被错误调用导造成破坏对象的封装性。

[GeekBand] 设计模式之观察者模式学习笔记的更多相关文章

  1. [GeekBand] 设计模式——工厂模式学习笔记

     本文参考文献:GeekBand课堂内容,授课老师:李建忠 :大话设计模式 其余的模式方法请自行查看Geekband相关课程,在此不累述. 这周的课题是: 针对DrawingSystem中的基类Sha ...

  2. Ruby设计模式-观察者模式学习笔记

    observer.rb #!/bin/env ruby # encoding: utf-8 require 'observer' class CriminalMovement include Obse ...

  3. c#观察者模式学习笔记(1)

    c#中的观察者是一种逻辑上很重要的角色,在服务端,观察者是服务端的通讯员,它将事件与业务紧密的结合,彼此又能按照逻辑进行分离. 实现方法为: (1)声明事件的委托原型,作为事件订阅的回调. (2)使用 ...

  4. 《Head.First设计模式》的学习笔记(9)--外观模式

    意图:为子系统中的一组接口提供一个一致的界面,Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 结构: 例子: 假设你有一套杀手级的家庭影院系统,内含DVD播放器.投影仪.自 ...

  5. .NET CORE学习笔记系列(2)——依赖注入【2】基于IoC的设计模式

    原文:https://www.cnblogs.com/artech/p/net-core-di-02.html 正如我们在<控制反转>提到过的,很多人将IoC理解为一种“面向对象的设计模式 ...

  6. 设计模式学习笔记——java中常用的设计模式

    单例设计模式(Singleton Pattern) 观察者模式(Observer Pattern) 工厂模式(Factory Pattern) 策略模式(Strategy Pattern) 适配器模式 ...

  7. 7 种 Javascript 常用设计模式学习笔记

    7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...

  8. 【Head-First设计模式】C#版-学习笔记-开篇及文章目录

    原文地址:[Head-First设计模式]C#版-学习笔记-开篇及文章目录 最近一年断断续续的在看技术书,但是回想看的内容,就忘了书上讲的是什么东西了,为了记住那些看过的东西,最好的办法就是敲代码验证 ...

  9. [学习笔记]设计模式之Abstract Factory

    写在前面 为方便读者,本文已添加至索引: 设计模式 学习笔记索引 在上篇笔记Builder设计模式中,时の魔导士祭出了自己的WorldCreator.尽管它因此能创造出一个有山有树有房子的世界,但是白 ...

随机推荐

  1. angular反向代理

    第一步:根目录新建 proxy.conf.json target:就是代理的服务器地址. 接口地址必须是http://localhost:8081/api开头 { "/api":{ ...

  2. HDU1969 Pie(二分搜索)

    题目大意是要办生日Party,有n个馅饼,有f个朋友.接下来是n个馅饼的半径.然后是分馅饼了, 注意咯自己也要,大家都要一样大,形状没什么要求,但都要是一整块的那种,也就是说不能从两个饼中 各割一小块 ...

  3. 硬件——STM32,ADC篇

    未完,待续...... 也就是stm32f10X系列的adc采集出来的结果是12位的 stm32f10X系列有两个16位adc 关于程序的编写方法:一般  “某某.c文件”:都是用来设置“某某”的一些 ...

  4. common daemon

    http://zdsyouxiang.iteye.com/blog/1940202 http://commons.apache.org/proper/commons-daemon/procrun.ht ...

  5. linux查找keyword在php出现的次数

    查找CleverCode在当前文件夹以及子文件夹,全部的php出现大于0的次数. # find -type f -name '*.php' | xargs grep CleverCode ./*.ph ...

  6. 每日技术总结:Toast组件,eslint,white-space,animate,$emit

    1.一个优雅的提示是网站必不可少的. 请参考:vue2.0 自定义 提示框(Toast)组件 2.ESLint使用总结 (1)在.eslintrc.js里关闭某条规则, '规则名': 'off'或0 ...

  7. 【例题 6-10 UVA - 699】The Falling Leaves

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 递归模拟就好. [代码] #include <bits/stdc++.h> using namespace std; c ...

  8. ios日期比较

    +(int)compareDate:(NSDate *)date1 date:(NSDate *)date2 { NSDateFormatter *dateFormatter = [[NSDateFo ...

  9. 移动端 h5 开发相关内容总结——JavaScript 篇

    1.改变页面标题的内容 有时候我们开发 h5页面的时候须要动态的去更新title 的名字,这个时候使用 document.title='改动后的名字'; 就行解决我们的问题. 或者使用 //当前fir ...

  10. 安装hadoop2.6.0伪分布式环境 分类: A1_HADOOP 2015-04-27 18:59 409人阅读 评论(0) 收藏

    集群环境搭建请见:http://blog.csdn.net/jediael_lu/article/details/45145767 一.环境准备 1.安装linux.jdk 2.下载hadoop2.6 ...