设计模式读后感

 

今天终于读完了设计模式,特书此文以留念

感想

昔日,郑某老师一直推荐设计模式,但是因为那个时候还没有打算好以后就靠开发吃饭了,因此一直没去看。反而是看了很多c++。最近,在暑假的实习中,我在为公司的祖传代码debug时,发现公司代码规模太大,添加新功能过于麻烦,debug也不容易。加上我之前用go写的主控开始没有设计好,后面吃了很多苦头,web模块与计划模块紧耦合,修bug难度,谁试谁知道。遂读设计模式。

不过我个人不是很推荐四人帮的这本(虽然我看的是这本),举得例子过于晦涩难懂,而且看到第二章会感觉脑子出问题,不过书是好书啦,也确实是经典。

我个人感觉像是设计模式这种每一种模式都是从实际例子中提炼出来的,应该吸收其思想,反而是模式本身不必记得太住,知道怎么做就可以了。有一种张三丰教张无忌太极的感觉2333。单看,不吸收思想硬套的话,反而会小工程过度设计,不够自然。

设计模式的思想

  1. 将变化的与不变的分离
  2. 将类之间的联系泛化从而解耦
  3. 真正的低效是人的低效,所以可以一定程度减少性能来优化维护性

  1. 泛化以实现高拓展
  2. 封装以方便切换
  3. 将类中无关的部分封装
  4. 将独立变化的部分独立封装

自己随便总结的23333

各个模式的总结

创建型模式

抽象工厂

将成系列的类的创建封装并抽象为接口,方便在需要大量创建对象时,方便成系列的调换。或在客户端仅需考虑抽象商品的类型,无需考虑需要具体的哪一个,以实现客户端与具体类型的解耦。

生成器

将一个极其复杂类的装配过程封装为生成器,以将变化的装配步骤,与不变的子部件生成相分离,也实现了构建类过程与构建子类过程相解耦。一般用于装配高度内联部件顺序联系可能发生变化,但是子部件在生成时相对不变的大型类。

工厂模式

父类仅保留一个创建对象的虚方法(接口),待子类具体实现。可以将具体实例化哪一个推迟到运行时。

原型

创建需要被实例化的对象的原型,再拷贝并修改拷贝体,来实现真正创建对象。

单件(单例

将对象的新建与计数器相内联,保证只能创建一个类的方法

原文未涉及多线程情况,加锁即可

结构性模式

适配器

你有一个接口/类型,和一个功能差不多但是不适合这个接口的类,在此类外套一层来适配接口/类型。

桥接

将独立变化的部分相分离并封装,使他们独立变化,避免产生过多的类。如果一个父类的若干子类中,有共通部分,可以将共通部分作为父类的成员,以实现变化的抽象和暂时不变的实现解耦分离。也就是将抽象与实现,通过将抽象部分转换为接口来实现互相分离,使抽象部分调用的实现可以独立变化。通过封装分离抽象可以减少一级继承。

组合

通过对对象进行抽象,将对象之间的包含关系泛化为可以包含任意多个从而转换为树形,已提供一致性并将包含者与被包含者相互解耦。

装饰

将希望动态地添加的类功能抽象为装饰器类,一层层包裹原对象,以实现在不继承的情况下修改功能。

外观

将子系统的对外接口统一归纳到一个总的外观类中,以实现外部与内部解耦。

享元

将粒度较小的轻量化类的状态从内部剥离到外部,以实现不包含任何与任何调用者相关联的属性,来将这个对象进行共享,从而减少额外创建过多类。可以减少一切皆对象带来的消耗。此模式将对象中不变的内部状态,与变化的外部状态相分离而减少对象数量。

代理

当一个类关联一个大型资源时,可以在需要时才加载资源,但是实现与资源本身无关的操作,以方便用户对资源进行与资源本身无关的操作。

行为模式

职责链

将请求的发送与接收解耦为接收者可以有多个,且形成一条链,实现发送的泛化解耦。

命令

将请求封装为一个对象,以实现对于请求的复杂操作或运行时绑定。

解释器

若某事物拥有一定的规则性,假定要对某事物进行操作。可以先对去进行分析形成树,将事物分解为部分,在对整棵树使用此操作。拥有较好的拓展性。

迭代器

创建一个类,并绑定另一个数据结构,来实现在不暴露其内部结构的情况下对可以对数据结构内部数据进行迭代。

中介者

发送方和请求方不直接发送请求,而是先发送给中介对象再由中介对象转发来实现发送方和接收方解耦。

备忘录

即对类内所有状态的封装备份。在需要存储内部状态的情况下但是不想暴露内部结构,可以建立一个友元类,通过拷贝内部属性实现备忘。

状态

当类的大部分行为与其一个状态相绑定时,可以将类的行为封装为一个接口。这个接口作为内部成员,并根据状态在运行时进行动态绑定具体的行为类。

策略

当类内某段代码是一个成系列算法簇的一员,而且你希望可以更好的拓展和动态替换,可以将其封装为对象。这个对象作为类的一个成员。

模板方法

当一些类仅有少量不同。可以将类的骨干部分定义为父类,其中不同的部分定义为一个虚函数,通过某个函数调用钩在父类上,使用子类继承父类并覆盖这个虚函数来实现完整的功能。

最常见的继承方式

访问者

当有一棵树,你希望对所有的节点进行多种操作,而且操作的种类会发生变化而节点的种类不会。与其把这种操作写为节点类的成员函数,不如把它单独抽象为一个类,并在节点类中只有一个接受这种类的访问方法。当你要对某节点进行操作时,仅需把操作对应的访问器作为节点类访问方法的参数即可。这样可以将节点与操作解耦。