作者: 西魏陶渊明
博客: https://blog.springlearn.cn/

天下代码一大抄, 抄来抄去有提高, 看你会抄不会抄!

一、设计模式

设计模式一般分为三类:创建型模式、结构型模式、行为型模式。

  • 创建型模式:对象实例化的模式,创建型模式用于解耦对象的实例化过程。
  • 结构型模式:把类或对象结合在一起形成一个更大的结构。
  • 行为型模式:类和对象如何交互,及划分责任和算法

1.1 创建型模式

创建型模式简单来说就是用来创建对象的。一共有五种:单例模式、建造者模式、工厂方法模式、抽象工厂模式、原型模式。

  1. 单例模式 :确保某一个类只有一个实例,并且提供一个全局访问点。
  2. 建造者模式 : 用来创建复杂的复合对象。
  3. 工厂方法模式 :让子类来决定要创建哪个对象。
  4. 抽象工厂模式 :创建多个产品族中的产品对象。
  5. 原型模式 :通过复制原型来创建新对象。

1.2 结构型模式

结构型模式主要是用于处理类或者对象的组合。一共有七种:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

  1. 代理模式 :控制客户端对对象的访问。
  2. 组合模式 :将整体与局部(树形结构)进行递归组合,让客户端能够以一种的方式对其进行处理。
  3. 适配器模式 :将原来不兼容的两个类融合在一起。
  4. 装饰者模式 :为对象添加新功能。
  5. 享元模式 :使用对象池来减少重复对象的创建。
  6. 外观模式 :对外提供一个统一的接口用来访问子系统。
  7. 桥接模式 :将两个能够独立变化的部分分离开来。

1.3 行为型模式

行为型模式主要是描述类或者对象是怎样交互和怎样分配职责的。一共有十一种:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

  1. 策略模式 :封装不同的算法,算法之间能互相替换。
  2. 状态模式 :根据不同的状态做出不同的行为。
  3. 责任链模式 :将事件沿着链去处理。
  4. 观察者模式 :状态发生改变时通知观察者,一对多的关系。
  5. 模板方法模式 :定义一套流程模板,根据需要实现模板中的操作。
  6. 迭代器模式 :提供一种方法顺序访问一个聚合对象中的各个元素。
  7. 备忘录模式 :保存对象的状态,在需要时进行恢复。
  8. 访问者模式 :稳定数据结构中,定义新的操作行为。
  9. 中介者模式 :将网状结构转变为星型结构,所有行为都通过中介。
  10. 解释器模式 :定义语法,并对其进行解释。
  11. 命令模式 :将请求封装成命令,并记录下来,能够撤销与重做。

总结
虽然设计模式是个好东西,能够给我们带来各种好处,比如降低对象之间的耦合,增加程序的可复用性、可扩展性、可维护性等等。
但是我们也不应该滥用设计模式,设计模式在一定程序上会增加系统的复杂性。我们在写码时应该评估好各方面,避免过度设计。

二、六大原则

2.1 开闭原则

定义

一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。

问题场景

在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。

解决方案

当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。

表达

用抽象构建框架,用实现扩展细节因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节,我们用从抽象派生的实现类来进行扩展,当软件需要发生变化时,我们只需要根据需求重新派生一个实现类来扩展就可以了。当然前提是我们的抽象要合理,要对需求的变更有前瞻性和预见性才行。

分析

就是对扩展开放,对修改关闭, 里式替换原则理论支持了这个一说法,及子类要能替换父类,这样子类就可以在父类的基础上,扩展

2.2 单一职责原则

定义

一个类只负责一项职责。

问题场景

类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。

解决方案

遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。

表达

不要让责任扩散

分析

一个类,指责要单一,避免如果有多种职责,修改一个职责的时候,误触到其他职责的问题

2.3 里氏替换原则

定义

所有引用基类的地方必须能透明地使用其子类的对象。

问题场景

有一功能P由类A完成,现在要扩展P,其中P由类A的子类B完成,则子类在完成的同时,可能会导致原来功能故障

解决方案

当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。

表达

使用继承的时候,不要随便修改父类中已经实现的方法

分析

子类要能替换父类

2.4 依赖倒置原则

定义

高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

问题场景

类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

解决方案

将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率。

表达

如果A依赖B,现在要改为依赖C,如果直接修改A有风险,可以让A去依赖一个接口,BC都实现这个接口,也就是策略模式

分析

白话就是说,要根据接口或者抽象去设计,不要依赖于细节,eg.项目中要换数据库,不用重新写底层的数据库代码. 就是使用了hibernate一样,替换方言就好了,因为hibernate是根据接口设计的,不同数据库有不同的实现,可以直接使用. eg2: 我生病了要去买药,如果A药铺,没有我就用B药铺买. 因为他们都是药铺,都有一样的功能,可以友好的替换

2.5 接口隔离原则

定义

客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。

问题场景

类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法

解决方案

将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则

表达

防止去实现不需要的接口方法,可以按接口拆分,避免臃肿。

分析

白话,接口要最小化,功能更细分. 目的是:不需要的功能,就不要去实现

比如有些接口可能里面什么方法都没有,其存在的意义,就是为了其实现类拥有特殊的功能.所以我们也要怕我们的接口里面没有方法,就怀疑了它存在的价值

public class RandomAccess{
}

当实现RandomAccess的类比如ArrayList就具有随机访问的能力,而没有实现该接口的,就只能去迭代访问。

我们可以简单的看下Collections下的binarySearch方法的源码

    public static <T>int binarySearch(List<? extends Comparable<? super T>> list, T key) {if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)return Collections.indexedBinarySearch(list, key);elsereturn Collections.iteratorBinarySearch(list, key);}

2.6 迪米特法则

定义

一个对象应该对其他对象保持最少的了解。

问题场景

类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

解决方案

尽量降低类与类之间的耦合。

表达

尽量降低类与类之间的耦合。

分析

降低类与类之间直接交互,能隐藏的属性就可以隐藏. eg. 修电脑,去IT部门,之前一直找小张,现在小张走了,还需要重新认识小李. 迪米特法则,就是直接找IT主管,让主管派人修. 主管就是接口,调用接口的方法,底层具体是小张还是小李,我们不用去管

这里其实也强调了接口的重要性!

书读百遍其义自见 - 六大原则 23种设计模式相关推荐

  1. 学习心得,书读百遍其义自见!

    书读百遍其义自见! 在小学课文上第一次见这句话的时候,还觉得没道理,尤其是像语文课本里的文言文,我当时觉得读一百遍,也还是那样,似懂非懂混混沌沌. 直到长大后,近些日子学习vue,我发现这句格言真是有 ...

  2. 书读百遍其义自见-------2017--05--27读书篇

    什么是 HTML? HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言 (Hyper Text Markup Language) HTML 不是一种编程语言,而是一种标记语言 (ma ...

  3. 书读百遍其义自现-学习fireflow体会

    fireflow的理路太清晰了 "书读百遍其义自现",仔细阅读了5遍<原理.设计和应用>的pdf格式文档介绍后,发现"非也"的思路太清晰了.一个良好 ...

  4. 书读百遍,其意自现 --- 意境与语境的融合

    书读百遍,其意自现. 书不会因为背下来了,就能够达到其意自现. 背下来的内容,也只有反复一遍一遍在脑中过电影,才会达到遍数的增加,理解的趋近. 当真正达到"书读百遍,其意自现",而 ...

  5. 品读鸿蒙HDF架构系列 | 读码百遍其义自见

    不同读码人都会有各自读代码的习惯和切入点,HDF是Harmony Driver Fundation的缩写,实际上便是鸿蒙形成的一套管理设备驱动的框架模型,也被称为"驱动子系统".本 ...

  6. 京东CTO的笔记23种设计模式和5大读源码方法...!网友:这次稳了...

    大家都知道源码框架有23个设计模式,但是我们大多停留在概念层面,真实开发中很少应用到,也不知道如何落地!!!那有没有办法解决了? 我整理了 Mybatis 和 Spring 源码中使用了大量的设计模式 ...

  7. 23天读懂23种设计模式:原型模式(创建型)

    点击上方 蓝字 关注我们 创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建.组合和表示方式. 原型模式目的:用原型实例指定创建对象的种类,并且通过拷贝这些原型创 ...

  8. 追MM与设计模式(23种设计模式巧妙解析,趣味理解)--微信公众号(程序员共读)

    创建型模式 1.FACTORY-追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说"来四个鸡翅"就 ...

  9. 读书百遍,真的能其义自见吗?

    从小我们就接受 仙人教诲:读书百遍,其义自见的真理....?请看我们可爱的百度文库的教诲: 中国有一句古话:"少年不读书,老来空白首."世间万物,皆属身外,惟有书能够渗心入骨地擦拭 ...

最新文章

  1. python logsumexp示例
  2. centos7在分区上建立文件系统和挂载
  3. linux系统指令学习
  4. filter-mutate过滤插件
  5. 分析一周后终于明白,为什么说不注重数据的企业会被时代淘汰?
  6. Jmeter+Ant+Jenkins接口自动化持续集成环境搭建(Linux)
  7. java反编译源码_java反编译获取源码
  8. Spring Boot 导出Excel表格
  9. SQL Server 中的执行计划和SQL Server Profiler
  10. linux建sybase设备,linux sybase 安装全过程(写给初学者)
  11. Android studio 0.5.0 注意事项
  12. 应用程序委托协议栈发送消息
  13. 如何在windows下把硬盘格式化成EXT3格式?
  14. 企业微信服务号注册认证支付接入流程
  15. KICAD——手动生成嘉立创可识别的BOM和POS文件
  16. mac升级mysql_Mac如何升级Mysql数据库 Mac升级Mysql数据库步骤
  17. 【文末有惊喜!】iOS日历攻略:提醒调休并过滤法定节假日
  18. SC8701 120W DC TO DC 电源模块的设计
  19. java开发中常用的算法_总结一下项目开发过程中常用的到的一些加密算法。
  20. 软件接口趣事:业务和技术人员眼中五彩斑斓的黑

热门文章

  1. 剑指offer系列——剑指 Offer 04. 二维数组中的查找(C语言)
  2. 凌晨一点肝文⭐1920×1080⭐高清必应壁纸爬取,只为爬虫小白们入门!!!
  3. overleaf怎么打单引号
  4. 国内MBA项目提前批面试剩余场次:浙大iMBA今天最后一批截止
  5. 追风筝的人 第七章
  6. Android中常见的4种线程池的理解(转)
  7. 2022-2028全球与中国紫外线发生器市场现状及未来发展趋势
  8. STM32F103详细频率测量过程
  9. python pptx怎么复制ppt_python pptx复制指定页的ppt教程
  10. 腾讯音乐回应网易云音乐诉其不正当竞争;“月薪三千能买什么样的手机”上热搜 投票第一竟是苹果?《计算机世界》停工停业|极客头条