设计模式

107 篇文章 0 订阅
1 篇文章 0 订阅

设计模式是解决问题的思想,重要的是它背后的思想。写代码时不要刻意追求设计模式。

什么是设计模式

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现实中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。简单说:
模式:在某些场景下,针对某类问题的某种通用的解决方案。
场景:项目所在的环境
问题:约束条件,项目目标等
解决方案:通用、可复用的设计,解决约束达到目标。

六大设计原则

学习设计模式,首先要学习的就是设计原则。

1.单一职责(SRP:Single responsibility principle)

一个类只负责一项职责。

2.里氏替换原则 (LSP:Liskov Substitution Principle)

在使用基类的的地方可以任意使用其子类替换基类,能保证子类完美替换基类。子类可以扩展父类功能,但不要改变父类原有的功能

3.依赖倒置原则 (Dependence Inversion Principle)

所谓依赖倒置原则就是要依赖于抽象,不要依赖于具体。即面向接口编程

4.接口隔离原则 (Interface Segregation Principle)

使用多个隔离的接口,比使用单个接口要好。设计接口功能尽量细粒度,最小功能单元

5.迪米特法则(最少知道原则) (Demeter Principle)

一个对象应该对其他对象保持最少的了解。就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。也就是说一个软件实体应当尽可能少的与其他实体发生相互作用。这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易,这是对软件实体之间通信的限制,它要求限制软件实体之间通信的宽度和深度。

降低耦合。方法内,局部变量中,不要引入新的类,应该作为类的成员变量引入,让外界知道。

6.开闭原则(Open Close Principle)

对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。
开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统。

总结:

六大设计原则中最重要的是:开闭原则、单一职责、依赖倒置原则。

设计模式的三个分类

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

各分类中模式的关键点

创建型模式

单例模式:某个类只能有一个实例,提供一个全局的访问点。

简单工厂:一个工厂类根据传入的参数决定创建出哪一种产品类的实例。

工厂方法:定义一个创建对象的接口,让子类决定实例化哪个类。

抽象工厂:创建相关或依赖对象的家族,而无需明确指定具体类。

建造者模式:封装一个复杂对象的构建过程,并可以按步骤构造。

原型模式:通过复制现有的实例来创建新的实例。

结构型模式

适配器模式:将一个类的方法接口转换成客户希望的另外一个接口。

组合模式:将对象组合成树形结构以表示“”部分-整体“”的层次结构。

装饰模式:动态的给对象添加新的功能。

代理模式:为其他对象提供一个代理以便控制这个对象的访问。

亨元(蝇量)模式:通过共享技术来有效的支持大量细粒度的对象。

外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。

桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。

行为型模式

模板方法模式:定义一个算法结构,而将一些步骤延迟到子类实现。

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。

策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。

状态模式:允许一个对象在其对象内部状态改变时改变它的行为。

观察者模式:对象间的一对多的依赖关系。

备忘录模式:在不破坏封装的前提下,保持对象的内部状态。

中介者模式:用一个中介对象来封装一系列的对象交互。

命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。

访问者模式:在不改变数据结构的前提下,增加作用于一组对象元素的新功能。

责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。

迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。

23种设计模式

1.简单工厂模式

一个工厂类根据传入的参数决定创建出哪一种产品类的实例。又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。

在这里插入图片描述
在这里插入图片描述

简单工厂模式的不足:在这里插入图片描述

2.工厂方法模式

将工厂类抽象出一个接口,对象的创建方法延迟到工厂子类去实现。扩展新的品类时,不要修改已有代码。
在这里插入图片描述
在这里插入图片描述

3.抽象工厂模式

考虑到水果需要包装:
1、水果邮寄客户时,需要包装。
2、产品分成了两个系列,一个水果系列,一个包装盒系列

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.建造者模式

工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性。

当建造对象比较复杂时:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

工厂模式总结:
在这里插入图片描述
原则:
1、解耦:把对象的创建和使用的过程分开。
2、工厂负责对象的创建,包括其init方法的调用,黑盒创建过程。
3、面向接口编程: 使用者只管使用,只知其接口而不知其实现类。
对比:
4、静态工厂:把所有对象的创建逻辑集中到一个(专业)类里处理
5、工厂方法模式:一个工厂负责创建一个产品类的创建
6、抽象工厂模式:将一个系列的产品的工厂合并成一个工厂,负责生产这个系列的产品
7、建造者模式:对象的创建比较复杂时,按步骤一块块创建,让创建过程模板化。

5.单例模式

水果店想创建帐本,保持仅有一个。
在这里插入图片描述

6.适配器模式

在我们的应用程序中我们可能需要将两个不同接口的类来进行通信,在不修改这两个的前提下我们可能会需要某个中间件来完成这个衔接的过程。这个中间件就是适配器。所谓适配器模式就是将一个类的接口,转换成客户期望的另一个接口。它可以让原本两个不兼容的接口能够无缝完成对接。

顾客来买桔子,结果发现桔子的包装盒子没有了,怎么办?发现苹果盒子还有多的,想要把桔子装在苹果盒里,暂时替代一下。

在这里插入图片描述

7.桥接模式

如果说某个系统能够从多个角度来进行分类,且每一种分类都可能会变化,那么我们需要做的就是将这多个角度分离出来,使得他们能独立变化,减少他们之间的耦合,这个分离过程就使用了桥接模式。所谓桥接模式就是将抽象部分和实现部分隔离开来,使得他们能够独立变化。

桥接模式将继承关系转化成关联关系,封装了变化,完成了解耦,减少了系统中类的数量,也减少了代码量。

果园水果熟了,需要我们进园去采摘,需要先确定采摘袋的大小和材质。
在这里插入图片描述
桥接模式表达采摘袋:
在这里插入图片描述
将两个维度变化的功能组合起来,为的是独立变化。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8.装饰模式

我们可以通过继承和组合的方式来给一个对象添加行为,虽然使用继承能够很好拥有父类的行为,但是它存在几个缺陷:一、对象之间的关系复杂的话,系统变得复杂不利于维护。二、容易产生“类爆炸”现象。三、是静态的。在这里我们可以通过使用装饰者模式来解决这个问题。

装饰者模式,动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。虽然装饰者模式能够动态将责任附加到对象上,但是他会产生许多的细小对象,增加了系统的复杂度。

打包水果时,需要做打防伪/加固/加急等一些附加动作:
在这里插入图片描述
希望在不影响业务主流程的前提下,在打包环节增加防伪/加固/加急等功能。
在这里插入图片描述
动态地给一个对象增加一些额外的职责,为的是功能增强。
在这里插入图片描述

9.代理模式

代理模式就是给某个对象提供一个代理,并由代理对象控制对目标对象的访问。代理对象是目标对象的代表,其他需要与这个目标对象打交道的操作都是和这个代理对象在交涉。

水果店与第三方合作,开展了海外水果代购服务
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

10.组合模式

组合模式组合多个对象形成树形结构以表示“整体-部分”的结构层次。它定义了如何将容器对象和叶子对象进行递归组合,使得客户在使用的过程中无须进行区分,可以对他们进行一致的处理。在使用组合模式中需要注意一点也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。

水果要送往客户的目的地,客户订单的目的地问题:
在这里插入图片描述
把一组相似的对象当作一个单一的对象,为的是减少数据类型。
在这里插入图片描述

在这里插入图片描述

11.外观模式

为多个子系统对外提供一个共同的接口。

我们都知道类与类之间的耦合越低,那么可复用性就越好,如果两个类不必彼此通信,那么就不要让这两个类发生直接的相互关系,如果需要调用里面的方法,可以通过第三者来转发调用。外观模式非常好的诠释了这段话。外观模式提供了一个统一的接口,用来访问子系统中的一群接口。它让一个应用程序中子系统间的相互依赖关系减少到了最少,它给子系统提供了一个简单、单一的屏障,客户通过这个屏障来与子系统进行通信。通过使用外观模式,使得客户对子系统的引用变得简单了,实现了客户与子系统之间的松耦合。但是它违背了“开闭原则”,因为增加新的子系统可能需要修改外观类或客户端的源代码。

客户下单付款后,有一系列的动作:采摘/商品包装/物流送货
在这里插入图片描述

在这里插入图片描述
糅合功能,对外只提供一个入口。在这里插入图片描述

在这里插入图片描述

12.模板方法模式

所谓模板方法模式就是在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

水果店不断扩展结算方式,希望不影响购物流程
在这里插入图片描述
在父类中编排主流程,将步骤实现延迟到子类去实现。

在这里插入图片描述
在这里插入图片描述

13.策略模式

在策略模式中将解决问题的方法定义成一个算法群,每一个方法都对应着一个具体的算法,这里的一个算法我就称之为一个策略。虽然策略模式定义了算法,但是它并不提供算法的选择,即什么算法对于什么问题最合适这是策略模式所不关心的,所以对于策略的选择还是要客户端来做。客户必须要清楚的知道每个算法之间的区别和在什么时候什么地方使用什么策略是最合适的,这样就增加客户端的负担。

每个订单,可选用一张优惠券
在这里插入图片描述

通过选择策略类,来执行不同算法分支。核心是通过注入对象,改变行为。
在这里插入图片描述

14.责任链模式

责任链模式描述的请求如何沿着对象所组成的链来传递的。它将对象组成一条链,发送者将请求发给链的第一个接收者,并且沿着这条链传递,直到有一个对象来处理它或者直到最后也没有对象处理而留在链末尾端。

每个订单,可用多张优惠券叠加减免在这里插入图片描述
将请求传给一个接收者链,由链将请求流转给目标对象。
在这里插入图片描述

在这里插入图片描述

15.观察者模式

观察者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。

发生改变的对象称之为观察目标,而被通知的对象称之为观察者。一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,所以么可以根据需要增加和删除观察者,使得系统更易于扩展。所以.观察者模式提供了一种对象设计,让主题和观察者之间以松耦合的方式结合。

青芒很好吃,但是库存没了,许多顾客都关注青芒何时能到货?
在这里插入图片描述
一个对象状态改变时通知其他对象。为的是尽量弱化对象间的依赖。

在这里插入图片描述

在这里插入图片描述

JDK 对观察者模式的支持:
在这里插入图片描述

16.命令模式

有些时候我们想某个对象发送一个请求,但是我们并不知道该请求的具体接收者是谁,具体的处理过程是如何的,我们只知道在程序运行中指定具体的请求接收者即可,对于这样将请求封装成对象的我们称之为命令模式。

优缺点及适用情况

优点:
降低对象之间的耦合度
新的命令可以很容易地加入到系统中
可以比较容易地设计一个组合命令
调用同一方法实现不同的功能

缺点:
可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用

适用情况:
系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互
系统需要在不同的时间指定请求、将请求排队和执行请求
系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作
系统需要将一组操作组合在一起,即支持宏命令

水果店的app的首页列表展示的商品,不断有新花样
在这里插入图片描述
使用命令模式:
在这里插入图片描述
通过增加Command抽象命令类,将不符合抽象编程的handler 调用,转为抽象编程。
在这里插入图片描述

在这里插入图片描述

17.访问者模式

访问者模式俗称23大设计模式中最难的一个。除了结构复杂外,理解也比较难。在我们软件开发中我们可能会对同一个对象有不同的处理,如果我们都做分别的处理,将会产生灾难性的错误。对于这种问题,访问者模式提供了比较好的解决方案。访问者模式即表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

访问者模式的目的是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式。同时我们还需要明确一点那就是访问者模式是适用于那些数据结构比较稳定的,因为他是将数据的操作与数据结构进行分离了,如果某个系统的数据结构相对稳定,但是操作算法易于变化的话,就比较适用适用访问者模式,因为访问者模式使得算法操作的增加变得比较简单了。

想要统计水果库存有多少?
在这里插入图片描述
何为双重分派?
在这里插入图片描述
利用双重分派机制,弥补java多态中的方法重载是静态化的不足。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

参考:
JAVA设计模式总结之六大设计原则
JAVA设计模式总结之23种设计模式
Java中常用的设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值