03 - 侯捷 - C++设计模式笔记

1 设计模式简介

设计模式目的是提高复用性,抽象可以用一种统一的方法进行处理,不用分而治之,
只有父类写了虚析构函数,以后子类通过多态释放时,子类的虚析构函数才会被调用到,否则调用不到子类的析构函数,
绝大多数的继承都应该用public继承,
在这里插入图片描述
需要多态性,虽然放的类型是shape,但之后可能希望指向的是Line类型或Rect类型,需要用指针Shape* ,如果不用指针,就会导致对象切割,如果传一个Line,会把L切割成一个小对象,所以里面不能放Shape,要放Shape指针才能表现多态性,
在这里插入图片描述
因为之前放的是指针,所以push_back里要new一个对象,里面不能放一个栈对象,需要放一个堆对象的指针,在MainForm析构的时候要负责释放shapevector里面存的一系列堆对象的指针,
在这里插入图片描述

2 面向对象设计原则

依赖倒置原则:隔离变化,依赖倒置原则与针对接口编程相辅相成,违背一个就会违背另一个原则,
开放封闭原则:以扩展的方式应对需求的改变
Liskov原则:所有需要父类的地方,子类对象都可以传过去使用,
接口隔离原则:如果只是子类应用的方法,就protected,如果是本类使用就private,真正有必要的情况下才public暴露出去, 客户程序就是使用它的程序,
接口标准化
毕昇是松耦合设计大师,从雕版印刷到活字印刷,紧耦合,字和版贴在一起无法分离,而活字印刷是字和版分离了,但是二者之间的关系靠字模的接口来定义,是松耦合,

3 Template Method模板方法

在这里插入图片描述
子类应用程序开发人员创建出application对象,所以pLib实际上是一个多态指针,即声明类型是library,但实际类型是application,所以调用虚函数的时候会按照动态绑定的规则绑定,此处调用的Run不是虚函数,但是Run里面调用的某些函数如Step2,Step4是虚函数,所以会去找子类application里的实现来调用,
在这里插入图片描述
在这里插入图片描述

基类的虚构函数应该写成虚函数,因为在delete 的时候如果基类的虚构函数没有写成虚函数,那么Library* pLib = new Application()就调用不到子类的析构函数,

在C++实现多态里,有一个关于 析构函数的重写问题:基类中的析构函数如果是虚函数,那么派生类的析构函数就重写了基类的析构函数。这里他们的函数名不相同,看起来违背了重写的规则,但实际上编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor。那么为什么要把基类中的析构函数写成虚函数呢?

原因:当基类指针指向派生类的时候,若基类析构函数不声明为虚函数,在析构时,只会调用基类而不会调用派生类的析构函数,从而导致内存泄露。

在这里插入图片描述
程序库写的比程序早,一个晚出现的东西调用一个早出现的东西就是早绑定,一个早出现的东西调用一个晚出现的东西就是晚绑定,
面向对象中,延迟到子类,指的就是定义一个虚函数,让子类去实现这个虚函数,或者让子类去override重写这个虚函数,延迟到子类就是支持子类来变化,
虽然用了面向对象语言,但是设计思维可能是结构化的,
在这里插入图片描述

改良后的设计模式就是模板方法Template Method,Template Method的模板就是样板,Run就是样板,即主流程放在父类里,稳定的代码要写成非虚函数如Run,而支持变化的要写成虚函数如step2,Template Method设计模式适用的前提条件是Run必须是稳定的, 即必须有一个稳定的算法骨架可以被重用,
假定所有东西都是稳定的或者都是不稳定的时候,设计模式也没有意义,设计模式最大的作用,就是在变化和稳定中间,寻找隔离点,然后来分离他们,从而来管理变化,
把类图中变化的部分和稳定的部分标记,
面向对象的扩展就是继承+虚函数,继承+多态,子类继承父类,子类对父类的虚函数进行复写override,
c语言的函数指针也可以晚绑定,但是没有虚函数的抽象性,虚函数就是虚函数表上挂了一个函数指针,

4 策略模式

在这里插入图片描述
更改的部分违反了开闭原则,应该尽可能用扩展的方式解决,
在这里插入图片描述
c++里,任何基类都需要加一个虚析构函数,即要把自己的析构函数声明为虚函数,否则多态的delete会出问题,把之前的一个个算法变成一个个TaxStrategy的子类,
在这里插入图片描述
TaxStrategy是多态指针,要放指针不能放对象,放对象就没有多态性了,指针要支持指向不同TaxStrategy的子类,
一般实现多态的变量都要用指针,通过工厂模式创建,不需要new一个实际的对象,而是用外界传来的一个StrategyFactory,这个StrategyFactory调用NewStrategy,由工厂决定返回某个TaxStrategy的具体的子类的对象,在工厂内部返回的还是堆对象,在SaleOrder类的析构里要负责删除它
在这里插入图片描述
设计模式里的复用性是指编译单位,二进制层面的复用性, 不是片段级的复用,salesOrder是稳定的,
在这里插入图片描述
context是salesorder,strategy是taxstrategy, 下面的三个都是可变的即各个国家tax,上面两个即基类和salesorder是稳定的,
代码里出现if else,且条件可能会变比如一周有七天不可能变,此时稳定不变的可以用ifelse,其余变化的用strategy模式,往往就是strategy模式需要出现的特征,if else是结构化设计分而治之思想,应该用面向对象抽象解决,

在这里插入图片描述
很多if else不会用到,但是被迫装载到cpu的高级缓存里,占用缓存,而strategy模式在运行时, 加载哪个,执行的时候就直接调用那个代码,

5.观察者模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值