目录

  • 设计模式的设计原则
  • 模板设计模式
  • 观察者模式
  • 策略设计模式

设计模式的设计原则

依赖倒置:高层模块不应该依赖低层模块,两者都应该依赖抽象; 抽象不应该依赖具体实现,具体实现应该依赖于抽象; (记住依赖抽象就好了)。
开放封闭:一个类应该对扩展(组合和继承)开放,对修改关闭;
面向接口:不将变量类型声明为某个特定的具体类,而是声明为某个接口;
客户程序无需获知对象的具体类型,只需要知道对象所具有的接口;
减少系统中各部分的依赖关系,从而实现“高内聚、松耦合”的类型设计方案;(记住只暴露接口,只调用接口)。
封装变化点:将稳定点和变化点分离,扩展修改变化点;让稳定点和变化点的实现层次分离;
单一职责:一个类应该仅有一个引起它变化的原因; (就是变化点不要太多)。
里氏替换:子类型必须能够替换掉它的父类型;主要出现在子类覆盖父类实现,原来使用父类型的程序可能出现错误;覆盖了父类方法却没> 有实现父类方法的职责;( 就是子类可以覆盖父类的方法,但是得保证父类必要的功能)。
接口隔离:不应该强迫客户依赖于它们不用的方法;
一般用于处理一个类拥有比较多的接口,而这些接口涉及到很多职责;
客户端不应该依赖它不需要的接口。
一个类对另一个类的依赖应该建立在最小的接口上。
组合优于继承:继承耦合度高,组合耦合度低;

模板设计模式

定义一个操作中的算法的骨架 ,而将一些步骤延迟到子类中。 Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

通过一个动物园表演的例子来说明该设计模式:

某个品牌动物园,有一套固定的表演流程,但是其中有若干个表演子流程可创新替换,以尝试迭代更新表演流程;

#include <iostream>
using namespace std;
// 开闭原则
class ZooShow {public:void Show() {//一套固定的表演流程,show0->show1->show2->show3// 加了一个特定的设定:show1表演流程没有超时的话,进行一个中场游戏环节;如果超时,直接入下一个子表演流程if (Show0())PlayGame();Show1();Show2();Show3();}
private:void PlayGame() {cout << "after Show0, then play game" << endl;}// 通过protected对其他用户关闭,但是子类开放的
protected://判断是否超时的变量bool expired;virtual bool Show0() {cout << "show0" << endl;//如果没有超时,返回true,超时了返回falseif (! expired) {return true;}return false;}virtual void Show1() {cout << "show1" << endl;}//抽象接口virtual void Show2() = 0;virtual void Show3() {cout << "show3" << endl;}
};
// 框架
// 模板方法模式
class NewShow1 : public ZooShow {protected://替换了原来的表演1virtual void Show1(){cout << "Newshow1 show1" << endl;}//实现了抽象接口virtual void Show2(){cout << "Newshow1 show2" << endl;}
};
class NewShow2 : public ZooShow {protected://替换了表演0,但是仍要实现原来的特定功能(里氏替换)virtual bool Show0() {cout << "NewShow2 show0" << endl;if (! expired) { // 里氏替换return true;}return false;}virtual void Show2(){cout << "Newshow2 show2" << endl;}
};
int main () {ZooShow *zs1 = new NewShow1; // 晚绑定ZooShow *zs2 = new NewShow2;zs1->Show();zs2->Show();return 0;
}

总结下模板设计模式的特点
子类可以复写父类子流程,使父类的骨架流程丰富;
父类中的抽象方法由子类实现,属于一种反向控制流程;
父类protected 保护子类需要复写的子流程,这样子类的子流程只能父类来调用;
通过固定算法骨架来约束子类的行为;

观察者模式

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

通过一个气象站的例子来说明:

气象站发布气象资料给数据中心,数据中心经过处理,将气象信息更新到两个不同的显示终端(A 、B和C);

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
// 定义一个抽象的基类,定义了显示温度的接口
class IDisplay {public:virtual void Show(float temperature) = 0;virtual ~IDisplay() {}
};
//不同的显示终端具体实现显示接口
class DisplayA : public IDisplay {public:virtual void Show(float temperature) {cout << "DisplayA Show temperature : " << temperature << endl;}
private:void jianyi();
};
class DisplayB : public IDisplay{public:virtual void Show(float temperature) {cout << "DisplayB Show temperature : " << temperature  << endl;}
};
class DisplayC : public IDisplay{public:virtual void Show(float temperature) {cout << "DisplayC Show temperature : " << temperature  << endl;}
};
// 应对稳定点,抽象
// 应对变化点,扩展(继承和组合)
//定义一个数据中心,负责注册目标显示终端、删除显示终端、通知终端显示功能
class DataCenter {public://注册显示终端void Attach(IDisplay * ob) {obs.push_back(ob);}//删除显示终端void Detach(IDisplay * ob) {obs.remove(ob);}//通知显示功能void Notify(int temper_num) {float temper = SetTemperature(temper_num);for (auto iter : obs) {iter->Show(temper);}}// 接口隔离
private:float SetTemperature(int temper) {return temper;}std::list<IDisplay*> obs;
};
int main() {DataCenter *center = new DataCenter;// ... 某个模块IDisplay *da = new DisplayA();center->Attach(da);IDisplay *db = new DisplayB();center->Attach(db);IDisplay *dc = new DisplayC();center->Attach(dc);center->Notify(36);//-----center->Detach(db);center->Notify(37);//....return 0;
}

总结观察者模式的特点

观察者模式使得我们可以独立地改变目标与观察者,从而使二者之间的关系松耦合;
观察者自己决定是否订阅通知,目标对象并不关注谁订阅了;
观察者不要依赖通知顺序,目标对象也不知道通知顺序;

策略设计模式

定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用它的客户程序而变化。

总结就是将对象和接口方法解耦,不同的算法可以以相同的形式调用,还可以节省实例化对象的开销。

用一个节假日销售价格的例子说明:

某商场节假日有固定促销活动,为了加大促销力度,现提升不同节假日促销活动规格;

#include <iostream>using namespace std;// 稳定点:使用抽象去解决它
// 变化点:可以通过扩展(继承和组合)去解决它
//策略基类,定义一个接口
class ProStategy {public:virtual void CalcPro(int ctx) = 0;
};
// 策略子类,使用不同的方法实现
class VAC_QiXi : public ProStategy {public:virtual void CalcPro(int ctx){cout << "QiXi : " << ctx << endl;}
};
// cpp
class VAC_Wuyi : public ProStategy {public:virtual void CalcPro(int ctx){cout << "Wuyi : " << ctx << endl;}
};
// cpp
class VAC_GuoQing : public ProStategy {public:virtual void CalcPro(int ctx){cout << "GuoQing : " << ctx << endl;}
};
//调度类
class Context {public:Context(ProStategy *sss) : s(sss){}~Context(){}void CalcPromotion(int ctx){s->CalcPro(ctx);}
private:ProStategy *s;
};int main () {ProStategy *s = new VAC_QiXi();Context *p = new Context(s);p->CalcPromotion(1);s = new VAC_Wuyi();p = new Context(s);p->CalcPromotion(2);s = new VAC_GuoQing();p = new Context(s);p->CalcPromotion(3);return 0;
}

策略设计模式的特点

策略模式提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换;
策略模式消除了条件判断语句;也就是在解耦合;
分离算法,选择实现;

创建型设计模式:模板设计模式/观察者设计模式/策略设计模式相关推荐

  1. java 设计模式 示例_Java中的策略设计模式-示例教程

    java 设计模式 示例 策略模式是行为设计模式之一 . 当我们对一个特定的任务有多种算法并且客户决定在运行时使用的实际实现时,将使用策略模式. 策略模式也称为策略模式 . 我们定义了多种算法,并让客 ...

  2. 从零开始学习Java设计模式 | 创建型模式篇:原型模式

    在本讲,我们来学习一下创建型模式里面的第四个设计模式,即原型模式. 概述 原型模式就是指用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象. 这段话读起来有点绕,是不是? ...

  3. 【设计模式】(八)--创建型模式--建造者模式

    [设计模式](八)–创建型模式–建造者模式 建造者模式 [设计模式](八)--创建型模式--建造者模式 建造者模式定义 构造者模式的优点 构造者模式的使用场景 构造者模式和工厂模式区别 构造者模式简单 ...

  4. 从零开始学习Java设计模式 | 创建型模式篇:抽象工厂模式

    在本讲,我们来学习一下创建型模式里面的第三个设计模式,即抽象工厂模式. 前言 前面介绍的工厂方法模式中考虑的是一类产品,如畜牧场只养动物.电视机厂只生产电视机(不生产空调.冰箱等其它的电器).计算机学 ...

  5. 设计模式(2)——创建型——工厂相关:简单工厂(Simple factory),工厂方法(Factory method),抽象工厂(Abstract factory)

    概要 这里试图描述23个设计模式中的两个工厂(Factory)相关的设计模式:工厂方法(Factorymethod),抽象工厂(Abstract factory). 注意点: 这两个都属于创建型设计模 ...

  6. 设计模式:策略设计模式

    一.什么是策略设计模式 1.1 策略设计模式定义 策略设计模式(Strategy Pattern)是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以让算法 ...

  7. 工厂设计模式和策略设计模式_设计模式:策略

    工厂设计模式和策略设计模式 这次我想谈谈策略设计模式 . 通过这种方式,我开始撰写有关行为设计模式的文章. 这种模式表示对象之间的某些交互模式,以使代码更灵活且组织得更好.此方法的最本质点是对象之间的 ...

  8. 设计模式学习笔记——观察者(Observer)模式

    设计模式学习笔记--观察者(Observer)模式 @(设计模式)[设计模式, 观察者模式, Observer] 设计模式学习笔记观察者Observer模式 基本介绍 观察者案例 类图 实现代码 Ob ...

  9. 设计模式学习笔记七:常用设计模式原则总结

    前面学习了一部分创建型模式,发现了一个比设计模式更重要的东西:设计模式原则.对于设计模式来说,为什么这个模式要这样解决这个问题,而另一个模式要那样,它们背后都遵循的就是永恒的设计原则.可以说,设计原则 ...

最新文章

  1. 基于Flink SQL构建流批一体实时数仓
  2. 有的OUTLOOK不能自动加载归档ARCHIVE邮件的问题
  3. win10创建新的计算机用户名和密码忘了,Win10 2004中要使用本计算机用户必须输入用户名和密码选项不见了如何恢复?...
  4. 【若依(ruoyi)】弹框图标 / layer 图标
  5. RabbitMQ 简介和使用
  6. 1445.32php,nginx实现mysql的负载均衡
  7. 使用Powershell批量获取Exchange 2013邮箱用户容量使用量
  8. 【资源下载】旷视研究院张祥雨valse2019报告PPT——高效轻量级深度模型的研究与实践
  9. thread.sleep会释放锁吗_面试 LockSupport.park()会释放锁资源吗?
  10. HIVE存储(四)ORCFile
  11. Atitit 前端重要概念和趋势总结 大前端 目录 1. 大前端 1 2. 三个层面上的大前端 1 2.1. 大前端与NodeJS与前后端分离 1 2.2. 微信Web 1 2.3. React
  12. 100---Python绘制圆锥体
  13. 有关图像生成的函数 .
  14. Python数据分析案例-分别使用时间序列ARIMA、SARIMAX模型与Auto ARIMA预测国内汽车月销量
  15. Java支付宝当面付demo实例配置沙箱
  16. MAC OS部署 TOMCATJ2EE项目
  17. break跳出两个嵌套的for循环
  18. 解决ultraedit-32卸载后文件关联问题
  19. 计算机专业英语影印版单词,计算机专业英语词汇词组翻译(08影印版)
  20. 算法题中关于去重问题的解法(不同的值)

热门文章

  1. 【STM32G431RBTx】备战蓝桥杯嵌入式→基本模块→ADC
  2. Qt 如何自适应不同分辨率
  3. python如何另存文件_python如何保存文本文件
  4. Python ——保存字典到文件
  5. 关于真机调试的N种姿势
  6. 【休闲益智】【HTML】我的数独我做主
  7. jar包制作Docker镜像
  8. “今日头条杯”首届湖北省大学程序设计竞赛(网络同步赛)C题:Who killed Cock Robin
  9. Linux同步时间chrony替换NTP简单好用
  10. 视频教程-跟着王进老师学开发Python篇:基础入门案例讲解-Python