设计模式总篇:从为什么需要原则到实际落地(附知识图谱)
聊聊为什么需求原则
我们一切人都看过科幻电影,都看到过未来场景中人类和机器人和平相处的场景

为了让具有自主智能
的机器人不失控,人类为机器人制定了三大规则:
-
第一规则:机器人不得损害人类单个,t @ L m c或许目睹人类单个将遭受危险而袖手不论 -
第二规则:机器人w t U Q 1 # I有必要服从人给予它的指令,当该指令与第一4 r h q k规则冲突时例外 -
第三规则:机器人在不违反第一、第二规则的情况下要尽或许维护自己的生计
当然有时也会出现下面的情况,机器人和人类初步互为阵营,各自= h 5 , S T ) g H为敌

但是各自为敌的情况出现,一般都是机器( y E R a . + = /人觉醒了自我意识,不再恪守三大规则
从逻辑学来说,假设机器人完全恪守三大规则及其衍生7 j y P , M k 1 g的条约
,那么机器人就可以和人类和平相处,当然也会有意外产生。
写代码为什么需求规划原则3 6 % f x S
和机器人的三大规则
相仿,几十年的编程阅历,让几代人` X e .总结出来了一些代码规划上的规则
,这` h _ . N C (就是规划方式的七大原则
我们遵循七大原则,必定会写出最完美的代码吗?
答案当然是不必定,终究没有人能确保自己可以完全遵循七大原则,一起个人的编程才能也会起到决定性要素。
那我们为什么还要恪守?
我自己想到的一句名言(往后或许可以成为名言~)
向着最好的方向去U y x Q ? I + d z极力,总不会是最差的结果。
七大原则详解
开闭原则 ★★★★★
软件实体对扩展是敞开的,但对批改是关闭的,即在不批改一个软件实体的根底上去扩展其功用
例如:
以战略方式为例,当我们新增4 W 4 N I W ;一种战略的Q 2 X时分,只需求结束战略顶层& # p (接口,在调用的时指向新的战略即可
针对这一条原则,在b 2 l 6 x / G J E结束难度上要比单一职责更难,在编码期间,我们需求充沛} k h考虑未来的拓宽性,标准接口,依托抽象,这样才能在需求拓宽的时分,十分便当的结束其效果
最佳! t Q 实践案例:【一起学系列】之模板方法:写SSO我只E j 1 C x Z )需5分钟
阐明:在接入第三方SSO时,假设需求新增接入方,根据文中的案例,只需结束固定接口,即可典雅的结束相应需求
依托倒置原则 ★★★★★
要针对抽象层编程,而不要针对具体类编程
例如:3 @ O
以适配器方式为例,将一个类的接口转换成客户期望的其他一个接口,以此结束的条件就是代码中所依托的都是抽象的,因为只有依托抽象,才能在代码运转期间改动其实体,运用多态
结束需求的效果
针对该条原则,其实有必定编程阅历的人必定会在无形中注意到,而且了解规划方式的话,会发现一切触及接口和结束的规划方式都2 ? A 5会遵循这一条原则j L M
最佳实践案例:【一起学系列】之模板方法:写SSO我只需5分钟
阐明:和上一条原则的侧重点不同,在SSO中必定有其固定的流程,如登录-获取Token-获取用户信息-解析-退出等等,在代码的编写阶段,需求我们定义出接Y b d ) } Q口/抽象类,f 3 N h A 4 Q ?然后依托于抽象层,终究改动具体类,以此达到无缝切换的效果
组成复用原则 ★★★★☆
总9 = # ? v % 5 & t结2 e r h n j一句话就是:多用组合,少用继承
例如:
以单例方式和署理方式为例,它们都是该方式的最佳实践者,单例方式是把不同? W r o 1 Q o W c的战略接口经过组合
的方法嵌入到Context
类中,如代码所示:
public abstract class Duck {
/**
* 翱翔c t 6 l行为是动态的,或许会Z 7 $变的,因而抽成多个接口的组合,而不是让Duck类继承
*/
Flc ) QyBehavior flyBehavior;
/*U Y 3 C / f*
* 每个鸭子的叫声不同,抽象成接口
*/
QuackBehavior quackBehavior;
}
同理,署理方式也是如此,这儿就考虑到一个问题,为1 G @ 5 k y什么要多用组合而非继承?
其实仍是Java中单继承引发的问题,一起继承的语义
过于苛刻,因而更多的时分建议善用组合
最佳实a K ( | ] h _ 践案例:【一起学系列】之战略方式:很多鸭子啊
阐明:战略方式就是组成复用原则的最佳实践者,没有之一
单一职责原则 ★★★9 . s * M [ L★☆
类的职责要单一,不能将太多的职责! ~ % M W l 8 t i放在一个类中
例如:
在代码规划中某种场景或许存在多种不同的情况,很或许就把代码混在一起了,这时我们运用情况方式
进行规划,把各种情况对应的结束细节都用类的等级独自区分,即表现了单一职则原则
针对这一条原则,其实绝大多数人在c { 4 w规划之初都会考虑到,但问题就在于随着工作中人员职责的^ * *交叉,很有或许会损坏他人规划的开始目的,为了便当,让一个类具有五花八门的功用
最佳实践案例:【一起学系列】之情况方式:你听过“流程”方式吗?
阐明:在情况方式中,每一种情况的处理都是独立的一个类,每个类只需求处理本身的核心逻辑,完美表现了单一职责原则
里氏代换原则 ★9 f S ? r★★★☆
在软件体系中,一个可以承受基类方针的当地必定可以承受一个子类方针
当运用继承时,遵循_ j N : V ? Y ] 0里氏替换原则。类B继承类A时,除增加新的方法结束新增功用外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法
继承包括这样一层意义:父类中凡是已经结束好的方法(相关于抽象方法而言),实践上是在设定一系列的标准和契约,尽管它不强制要求一切的子类有必要遵循这些契约,但是假设子类对这些非抽象方法任意批改,就会对整个继承体系构成损坏。而4 { y 8 ? y [里氏替换原则就是表达了这一层意义
例如:
我们都用n U H f 1 J 5 /过ArrayList
,有谁看过 forEach
方法的源码?
// ArrayList 的父级接口 Iterable 定义的默许方法
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (; ` - 6 Y T t : this) {
action.accept(t);
}
}
ArrayLi? y 8st
重写的方法:
@Override
public void forEach(Consumer<? super E> action) {
Objects+ # n 1 P V.requireNonNull(action);
final int expectedModCount = modCount;
@Suppr6 ^ v } U Q bessWarnings("unchecked")
final E[] elementData = (E[D / E H 7]) this.elementData;
final int size = this.size;
for (int i=0; modCount ==h Z 3 * expectedModCount && i < size; i++) {
action.accept([ 0 t : * ,elementData[Z ; q }i]);L D q D H |
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
我们看到,ArrayList
的重写仅仅针对数组这种结构优化了功用,其目的性和Iterable
接口中的完全共同,因而这_ 5 : ?种方法的重写不会引起任何问题,反而可以提高功率,我们需求学习这样的方法
迪米特原则 ★★★☆☆
一个方针应该对其他方针y ) N a %保持最少的了解,又叫:最少知道原则
例如:
在代码规划场景中,某一个类的调用都会固定运C 4 G H X M W用三个方法,是否可以考虑把三个方法抽取出来,供给一个公共的对外方法?这种思路就是外观方式
,n w p u G c 7 x (外R @ i { b g ( b观方式也是迪米特原则的最佳实践
最佳实践案例:【一起学系列】之适配器形– d q X : q 8 D y式:还有外观方式呢
阐明:运用a i W 3外观方式
构建一致的对外方法,屏蔽其内部结束,这样一旦内部结束需求更改,完全不会影响调用方,你Get了吗?
接口阻隔原则 ★★☆☆☆
运用多个专门的接口来取代一个一致的接口
这个方式其实也很好n . 2 q J了解,比如我们定义了接口A,接口B结束& 0 H y c I 4了接口A,接口C结束了接口B,基类D其实只需求接口N % M ~C的方法,但是此时不得不结束一切的方法
其实构成这个根本原因:对接口的抽象y R d 3 ] = Z,规划出现了误差
终究看过JDK源码或许Spring源码的同学,可以经常发现某一个接口或许结束了一大堆的接口,但是关于一般开发者而言,没有这种强大的规划才能,就需求在规划的时分多考虑,假设发现违反了接口阻隔原则
的情况,就应该对接口进行拆分
思维导图

Processon分享地址:https://www.processon.com/view/link/5f0210aa7d9c0844204b4845
PS:需求源c A w M & 7 X B文件的小伙伴可以在文末扫描二维码,发送【规划方式】即可
规划_ / –方式的系列文章举荐
所N u 1 p i属类型 | 规划方式 | 标题 & 链接 |
---|---|---|
行为型方式 | 战略方式 | 【一起学系列】之战略方式:很多鸭子啊 |
行为型方式 | 观察者方式 | 【一起学系列】之观察者方式:我没有在监控你啊 |
行为型方式 | 指令方式 | 【一起学系列】之指令方式:封装一个简单Jedis?* R r |
行为型方式 | 模板方法方式 | 【一起学系列】之模板方法:写SSO我只需5分钟 |
行为型方式 | 迭代器方式 | 【一起学系列】之迭代器&组合:尽管有点用不上啦 |
行为型形1 [ h G式 | 情况方式 | 【一起学系列= K @ = E Z Y】之情况方式:你听过“流程”方式} t N吗? |
行为f – a型方式 | 职责链方式 | 【一起学系列】之剩余的规划方式们 |
行为型方式 | 备忘录方式 | 【一起学系列】之剩余的规划方式们 |
结构型方式 | 装修器方式 | 【一起学系列】之装修器方式) f ( {:不改代码增强功用? |
结构型方式 | 适配器方式 & 外观– $ L b C方式 | 【一起学系列】之7 2 a v T适配器方式:还有外观方式呢 |
结构型方式 a x % | 组合方式 | 【一起学系列】之迭代器&组合:尽管有点C b n F z S b M }用不上啦 |
结构型方式 | 署理方式 | 【一h @ x ` R a [ l ^同学系列】之署理方式:是为了操控p 0 J l B |访问啊! |
创建型方式 | 工厂方式 (工厂方法及笼S ; a M 7统工厂) |
【一起学系列】之工厂方式:产品?产品族? |
创建型方式 | 单例方式 | 【一起学系列】之单例方式:只举荐三种~ |
创建型方式 | 制作者方式 | 【一起学系列】之剩余的规划形– W H式们 |
源码链接
GitHub地址
-
统筹了《HeadFirst》以及《GOF》两本经典书本中的案例 -
供j $ / 4 a给了友爱的阅读辅导

本文运用 mdnice 排版