设计原则
单一职责原则 S
修改一个类的原因只能有一个。
开闭原则 O
应该对扩展开放,对修改封闭。为未来代码改变的可能性在现在代码中预留接口。
里氏替换原则 L
子类必须保持与父类行为的兼容。
接口隔离原则 I
客户端不应该强迫依赖于其不使用的方法。
依赖倒置原则 D
高层次的类不应该依赖于低层次的类。两者都应该依赖于抽象接口。抽象接口不应该依赖于具体实现。具体实现应该依赖于抽象接口。
你无需修改已有的类就能用不同的业务逻辑类扩展低层次的类。
设计模式
- 设计模式不能解决所有问题。
- 强行使用可能会适得其反。
- 设计模式是问题的解决方案,不是解决问题的解决方案。
创建型设计模式
描述:
- 以适用于特定情况的方式创建对象,解决对象以基本形式创建时导致的设计问题或增加的设计复杂性。
- 如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
何时使用?对象创建的基本形式可能导致设计问题或增加设计的复杂性。
简单工厂模式 Simple Factory
描述:为客户端生成一个实例,而不会向客户端公开任何实例化的逻辑。
何时使用?当创建对象涉及一些逻辑时,并且这些逻辑重复散落在不通地方时。
工厂方法模式 Factory Method
描述:在父类中提供一个创建对象的接口以允许子类决定实例化对象的类型。
何时使用?在类中有一些通用处理但在运行时动态决定所需的子类时很有用。换句话说,当客户端不知道它可能需要什么样的子类时。
抽象工厂模式 Abstract Factory
描述:让你能创建一系列相关的对象,而无需指定其具体的类。
何时使用?当涉及到不那么简单的,存在相互依赖关系的创建逻辑时使用。
构造器模式 Builder
描述:使你能够分步骤创建复杂对象。允许你使用相同的创建代码生成不同类型和形式的对象。
何时使用?当一个对象可能存在几种类型并避免构造函数伸缩时使用。与工厂模式的主要区别在于:当创建是一步过程时,将使用工厂模式,而当创建是多步骤过程时,将使用建造者模式。
原型模式 Prototype
描述:N/A
单例模式 Singleton
描述:让你能够保证一个类只有一个实例,并提供一个访问该实例的全局节点。
何时使用?一个类只有一个实例。
结构型设计模式
描述:结构设计模式是通过识别实现实体之间关系的简单方法来简化设计的设计模式。
何时使用?符合特定结构时使用。
适配器模式 Adapter
描述:让接口不兼容的对象能够相互合作。
何时使用?在适配器中包装其他不兼容的对象,使其与另一个类兼容。
桥梁模式 Bridge
描述:N/A
组合模式 Composite
描述:可以将对象合成树状结构,并且能像使用独立对象一样使用它们。
何时使用?存在树形结构时使用。
装饰器模式 Decorator
描述:允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。
何时使用?类的功能和属性需要动态变化时使用。
门面模式 Facade
描述:N/A
享元模式 Flyweight
描述:N/A
代理模式 Proxy
描述:让你能够提供对象的替代品或者占位符。代理控制着对原对象的访问,并允许在请求提交给对象前后进行一些处理。
何时使用?保护原有对象不被破坏,同时为其扩展功能时使用。
行为型设计模式
描述:行为模式负责对象间的高效沟通和职责委派。
何时使用?合适的时候使用。
责任链模式 Chain of Responsibilities
描述:允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或者将其传递给链上的下一个处理者。
何时使用?当存在多个处理者时使用。
命令模式 Command
描述:N/A
迭代器模式 Iterator
描述:让你能在不暴露集合底层表现形式的情况下遍历集合中的所有元素。
何时使用?
- 需要自己控制迭代进程时使用。
- 迭代逻辑复杂时使用。
中介者模式 Mediator
描述:N/A
备忘录模式 memento
描述:允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。
何时使用?需要保存和恢复对象之前的状态。
观察者模式 Observer
描述:允许你定义一种订阅机制,可在对象时间发生时通知多个观察该对象的其他对象。
何时使用?需要对行为作出反应的行为者可能存在动态变化。
访问者模式 Visitor
描述:N/A
策略模式 Strategy
描述:能让你定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换。
何时使用?需要动态决定执行策略时。
状态模式 State
描述:让你能够在一个对象的内部状态变化时改变其行为,使其看上去就像改变了自身所属的类。
何时使用?对象的行为受其外部状态影响时使用。
模板方法模式 Template Method
描述:在超类中定义一个算法框架,允许子类在不修改结构的情况下重写算法的特定步骤。
何时使用?存在顺序特化的一类逻辑时使用。
代码坏味道
命名
- 命名不能精准描述意图
parse() - 命名描述的是实现细节而不是意图
upsertOrDeleteWordCloud() - 名称与内容不匹配
- 使用意义不明的缩写
- 错误的英文
控制语句
- 循环嵌套
- 分支嵌套
代码风格
- 方法体过长
- 单行代码过长
- 类过长
- 方法参数过多
- 空格换行不统一
实现
- 命名不一致
- 实现方案不一致
lodash.forEachORarray.forEach() - 不同层级的业务出现在同一个循环中
- 落后的实现
- 过于聪明的实现
注释
- 被注释掉的代码
- 复述代码的注释
设计
- 连续多个方法调用
- Primitive Obsession,使用更抽象的类型替代基本类型
- 缺少防腐,外部依赖和核心逻辑缺少封装,全部暴露在外
- 滥用箭头函数
- 逻辑结构重复缺少抽象和封装
- 改变参数的值,修改不属于当前作用域的变量
- 捕获异常但不处理
- 错误的类型声明
- 缺少访问控制
