快速理解二十三种设计模式 (速记)
设计模式六大原则
单一职责原则(Single Responsibility Principle)
里氏替换原则(Liskov Substitution Principle)
依赖倒置原则(Dependence Inversion Principle)
接口隔离原则(Interface Segregation Principle)
迪米特法则(最少知道原则)(Law of Demeter)
合成复用原则(Composite Reuse Principle)
设计模式三大类
创建型模式(Creational Pattern):对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离。
(5种)工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式
结构型模式(Structural Pattern):关注于对象的组成以及对象之间的依赖关系,描述如何将类或者对象结合在一起形成更大的结构,就像搭积木,可以通过简单积木的组合形成复杂的、功能更为强大的结构。
(7种)适配器模式、装饰者模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为型模式(Behavioral Pattern):关注于对象的行为问题,是对在不同的对象之间划分责任和算法的抽象化;不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。
(11种)策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式
简单工厂模式
一个工厂根据不同的参数返回不同的产品
>水果店理解为一个简单工厂,你要苹果,他给你苹果,你要梨子,他就给你梨子。
工厂模式
一个工厂创建一个具体的产品,一个产品对应一个工厂类。
>宝马x1一个工厂类,x2一个工厂类,x3一个工厂类,奔驰A级一个工厂类,C级一个工厂类
抽象工厂模式
一个工厂创建一类产品,一类产品对应一个工厂。
>比如汽车制造工厂是个抽象工厂,它既可以生产宝马X1,也可以生产X2,X3。罐头厂是一个抽象工厂,它可以生产橘子罐头,也可以生产黄桃罐头。
单例模式
这个没啥好说的,保证一个类仅有一个实例,并提供一个访问它的全局访问点。
需要记忆的是懒汉式
和饿汉式
。
懒汉式:需要的时候才实例化,常用的例子就是非空检查和双重检查式的实现。
饿汉式:类加载的时候就先实例化。
类似这样的
饿汉式会线程安全些。
我们用的最主流的方式是静态内部类的方式。
>一个省只会有一个省长。
建造者模式
就是我们常用的Builder
模式。使用多个简单的对象一步一步构建成一个复杂的对象,可以简化复杂对象的构建过程。
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
>1. Android
中的Dialog
创建就是典型的建造者模式。
>2. 比如拼图,你拼的顺序可以随意,但是最终组合出来的东西总是同一个。
原型模式
用于创建重复的对象,同时又能保证性能。
自己复制自己
对象内部实现一个原形接口,用于创建对象自己的克隆。
>1. 影分身
>2. Java Object的clone()
适配器模式
两个不兼容的接口之间的桥梁。
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
>港版的电源插头是英标的大头,国产的插排都是国标的小口,需要买个转换器,这个转换器就是适配器。
代理模式
分为静态代理和动态代理。静态会有一个静态代理类,动态主要是运行时通过反射机制实现。
在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
>1. Windows 里面的快捷方式
>2. 皇帝早朝时,由太监给皇帝传话,皇帝->太监->大臣之间,太监就相当于代理。
桥接模式
把抽象化与实现化解耦,使得二者可以独立变化
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。
>墙上的开关和吊顶的灯,当开关按下的时候,灯泡熄灭了,开关再次按下,灯泡又亮了。它们之间的状态是独立的。比如开关,可以关和开,灯泡可以亮和灭。但是它们又相互耦合,开关关闭时,灯泡灭,开启时,灯泡亮。那么我们人就是client
,开关和灯泡就是抽象和实现的解耦。
组合模式
又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
>1. 集团公司一般有最顶部是总公司,总公司下面会有行政,研发等各个部门以及分公司,分公司下面又会有各个部门。这样就形成了一个树状结构。
>2. Android中ViewGroup
,View
,Button
等之间的关系也是组合模式。
装饰器模式
允许向一个现有的对象添加新的功能,同时又不改变其结构。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
>1. 一幅画外面加了个画框成了一个装饰画。
>2. 人类不穿衣服是不文明行为,穿了衣服就装饰成了文明的人。衣服还会给你提供额外的功能,比如口袋。
*引申*:装饰器模式和代理模式有什么区别?
简单理解:它俩都是对原对象进行了包装,但是代理模式倾向于对权限的控制,一般来说,我们不希望client
直接访问到目标对象或者client
无法直接访问到目标对象的清下,用代理模式(代理类里面也可以增强功能)
装饰器模式我们可以随意访问装饰类和装饰类包装的原目标类,装饰类提供了更强的能力。
外观模式
隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。
这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。
>1. 去医院看病,需要挂号,抽血,拿药等等,流程很复杂,医院提供了接待员,他帮你处理所有的流程,你只需要专心看病就行了。
>2. Android
的图片加载库Glide
,一句代码帮你实现图片的下载和显示,隐藏了复杂的图片显示逻辑。
>3. 我们使用的手机,包含通话,相机,游戏各种功能。不要你打电话用个座机,拍照拿个相机,打游戏买哥NS。
中介者模式
用来降低多个对象和类之间的通信复杂性。
这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。
>1. 我们去租房,如果自己去找房东直租太累了,我们找中介,中介找房东,最后我们通过中介租到房。
>2. 我们说的技术中台,从整体看也是个中介者模式,没有中台前我们各个业务逻辑间相互耦合,杂乱无章,有了中台后,client
和server
通过中台交互。
>3. 用户->运营人员->程序员,这三者也可以形成中介者模式,运营人员从用户获取程序问题,反馈给程序员修改。运营人员就是个中介。
*引申*:外观模式和中介者模式有什么区别?
外观模式通过增加类来把原来复杂的业务逻辑封装并简化成容易使用的方式。
中介者模式通过中介类隐藏多个调用者之间的复杂耦合关系,中介者分别和原本耦合的类打交道。
享元模式
主要用于减少创建对象的数量,以减少内存占用和提高性能。
享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。
>1. JAVA
中的 String
,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。
>2. 数据库连接池
>3. 线程池
责任链模式
为请求创建了一个接收者对象的链。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
>1. Android
中的事件分发机制
>2. 击鼓传花游戏
>3. 平时用到的请假审批流程,你的leader开始,一步步向上审批。
模板模式
一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
>1. 造房子的顺序,必须先打地基,搭建主体,按照设计图一步步来,你不能反着来。
>2. App
的生命周期,那必须是启动-运行-销毁
>3. 春晚准备好的节目单,必须安装顺序演下去。
*引申*:责任链模式和模板模式有什么区别?
责任链是不同模块一级级连接而成,可以从任意地方开始执行。
模板模式必须按照规定的方式顺序执行。
命令模式
是一种数据驱动的设计模式
请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
>1. 川普发了封杀TikTok
的命令,下面的相关部门就开始执行。川普的命令发布者,下面的部门是执行者。
策略模式
一个类的行为或其算法可以在运行时更改。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context
对象。策略对象改变 context
对象的执行算法。
>1. 旅行出游,选择交通方式。飞机,高铁等。
>2. 对一个数组排序,有多种排序方式,比如插入,归并,冒泡。提供一个统一接口,分别实现不同的排序算法。
>3. B站看视频,切换不同分辨率(720,1080,天龙人专享蓝光)
备忘录模式
保存一个对象的某个状态,以便在适当的时候恢复对象。
>1. 游戏存档
>2. 数据库的事务管理
>3. 原子性
>4. 修改文件前,先创建一个备份文件,修改成功就删除备份文件
观察者模式
当对象间存在一对多关系时,则使用观察者模式。
当一个对象被修改时,则会自动通知依赖它的对象。
>1. 球赛现场,观众是观察者,裁判是被观察者,犯规或者进球后,裁判作出判决,同步状态给观众。
>2. RSS订阅,所有的人都订阅同一个RSS地址,当内容发生变化时,订阅者都能看到变化。
解释器模式
提供了评估语言的语法或表达式的方式。
这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。
>1. 比如我们Maven
的配置文件xml
,里面定义了许多标签,程序要理解它需要有个解释器来告诉你每个标签代表什么意思
>2. 常见的配置文件,需要解析器来解析每个配置的意义。
迭代器模式
这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。
>1. JAVA 中的 iterator
>2. 新年第一天,排队领红包,一个一个去老板办公室。
状态模式
类的行为是基于它的状态改变的。
在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。
不同的状态有不同的行为。
>1. 一个人运动的时候他可以走、跑、跳。
>2. 电视和遥控器,电视关机状态下,遥控器只能控制电视开机,其他按钮无效。开机状态下,遥控器可以关机,调频道,调音量等。
>3. 手机里面的wifi
设置,开关关闭后,wifi
功能关闭。打开后可以寻找wifi
信号,连接wifi
访问者模式
将数据操作和数据结构分离的设计模式。
在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。
根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
>公司年终绩效考核,CEO和CTO分别考核非技术和技术,非技术和技术的考核指标不一样,分为两套,CEO只需要关注非技术的这套,CTO关注技术的这套。
版权声明: 本文为 InfoQ 作者【simon】的原创文章。
原文链接:【http://xie.infoq.cn/article/2eaf2954ddea59db79ef3a5cf】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论