mirror of
https://github.com/wahyd4/daily.git
synced 2026-08-09 05:16:16 +10:00
设计模式
This commit is contained in:
+40
-79
@@ -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)**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user