设计模式总篇:从为何须要原则到实际落地(附知识图谱)

聊聊为何须要原则

咱们全部人都看过科幻电影,都看到过将来场景中人类和机器人和平相处的场景java

为了让拥有自主智能的机器人不失控,人类为机器人制定了三大定律:git

  • <font color="red">第必定律:机器人不得伤害人类个体,或者目击人类个体将遭受危险而袖手无论</font>
  • <font color="red">第二定律:机器人必须服从人给予它的命令,当该命令与第必定律冲突时例外</font>
  • <font color="red">第三定律:机器人在不违反第1、第二定律的状况下要尽量保护本身的生存</font>

固然有时也会出现下面的状况,机器人和人类开始互为阵营,各自为敌github

可是各自为敌的状况出现,通常都是机器人觉醒了自我意识,再也不遵照三大定律编程

从逻辑学来讲,若是机器人彻底遵照三大定律及其衍生的条约,那么机器人就能够和人类和平相处,固然也会有意外发生。设计模式

写代码为何须要设计原则

和机器人的三大定律相仿,几十年的编程经验,让几代人总结出来了一些代码设计上的定律,这就是设计模式的七大原则数组

咱们遵循七大原则,必定会写出最完美的代码吗?ide

答案固然是不必定,毕竟没有人能保证本身能够彻底遵循七大原则,同时我的的编程能力也会起到决定性因素。post

那咱们为何还要遵照?性能

我本身想到的一句名言(之后或许能够成为名言~)学习

向着最好的方向去努力,总不会是最差的结果。

七大原则详解

开闭原则 ★★★★★

软件实体对扩展是开放的,但对修改是关闭的,即在不修改一个软件实体的基础上去扩展其功能

例如:

以策略模式为例,当咱们新增一种策略的时候,只须要实现策略顶层接口,在调用的时指向新的策略便可

针对这一条原则,在实现难度上要比单一职责更难,在编码期间,咱们须要充分考虑将来的拓展性,规范接口,依赖抽象,这样才能在须要拓展的时候,很是方便的实现其效果

最佳实践案例:【一块儿学系列】之模板方法:写SSO我只要5分钟

说明:在接入第三方SSO时,若是须要新增接入方,基于文中的案例,只需实现固定接口,便可优雅的实现相应需求

依赖倒置原则 ★★★★★

要针对抽象层编程,而不要针对具体类编程

例如:

以适配器模式为例,将一个类的接口转换成客户但愿的另一个接口,以此实现的前提即是代码中所依赖的都是抽象的,由于只有依赖抽象,才能在代码运行期间改变其实体,利用多态实现须要的效果

针对该条原则,其实有必定编程经验的人必定会在无形中注意到,并且了解设计模式的话,会发现全部涉及接口和实现的设计模式都会听从这一条原则

最佳实践案例:【一块儿学系列】之模板方法:写SSO我只要5分钟

说明:和上一条原则的侧重点不一样,在SSO中必然有其固定的流程,如登陆-获取Token-获取用户信息-解析-退出等等,在代码的编写阶段,须要咱们定义出接口/抽象类,而后依赖于抽象层,最终改变具体类,以此达到无缝切换的效果

合成复用原则 ★★★★☆

总结一句话就是:多用组合,少用继承

例如:

以单例模式和代理模式为例,它们都是该模式的最佳实践者,单例模式是把不一样的策略接口经过组合的方式嵌入到Context类中,如代码所示:

public abstract class Duck {
    /**
     * 飞行行为是动态的,可能会变的,所以抽成多个接口的组合,而不是让Duck类继承
     */
    FlyBehavior flyBehavior;

    /**
     * 每一个鸭子的叫声不一样,抽象成接口
     */
    QuackBehavior quackBehavior;
}

同理,代理模式也是如此,这里就考虑到一个问题,为何要多用组合而非继承?

其实仍是Java中单继承引起的问题,同时继承的语义过于苛刻,所以更多的时候建议善用组合

最佳实践案例:【一块儿学系列】之策略模式:好多鸭子啊

说明:策略模式就是合成复用原则的最佳实践者,没有之一

单一职责原则 ★★★★☆

类的职责要单一,不能将太多的职责放在一个类中

例如:

在代码设计中某种场景可能存在多种不一样的状态,极可能就把代码混在一块儿了,这时咱们利用状态模式进行设计,把各类状态对应的实现细节都用类的级别单独划分,即体现了单一职则原则

针对这一条原则,其实绝大多数人在设计之初都会考虑到,但问题就在于随着工做中人员职责的交叉,颇有可能会破坏他人设计的最初目的,为了方便,让一个类拥有五花八门的功能

最佳实践案例:【一块儿学系列】之状态模式:你听过“流程”模式吗?

说明:在状态模式中,每一种状态的处理都是独立的一个类,每一个类只须要处理自身的核心逻辑,完美体现了单一职责原则

里氏代换原则 ★★★★☆

在软件系统中,一个能够接受基类对象的地方必然能够接受一个子类对象

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

继承包含这样一层含义:父类中凡是已经实现好的方法(相对于抽象方法而言),其实是在设定一系列的规范和契约,虽然它不强制要求全部的子类必须听从这些契约,可是若是子类对这些非抽象方法任意修改,就会对整个继承体系形成破坏。而里氏替换原则就是表达了这一层含义

例如:

咱们都用过ArrayList,有谁看过 forEach方法的源码?

// ArrayList 的父级接口 Iterable  定义的默认方法
default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}

ArrayList重写的方法:

@Override
public void forEach(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    final int expectedModCount = modCount;
    @SuppressWarnings("unchecked")
    final E[] elementData = (E[]) this.elementData;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        action.accept(elementData[i]);
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
}

咱们看到,ArrayList的重写只是针对数组这种结构优化了性能,其目的性和Iterable接口中的彻底一致,所以这种方式的重写不会引发任何问题,反而能够提升效率,咱们须要学习这样的方式

迪米特原则 ★★★☆☆

一个对象应该对其余对象保持最少的了解,又名:最少知道原则

例如:

在代码设计场景中,某一个类的调用都会固定使用三个方法,是否能够考虑把三个方法抽取出来,提供一个公共的对外方法?这种思路就是外观模式,外观模式也是迪米特原则的最佳实践

最佳实践案例:【一块儿学系列】之适配器模式:还有外观模式呢

说明:利用外观模式构建统一的对外方法,屏蔽其内部实现,这样一旦内部实现须要更改,彻底不会影响调用方,你Get了吗?

接口隔离原则 ★★☆☆☆

使用多个专门的接口来取代一个统一的接口

这个模式其实也很好理解,好比咱们定义了接口A,接口B实现了接口A,接口C实现了接口B,基类D其实只须要接口C的方法,可是此时不得不实现全部的方法

<font color="red">其实形成这个根本缘由:对接口的抽象,设计出现了误差</font>

毕竟看过JDK源码或者Spring源码的同窗,能够常常发现某一个接口可能实现了一大堆的接口,可是对于普通开发者而言,没有这种强大的设计能力,就须要在设计的时候多思考,若是发现违背了接口隔离原则的状况,就应该对接口进行拆分

思惟导图

Processon分享地址: https://www.processon.com/vie...

PS:须要源文件的小伙伴能够在文末扫描二维码,发送【设计模式】便可

设计模式的系列文章推荐

所属类型 设计模式 标题 & 连接
<font color="red">行为型模式</font> 策略模式 【一块儿学系列】之策略模式:好多鸭子啊
<font color="red">行为型模式</font> 观察者模式 【一块儿学系列】之观察者模式:我没有在监控你啊
<font color="red">行为型模式</font> 命令模式 【一块儿学系列】之命令模式:封装一个简单Jedis?
<font color="red">行为型模式</font> 模板方法模式 【一块儿学系列】之模板方法:写SSO我只要5分钟
<font color="red">行为型模式</font> 迭代器模式 【一块儿学系列】之迭代器&组合:虽然有点用不上啦
<font color="red">行为型模式</font> 状态模式 【一块儿学系列】之状态模式:你听过“流程”模式吗?
<font color="red">行为型模式</font> 职责链模式 【一块儿学系列】之剩下的设计模式们
<font color="red">行为型模式</font> 备忘录模式 【一块儿学系列】之剩下的设计模式们
<font color="blue">结构型模式</font> 装饰器模式 【一块儿学系列】之装饰器模式:不改代码加强功能?
<font color="blue">结构型模式</font> 适配器模式 & 外观模式 【一块儿学系列】之适配器模式:还有外观模式呢
<font color="blue">结构型模式</font> 组合模式 【一块儿学系列】之迭代器&组合:虽然有点用不上啦
<font color="blue">结构型模式</font> 代理模式 【一块儿学系列】之代理模式:是为了控制访问啊!
<font color="green">建立型模式</font> 工厂模式
(工厂方法及抽象工厂)
【一块儿学系列】之工厂模式:产品?产品族?
<font color="green">建立型模式</font> 单例模式 【一块儿学系列】之单例模式:只推荐三种~
<font color="green">建立型模式</font> 建造者模式 【一块儿学系列】之剩下的设计模式们

源码连接

GitHub地址

  • 兼顾了《HeadFirst》以及《GOF》两本经典书籍中的案例
  • 提供了友好的阅读指导

LOGO

相关文章
相关标签/搜索