design

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Software Design

软件设计

This skill provides guidance on software design principles, emphasizing simplicity, maintainability, and clean architecture.
本技能提供软件设计原则相关指导,强调简洁性、可维护性与清晰架构。

The Four Rules of Simple Design

简单设计四原则

These rules, in priority order, guide all design decisions:
  1. Passes the tests — The code must work correctly
  2. Reveals intention — The code clearly expresses what it does
  3. No duplication — Every piece of knowledge has a single representation (DRY)
  4. Fewest elements — No unnecessary classes, methods, or code
Rules 2 and 3 are closely related and reinforce each other. When they appear to conflict, favor revealing intention — clarity for the reader takes precedence.
The rules are applied in order: never sacrifice correctness for clarity, never sacrifice clarity for DRY, and never add elements just to reduce duplication.
这些规则按优先级排序,指导所有设计决策:
  1. 通过测试 —— 代码必须能正确运行
  2. 清晰表意 —— 代码能明确表达其功能
  3. 无重复 —— 每一项知识都只有单一表示(DRY)
  4. 最少元素 —— 不包含不必要的类、方法或代码
规则2和3紧密相关且相辅相成。当它们看似冲突时,优先选择清晰表意——读者的理解优先级更高。
规则需按顺序应用:绝不能为了清晰性牺牲正确性,绝不能为了遵循DRY原则牺牲清晰性,绝不能仅仅为了减少重复而添加元素。

SOLID Principles

SOLID原则

Single Responsibility Principle (SRP)

单一职责原则(SRP)

A module should have one, and only one, reason to change.
This means a module should be responsible to one, and only one, actor or stakeholder. When multiple actors depend on the same module, changes for one actor risk breaking functionality for another.
Signs of SRP violations:
  • A class that changes for multiple reasons
  • Methods that serve different stakeholders
  • "And" in class names (e.g.,
    UserValidatorAndNotifier
    )
一个模块应该有且仅有一个引起变化的原因。
这意味着一个模块应该只对一个参与者或利益相关者负责。当多个参与者依赖同一个模块时,为其中一个参与者进行的修改可能会破坏其他参与者的功能。
违反SRP的迹象:
  • 一个类会因多种原因发生变更
  • 方法服务于不同的利益相关者
  • 类名中包含“And”(例如
    UserValidatorAndNotifier

Open/Closed Principle (OCP)

开闭原则(OCP)

Software entities should be open for extension but closed for modification.
Design modules so new functionality can be added without changing existing code.
软件实体应对扩展开放,对修改关闭。
设计模块时,应确保无需修改现有代码即可添加新功能。

Liskov Substitution Principle (LSP)

里氏替换原则(LSP)

Subtypes must be substitutable for their base types.
Any code that works with a base type should work correctly with any subtype.
子类型必须能够替换其基类型。
任何适用于基类型的代码都应能正确处理其子类型。

Interface Segregation Principle (ISP)

接口隔离原则(ISP)

Clients should not be forced to depend on interfaces they do not use.
Prefer many small, specific interfaces over one large, general interface.
客户端不应被迫依赖它们不需要的接口。
优先选择多个小型、专用的接口,而非一个大型、通用的接口。

Dependency Inversion Principle (DIP)

依赖倒置原则(DIP)

High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend on details. Details should depend on abstractions.
高层模块不应依赖低层模块,两者都应依赖抽象。
抽象不应依赖细节,细节应依赖抽象。

Coupling and Cohesion

耦合与内聚

Maximize cohesion, minimize coupling.
最大化内聚,最小化耦合。

Cohesion

内聚

Cohesion measures how strongly related the responsibilities of a module are. High cohesion means a module does one thing well.
Signs of low cohesion:
  • Methods that don't use most of the class's instance variables
  • Unrelated methods grouped in the same class
  • Difficulty naming the class without using "and" or "or"
内聚衡量模块内各职责之间的关联程度。高内聚意味着模块能很好地完成单一任务。
低内聚的迹象:
  • 方法未使用类的大部分实例变量
  • 不相关的方法被归到同一个类中
  • 难以给类命名,除非使用“and”或“or”

Coupling

耦合

Coupling measures the degree of interdependence between modules. Low coupling means modules can change independently.
耦合衡量模块之间的相互依赖程度。低耦合意味着模块可以独立变更。

Connascence

共生性(Connascence)

Connascence provides a framework for understanding and measuring coupling. Two components are connascent if a change to one requires a change to the other.
共生性提供了一个理解和衡量耦合的框架。如果修改一个组件需要同时修改另一个组件,那么这两个组件就是共生的。

Dimensions of Connascence

共生性的维度

  • Strength: How difficult is it to refactor?
  • Locality: How close are the coupled components?
  • Degree: How many components are affected?
  • 强度:重构的难度有多大?
  • 局部性:耦合的组件距离有多近?
  • 程度:有多少组件会受到影响?

Types of Static Connascence (weakest to strongest)

静态共生性的类型(从弱到强)

  1. Connascence of Name (CoN): Components agree on names
    • Weakest form; easy to refactor with rename tools
  2. Connascence of Type (CoT): Components agree on types
    • Slightly stronger; type changes propagate
  3. Connascence of Meaning (CoM): Components agree on value meanings
    • Often appears as magic numbers or strings
    • Refactor to CoN by introducing named constants
  4. Connascence of Position (CoP): Components agree on order
    • Common in positional arguments
    • Refactor to CoN using keyword arguments or objects
  5. Connascence of Algorithm (CoA): Components agree on algorithm
    • Example: encoder and decoder must use same algorithm
    • Encapsulate the algorithm in a shared module
  1. 名称共生(CoN):组件使用相同的名称
    • 最弱的形式;使用重命名工具即可轻松重构
  2. 类型共生(CoT):组件使用相同的类型
    • 强度稍高;类型变更会传播开来
  3. 含义共生(CoM):组件对值的含义达成共识
    • 通常表现为魔法数字或字符串
    • 通过引入命名常量重构为名称共生
  4. 位置共生(CoP):组件对顺序达成共识
    • 常见于位置参数
    • 使用关键字参数或对象重构为名称共生
  5. 算法共生(CoA):组件使用相同的算法
    • 示例:编码器和解码器必须使用相同的算法
    • 将算法封装在共享模块中

Types of Dynamic Connascence (stronger than static)

动态共生性的类型(比静态共生性更强)

  1. Connascence of Execution (CoE): Order of execution matters
  2. Connascence of Timing (CoT): Timing of execution matters
  3. Connascence of Values (CoV): Values must change together
  4. Connascence of Identity (CoI): Components must reference same instance
  1. 执行共生(CoE):执行顺序很重要
  2. 时序共生(CoT):执行的时间安排很重要
  3. 值共生(CoV):值必须同步变更
  4. 标识共生(CoI):组件必须引用同一个实例

Refactoring Guidance

重构指导

  • Prefer weaker forms of connascence over stronger forms
  • Reduce the degree of connascence (fewer coupled components)
  • Increase locality (keep coupled components close together)
  • Convert dynamic connascence to static when possible
  • 优先选择较弱形式的共生性,而非较强形式
  • 降低共生性的程度(减少耦合的组件数量)
  • 提高局部性(将耦合的组件放在一起)
  • 尽可能将动态共生性转换为静态共生性

Design Heuristics

设计启发式

  • Favor composition over inheritance
  • Program to interfaces, not implementations
  • Encapsulate what varies
  • Strive for loosely coupled designs
  • Keep classes focused and small
  • 优先使用组合而非继承
  • 针对接口编程,而非针对实现编程
  • 封装变化的部分
  • 力求实现松耦合设计
  • 保持类的专注性和小巧性