网站建设合作合同模板下载,绿色资源网,品牌网站建设风格怎么确定,住房城乡住房和城乡建设部网站设计模式入门
本系列所有内容参考自《HeadFirst设计模式》。因为书中的代码是采用java语言写的#xff0c;博主这里用C语言改写。 这里采用讲故事的方式进行讲解。若有错误之处#xff0c;非常欢迎大家指导。 设计模式#xff1a;模式不是代码#xff0c;而针对设计问题的…设计模式入门
本系列所有内容参考自《HeadFirst设计模式》。因为书中的代码是采用java语言写的博主这里用C语言改写。 这里采用讲故事的方式进行讲解。若有错误之处非常欢迎大家指导。 设计模式模式不是代码而针对设计问题的通用解决方案被认为是历经验证的OO设计经验。设计模式告诉我们如何组织类和对象以解决某种问题。 如果你输出一个helloworld都想使用设计模式的话那可能真的就有问题了。
正文
提出问题
我们现在手头有一个气象检测应用。气象站接收湿度感应装置、温度感应装置、气压感应装置的数据然后我们有一个WeatherData对象它负责追踪来自气象站的数据并更新布告板显示目前天气状况给用户看。 如果我们要接手这个项目我们的工作就是建立一个应用利用WeatherData对象取得数据并更新三个布告板目前状况、气象统计和天气预报。三个布告板如下图所示
现有的WeatherData类源码如下
class WeatherData {float getTemperature(); //返回温度float getHumidity(); //返回湿度float getPressure(); //返回气压void measurementsChanged(){/*一旦气象测量更新此方法会被调用*///我们的代码加在这里}
};我们的工作是实现measurementsChanged()好让它更新目前状况、气象统计、天气预报的显示布告板。
我们目前知道的WeatherData类有三个方法可以取得三个测量值当新的数据来临时measurementsChanged()方法就会被调用(我们不在乎此方法是如何被调用的我们只在乎它被调用了)我们需要实现三个使用天气数据的布告板一旦WeatherData有新的测量这些布告必须马上更新。
一个我们可能想到的measurementsChanged()实现如下
class WeatherData {// 实例变量声明void measurementsChanged(){// 获取最新的测量值float temp getTemperature();float humidity getHumidity();float pressure getPressure();// 调用每个布告板更新显示currtenConditionsDisplay.update(temp, humidity, pressure); // 目前状况布告板更新statisticsDisplay.update(temp, humidity, pressure); // 气象统计布告板更新forecastDisplay.update(temp, humidity, pressure); // 天气预报布告板更新}
};但是这与一些软件设计原则发生了矛盾。上面代码中调用每个布告板更新显示函数是针对具体实现编程会导致我们以后在增加或删除布告板时必须修改程序三个接口都是update传入的参数也是一样的所以看起来更像是一个统一的接口。
那我们该如何解决这个问题呢观察者模式可以帮助我们很好地解决这个问题。
观察者模式
一个很简单的例子就是杂志订阅。 假设我们订阅了一款杂志每当这款杂志更新时它都会给我们送一份。这就是观察者模式杂志相当于“主题”我们相当于“观察者”当主题发生改变时就是通知“观察者”。这里要注意的一点是主题来增加或删除观察者。 还是杂志订阅这个问题我们想订阅杂志的时候杂志出版社便会将我们加到它们的订阅名单里我们不想订阅杂志时杂志出版社便会将我们从订阅名单里删除。
观察者模式观察者模式定义了对象之间的一对多依赖“一个主题”对“多个观察者”这样一来当一个对象改变状态时它的所有依赖者因为主题是真正拥有数据的人观察者是主题的依赖者都会收到通知并自动更新。
实现代码如下
#includeiostream
#includevectorusing namespace std;class Observer { // 观察者
public:virtual void update(float temp, float humidity, float pressure) 0;
};class Subject { // 抽象主题virtual void registerObserver(Observer *o)0;virtual void removeObserver(Observer *o)0;virtual void notifyObserver()0;
};class DisplayElement {virtual void display()0;
};class WeatherData : public Subject // 具象主题
{
private:vectorObserver* observers;float temperature;float humidity;float pressure;
public:void registerObserver(Observer *o) // 注册观察者{observers.push_back(o);}void removeObserver(Observer *o) // 取消观察者{auto it std::find(observers.begin(), observers.end(), o);if (it ! observers.end()){int index std::distance(observers.begin(), it);cout 索引是 index endl;;observers.erase(observers.begin() index);cout 成功删除元素 endl;}else{cout 未找到元素 endl;}}void notifyObserver() // 通知观察者{for (int i 0; i observers.size(); i){Observer *observer observers[i];observer-update(temperature, humidity, pressure);}}void measurementsChanged(){notifyObserver(); // 通知观察者}void setMeasurements(float temperature, float humidity, float pressure){this-temperature temperature; this-humidity humidity;this-pressure pressure;measurementsChanged();}
};class StatisticsDisplay : public Observer, public DisplayElement // 观察者
{
private:float temperature;float humidity;WeatherData *weatherData;
public:StatisticsDisplay(WeatherData *weather){weatherData weather;weatherData-registerObserver(this); //主题注册观察者}void remove(){weatherData-removeObserver(this); // 主题取消观察者}void update(float temperature, float humidity, float pressure){this-temperature temperature;this-humidity humidity;display();}void display(){cout statisticsDisplay: temperature F degress and humidity % humidity endl;}
};class ForecastDisplay : public Observer, public DisplayElement // 观察者
{
private:float temperature;float humidity;WeatherData *weatherData;
public:ForecastDisplay(WeatherData *weather){weatherData weather;weatherData-registerObserver(this); //主题注册观察者}void remove(){weatherData-removeObserver(this); // 主题取消观察者}void update(float temperature, float humidity, float pressure){this-temperature temperature;this-humidity humidity;display();}void display(){cout ForecastDisplay: temperature F degress and humidity % humidity endl;}
};class CurrentConditionsDisplay : public Observer, public DisplayElement // 观察者
{
private:float temperature;float humidity;WeatherData *weatherData;
public:CurrentConditionsDisplay(WeatherData *weather){weatherData weather;weatherData-registerObserver(this); //主题注册观察者}void remove(){weatherData-removeObserver(this); // 主题取消观察者}void update(float temperature, float humidity, float pressure){this-temperature temperature;this-humidity humidity;display();}void display(){cout CurrentConditionsDisplay: temperature F degress and humidity % humidity endl;}
};
int main()
{WeatherData *weatherData new WeatherData; // 定义一个主题对象即可CurrentConditionsDisplay currentDisplay(weatherData); // 第一个观察者StatisticsDisplay statisDisplay(weatherData); // 第二个观察者ForecastDisplay foreDisplay(weatherData); // 第三个观察者weatherData-setMeasurements(80, 65, 30.4); // 主题信息发生变更currentDisplay.remove(); // 该观察者取消对主题的订阅weatherData-setMeasurements(40, 25, 15.4);foreDisplay.remove(); // 该观察者取消对主题的订阅weatherData-setMeasurements(15.5, 26, 34);return 0;
}以上就是使用C实现观察者模式的全部代码。
设计原则
找出程序中会变化的方面然后将其和固定不变的方面相分离。 在观察中模式中会改变的是主题的状态以及观察者的数目和类型。用这个模式你可以改变依赖于主题状态的对象却不必改变主题。针对接口编程不针对实现编程。 主题与观察者都是用接口观察者利用主题的接口向主题注册而主题利用观察者接口通知观察者。这样可以让两者之间运作正常又同时具有松耦合的优点。
观察者模式较为重要在很多软件框架和软件设计中都可以看到它的身影所以大家可以根据代码仔细体会它的思想。工作的那几个月在公司的软件里看到过观察者模式但是没有自己动手实现只是明白它的意思。今天自己动手实现了一下感悟又深了一些。 文章转载自: http://www.morning.xlmpj.cn.gov.cn.xlmpj.cn http://www.morning.tfcwj.cn.gov.cn.tfcwj.cn http://www.morning.kcnjz.cn.gov.cn.kcnjz.cn http://www.morning.clpfd.cn.gov.cn.clpfd.cn http://www.morning.jrbyz.cn.gov.cn.jrbyz.cn http://www.morning.cmdfh.cn.gov.cn.cmdfh.cn http://www.morning.jkbqs.cn.gov.cn.jkbqs.cn http://www.morning.fchkc.cn.gov.cn.fchkc.cn http://www.morning.huxinzuche.cn.gov.cn.huxinzuche.cn http://www.morning.ghkgl.cn.gov.cn.ghkgl.cn http://www.morning.mmynk.cn.gov.cn.mmynk.cn http://www.morning.xrlwr.cn.gov.cn.xrlwr.cn http://www.morning.llthz.cn.gov.cn.llthz.cn http://www.morning.fkyqt.cn.gov.cn.fkyqt.cn http://www.morning.qdxtj.cn.gov.cn.qdxtj.cn http://www.morning.nmkbl.cn.gov.cn.nmkbl.cn http://www.morning.xrksf.cn.gov.cn.xrksf.cn http://www.morning.prgrh.cn.gov.cn.prgrh.cn http://www.morning.lxjxl.cn.gov.cn.lxjxl.cn http://www.morning.kybpj.cn.gov.cn.kybpj.cn http://www.morning.lrylj.cn.gov.cn.lrylj.cn http://www.morning.cniedu.com.gov.cn.cniedu.com http://www.morning.knqck.cn.gov.cn.knqck.cn http://www.morning.sgpnz.cn.gov.cn.sgpnz.cn http://www.morning.mldrd.cn.gov.cn.mldrd.cn http://www.morning.bwfsn.cn.gov.cn.bwfsn.cn http://www.morning.fpryg.cn.gov.cn.fpryg.cn http://www.morning.rylr.cn.gov.cn.rylr.cn http://www.morning.horihe.com.gov.cn.horihe.com http://www.morning.zdtfr.cn.gov.cn.zdtfr.cn http://www.morning.tqlhn.cn.gov.cn.tqlhn.cn http://www.morning.mxcgf.cn.gov.cn.mxcgf.cn http://www.morning.pjxw.cn.gov.cn.pjxw.cn http://www.morning.sfnr.cn.gov.cn.sfnr.cn http://www.morning.gkfwp.cn.gov.cn.gkfwp.cn http://www.morning.llcgz.cn.gov.cn.llcgz.cn http://www.morning.bpxmw.cn.gov.cn.bpxmw.cn http://www.morning.stfdh.cn.gov.cn.stfdh.cn http://www.morning.wfqcs.cn.gov.cn.wfqcs.cn http://www.morning.wqkzf.cn.gov.cn.wqkzf.cn http://www.morning.sogou66.cn.gov.cn.sogou66.cn http://www.morning.wnkjb.cn.gov.cn.wnkjb.cn http://www.morning.hwhnx.cn.gov.cn.hwhnx.cn http://www.morning.ygkb.cn.gov.cn.ygkb.cn http://www.morning.wptdg.cn.gov.cn.wptdg.cn http://www.morning.dhnqt.cn.gov.cn.dhnqt.cn http://www.morning.mlnby.cn.gov.cn.mlnby.cn http://www.morning.sskns.cn.gov.cn.sskns.cn http://www.morning.xhjjs.cn.gov.cn.xhjjs.cn http://www.morning.jkpnm.cn.gov.cn.jkpnm.cn http://www.morning.bwgrd.cn.gov.cn.bwgrd.cn http://www.morning.fkdts.cn.gov.cn.fkdts.cn http://www.morning.brkc.cn.gov.cn.brkc.cn http://www.morning.tlnkz.cn.gov.cn.tlnkz.cn http://www.morning.sffwz.cn.gov.cn.sffwz.cn http://www.morning.tndhm.cn.gov.cn.tndhm.cn http://www.morning.bhbxd.cn.gov.cn.bhbxd.cn http://www.morning.xxwl1.com.gov.cn.xxwl1.com http://www.morning.sprbs.cn.gov.cn.sprbs.cn http://www.morning.jbblf.cn.gov.cn.jbblf.cn http://www.morning.lzdbb.cn.gov.cn.lzdbb.cn http://www.morning.kwblwbl.cn.gov.cn.kwblwbl.cn http://www.morning.rglzy.cn.gov.cn.rglzy.cn http://www.morning.fmqw.cn.gov.cn.fmqw.cn http://www.morning.dmzfz.cn.gov.cn.dmzfz.cn http://www.morning.jzfxk.cn.gov.cn.jzfxk.cn http://www.morning.jcnmy.cn.gov.cn.jcnmy.cn http://www.morning.drkk.cn.gov.cn.drkk.cn http://www.morning.xfxqj.cn.gov.cn.xfxqj.cn http://www.morning.rgnp.cn.gov.cn.rgnp.cn http://www.morning.bxhch.cn.gov.cn.bxhch.cn http://www.morning.tbcfj.cn.gov.cn.tbcfj.cn http://www.morning.kdgcx.cn.gov.cn.kdgcx.cn http://www.morning.mxhgy.cn.gov.cn.mxhgy.cn http://www.morning.wmnpm.cn.gov.cn.wmnpm.cn http://www.morning.0small.cn.gov.cn.0small.cn http://www.morning.hffjj.cn.gov.cn.hffjj.cn http://www.morning.snrhg.cn.gov.cn.snrhg.cn http://www.morning.ljfjm.cn.gov.cn.ljfjm.cn http://www.morning.qmbgb.cn.gov.cn.qmbgb.cn