设计模式

This commit is contained in:
pingwen
2020-08-26 13:56:31 +08:00
parent d7c1b8603c
commit d2fd1a1072
+40 -79
View File
@@ -62,67 +62,40 @@
**3)编码规范**
1命名以能准确达意为目标,利用上下文简化命名,命名要可读、可搜索。
(2)注释的内容主要包含这样四个方面:做什么、为什么、怎么做、怎么用。对一些边界条件、特殊情况进行说明,以及对函数输入、输出、异常进行说明
(3)类、函数规模不要超过一个显示屏的垂直高度
(4)一行代码最长不能超过 IDE 显示的宽度
(5)善用空行分割单元块,在类的成员变量与函数之间、静态成员变量与普通成员变量之间、各函数之间、甚至各成员变量之间,界限更加明确
(6)缩进,Java 语言倾向于两格缩进,PHP 语言倾向于四格缩进
(7)大括号是否要另起一行,PHP 程序员喜欢另起一行,Java 程序员喜欢跟上一条语句放到一起
(8)类中成员的排列顺序,在 Java 类文件中,先要书写类所属的包名,然后再罗列 import 引入的依赖类。
(9)把代码分割成更小的单元块,要有模块化和抽象思维,善于将大块的复杂逻辑提炼成类或者函数,屏蔽掉细节,让阅读代码的人不至于迷失在细节中。
(10)避免函数参数过多,考虑函数是否职责单一,是否能通过拆分成多个函数的方式来减少参数。将函数的参数封装成对象。
(11)勿用函数参数来控制逻辑,不要在函数中使用布尔类型的标识参数来控制内部逻辑。
(12)函数设计要职责单一,相对于类和模块,函数的粒度比较小,代码行数少,所以在应用单一职责原则的时候,没有像应用到类或者模块那样模棱两可,能多单一就多单一。
(13)移除过深的嵌套层次,嵌套最好不超过两层,超过两层之后就要思考一下是否可以减少嵌套。
(14)学会使用解释性变量,常量取代魔法数字。使用解释性变量来解释复杂表达式。
1. 命名以能准确达意为目标,利用上下文简化命名,命名要可读、可搜索。
2. 注释的内容主要包含这样四个方面:做什么、为什么、怎么做、怎么用。对一些边界条件、特殊情况进行说明,以及对函数输入、输出、异常进行说明。
3. 类、函数规模不要超过一个显示屏的垂直高度
4. 一行代码最长不能超过 IDE 显示的宽度。
5. 善用空行分割单元块,在类的成员变量与函数之间、静态成员变量与普通成员变量之间、各函数之间、甚至各成员变量之间,界限更加明确
6. 缩进,Java 语言倾向于两格缩进,PHP 语言倾向于四格缩进。
7. 大括号是否要另起一行,PHP 程序员喜欢另起一行,Java 程序员喜欢跟上一条语句放到一起
8. 类中成员的排列顺序,在 Java 类文件中,先要书写类所属的包名,然后再罗列 import 引入的依赖类。
9. 把代码分割成更小的单元块,要有模块化和抽象思维,善于将大块的复杂逻辑提炼成类或者函数,屏蔽掉细节,让阅读代码的人不至于迷失在细节中
10. 避免函数参数过多,考虑函数是否职责单一,是否能通过拆分成多个函数的方式来减少参数。将函数的参数封装成对象。
11. 勿用函数参数来控制逻辑,不要在函数中使用布尔类型的标识参数来控制内部逻辑
12. 函数设计要职责单一,相对于类和模块,函数的粒度比较小,代码行数少,所以在应用单一职责原则的时候,没有像应用到类或者模块那样模棱两可,能多单一就多单一。
13. 移除过深的嵌套层次,嵌套最好不超过两层,超过两层之后就要思考一下是否可以减少嵌套
14. 学会使用解释性变量,常量取代魔法数字。使用解释性变量来解释复杂表达式。
**4)代码质量问题清单**
下面 7 个是通用的关注点,可以作为一些常规检查项,套用在任何代码的重构上。
(1)目录设置是否合理、模块划分是否清晰、代码结构是否满足“高内聚、松耦合”
(2)是否遵循经典的设计原则和设计思想(SOLID、DRY、KISS、YAGNI、LOD 等)
(3)设计模式是否应用得当?是否有过度设计
(4)代码是否容易扩展?如果要添加新功能,是否容易实现?
(5)代码是否可以复用?是否可以复用已有的项目代码或类库?是否有重复造轮子?
(6)代码是否容易测试?单元测试是否全面覆盖了各种正常和异常的情况?
(7)代码是否易读?是否符合编码规范(比如命名和注释是否恰当、代码风格是否一致等)?
1. 目录设置是否合理、模块划分是否清晰、代码结构是否满足“高内聚、松耦合”?
2. 是否遵循经典的设计原则和设计思想(SOLID、DRY、KISS、YAGNI、LOD 等)
3. 设计模式是否应用得当?是否有过度设计?
4. 代码是否容易扩展?如果要添加新功能,是否容易实现
5. 代码是否可以复用?是否可以复用已有的项目代码或类库?是否有重复造轮子?
6. 代码是否容易测试?单元测试是否全面覆盖了各种正常和异常的情况
7. 代码是否易读?是否符合编码规范(比如命名和注释是否恰当、代码风格是否一致等)?
还要关注代码实现是否满足业务本身特有的功能和非功能需求。一些比较共性的关注点如下所示:
1)代码是否实现了预期的业务需求
(2)逻辑是否正确?是否处理了各种异常情况
(3)日志打印是否得当?是否方便 debug 排查问题
(4)接口是否易用?是否支持幂等、事务等?
(5)代码是否存在并发问题?是否线程安全?
(6)性能是否有优化空间,比如,SQL、算法是否可以优化?
(7)是否有安全漏洞?比如输入输出校验是否全面?
1. 代码是否实现了预期的业务需求?
2. 逻辑是否正确?是否处理了各种异常情况
3. 日志打印是否得当?是否方便 debug 排查问题?
4. 接口是否易用?是否支持幂等、事务等
5. 代码是否存在并发问题?是否线程安全?
6. 性能是否有优化空间,比如,SQL、算法是否可以优化
7. 是否有安全漏洞?比如输入输出校验是否全面?
## 三、创建型设计模式
@@ -133,10 +106,8 @@
**2)工厂模式**
用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。
1)简单工厂(Simple Factory)利用 if 分支创建对象
2)工厂方法(Factory Method)定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
1. 简单工厂(Simple Factory)利用 if 分支创建对象。
2. 工厂方法(Factory Method)定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类
**3)建造者模式(Builder Design Pattern**
@@ -155,18 +126,14 @@
**2)桥接模式(Bridge Design Pattern**
对于这个模式有两种不同的理解方式。
(1)将抽象和实现解耦,让它们可以独立变化
(2)一个类存在两个(或多个)独立变化的维度,通过组合的方式,让这两个(或多个)维度可以独立进行扩展。
1. 将抽象和实现解耦,让它们可以独立变化。
2. 一个类存在两个(或多个)独立变化的维度,通过组合的方式,让这两个(或多个)维度可以独立进行扩展
**3)装饰器模式(Decorator Design Pattern**
相对于简单的组合关系,有两个比较特殊的地方。
1装饰器类和原始类继承同样的父类,这样可以对原始类“嵌套”多个装饰器类
(2)装饰器类是对功能的增强,这也是装饰器模式应用场景的一个重要特点。
1. 装饰器类和原始类继承同样的父类,这样可以对原始类“嵌套”多个装饰器类。
2. 装饰器类是对功能的增强,这也是装饰器模式应用场景的一个重要特点
代理类附加的是跟原始类无关的功能,而在装饰器模式中,装饰器类附加的是跟原始类相关的增强功能。
@@ -179,24 +146,18 @@
适配器模式可以看作一种“补偿模式”,用来补救设计上的缺陷。应用这种模式算是“无奈之举”。
代理、桥接、装饰器和适配器都可以称为 Wrapper 模式,也就是通过 Wrapper 类二次封装原始类。
(1)代理模式:代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问,而非加强功能,这是它跟装饰器模式最大的不同
(2)桥接模式:桥接模式的目的是将接口部分和实现部分分离,从而让它们可以较为容易、也相对独立地加以改变
(3)装饰器模式:装饰者模式在不改变原始类接口的情况下,对原始类功能进行增强,并且支持多个装饰器的嵌套使用。
(4)适配器模式:适配器模式是一种事后的补救策略。适配器提供跟原始类不同的接口,而代理模式、装饰器模式提供的都是跟原始类相同的接口。
1. 代理模式:代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问,而非加强功能,这是它跟装饰器模式最大的不同。
2. 桥接模式:桥接模式的目的是将接口部分和实现部分分离,从而让它们可以较为容易、也相对独立地加以改变
3. 装饰器模式:装饰者模式在不改变原始类接口的情况下,对原始类功能进行增强,并且支持多个装饰器的嵌套使用。
4. 适配器模式:适配器模式是一种事后的补救策略。适配器提供跟原始类不同的接口,而代理模式、装饰器模式提供的都是跟原始类相同的接口
**5)门面模式(Facade Design Pattern**
为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。子系统(subsystem)既可以是一个完整的系统,也可以是更细粒度的类或者模块。
与适配器模式的区别:
1)适配器模式做接口转换,解决的是原接口和目标接口不匹配的问题。在代码结构上主要是继承加组合
(2)门面模式做接口整合,解决的是多接口调用带来的问题。在代码结构上主要是封装。
1. 适配器模式是做接口转换,解决的是原接口和目标接口不匹配的问题。在代码结构上主要是继承加组合。
2. 门面模式做接口整合,解决的是多接口调用带来的问题。在代码结构上主要是封装
**6)组合模式(Composite Design Pattern**