minimal-abstractions
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMinimal Abstractions
极简抽象设计
Quick Start
快速开始
Before adding a new abstraction (interface, abstract class, wrapper, layer), ask:
- Does a similar abstraction already exist in this project?
- Are there 2+ concrete use cases requiring this abstraction RIGHT NOW?
- Is the complexity cost justified by actual flexibility needs?
If any answer is "no" or "maybe" → Don't add it. Use the simplest solution that works.
在添加新的抽象设计(interface、abstract class、包装器、层级)之前,请先问自己以下问题:
- 项目中是否已存在类似的抽象设计?
- 目前是否有2个及以上的具体用例需要该抽象设计?
- 该抽象带来的复杂度成本是否能被实际的灵活性需求所证明?
如果任何一个问题的答案是“否”或“可能”→ 不要添加该抽象。使用最简单的可行方案即可。
Table of Contents
目录
- When to Use This Skill
- What This Skill Does
- Core Philosophy
- Abstraction Evaluation Checklist
- Detection Patterns (Red Flags)
- Examples: Good vs Over-Engineered
- Integration with Architecture Validation
- Expected Outcomes
- Red Flags to Avoid
- 何时使用该能力
- 该能力能做什么
- 核心理念
- 抽象设计评估清单
- 检测模式(红色预警信号)
- 示例:合理设计 vs 过度设计
- 与架构验证的集成
- 预期成果
- 需要避免的红色预警信号
When to Use This Skill
何时使用该能力
Explicit Triggers (User asks):
- "Is this abstraction necessary?"
- "Are we over-engineering this?"
- "Too many layers in this code"
- "Simplify this architecture"
- "Reduce complexity"
- "Do we need this interface/wrapper/layer?"
- "Should we use [design pattern]?"
Implicit Triggers (Autonomous invocation):
- Reviewing pull requests with new interfaces/abstract classes
- Architecture proposals introducing new layers
- Code reviews where new patterns are introduced
- Refactoring tasks aimed at simplification
- When a new abstraction is proposed and only one implementation exists
Debugging/Problem Triggers:
- Maintenance burden is high due to abstraction complexity
- Team members confused by excessive indirection
- Tests are difficult to write due to layering
- Simple changes require touching multiple abstraction layers
显式触发场景(用户提问):
- “这个抽象是否必要?”
- “我们是不是过度设计了?”
- “这段代码的层级太多了”
- “简化这个架构”
- “降低复杂度”
- “我们需要这个接口/包装器/层级吗?”
- “我们应该使用[设计模式]吗?”
隐式触发场景(自动调用):
- 评审包含新interface/abstract class的拉取请求
- 评审引入新层级的架构提案
- 代码评审中出现新设计模式
- 以简化为目标的重构任务
- 当仅存在一个实现的新抽象设计被提出时
调试/问题触发场景:
- 由于抽象复杂度导致维护负担过重
- 团队成员因过度间接调用而感到困惑
- 由于层级划分导致测试难以编写
- 简单的变更需要修改多个抽象层级
What This Skill Does
该能力能做什么
This skill provides a systematic framework for:
- Evaluating whether new abstractions are warranted
- Detecting over-engineering and unnecessary complexity
- Guiding developers to use existing project abstractions
- Preventing abstraction proliferation
- Simplifying code by removing unneeded layers
该能力提供一个系统化框架,用于:
- 评估新抽象设计是否合理
- 检测过度工程和不必要的复杂度
- 引导开发者使用项目已有的抽象设计
- 避免抽象设计的泛滥
- 通过移除不必要的层级来简化代码
Instructions
操作指南
When evaluating an abstraction:
- Search for existing abstractions - Use Grep/Read to find similar patterns in codebase
- Apply the evaluation checklist - Run through all 5 questions in section 4
- Check for red flags - Scan code for patterns in section 5
- Recommend simpler alternative - Provide concrete code example
- Document decision - Explain why abstraction is/isn't needed
评估抽象设计时,请遵循以下步骤:
- 搜索已有抽象设计 - 使用Grep/Read工具在代码库中查找类似模式
- 应用评估清单 - 逐一核对第4节中的5个问题
- 检查红色预警信号 - 扫描代码中是否存在第5节中的模式
- 推荐更简单的替代方案 - 提供具体的代码示例
- 记录决策结果 - 说明该抽象设计是否必要的原因
Core Philosophy
核心理念
The Abstraction Principle
抽象设计原则
Abstractions are not free - every interface, wrapper, layer, or pattern adds:
- Cognitive load (developers must understand the abstraction)
- Maintenance burden (more code to test, debug, refactor)
- Indirection cost (harder to trace execution flow)
- Rigidity (abstractions create assumptions that resist change)
When abstractions ARE valuable:
- Multiple concrete implementations exist or are planned imminently
- Decoupling is critical (e.g., domain from infrastructure in Clean Architecture)
- Testability requires dependency injection
- Third-party integrations need isolation
When abstractions are NOT valuable:
- "We might need it someday" (YAGNI - You Aren't Gonna Need It)
- "It's a best practice" (without understanding why)
- Only one implementation exists and no others are planned
- Wrapping for wrapping's sake
抽象设计并非无成本 - 每个interface、包装器、层级或模式都会增加:
- 认知负担(开发者必须理解该抽象设计)
- 维护成本(需要测试、调试、重构更多代码)
- 间接调用成本(追踪执行流程变得更困难)
- 僵化性(抽象设计会形成阻碍变更的假设)
抽象设计有价值的场景:
- 已存在或即将存在多个具体实现
- 解耦至关重要(例如Clean Architecture中领域层与基础设施层的解耦)
- 可测试性依赖依赖注入
- 需要隔离第三方集成
抽象设计无价值的场景:
- “我们以后可能会用到”(违反YAGNI原则 - You Aren't Gonna Need It)
- “这是最佳实践”(但未理解其背后原因)
- 仅存在一个实现且无其他实现计划
- 为了包装而包装,没有实际价值
Prefer Existing Abstractions
优先使用已有抽象设计
Before creating a new abstraction:
- Search the codebase for similar patterns
- Extend or adapt existing abstractions
- Reuse project-standard patterns (e.g., Repository, Service, Handler)
- Only create new abstractions when existing ones truly don't fit
在创建新的抽象设计之前:
- 在代码库中搜索类似模式
- 扩展或适配已有抽象设计
- 复用项目标准模式(例如Repository、Service、Handler)
- 仅当已有抽象设计完全不适用时,才创建新的抽象设计
Abstraction Evaluation Checklist
抽象设计评估清单
Use this checklist before adding ANY new abstraction (interface, abstract class, wrapper, layer):
在添加任何新的抽象设计(interface、abstract class、包装器、层级)之前,请使用以下清单进行评估:
Question 1: Does this abstraction already exist?
问题1:该抽象设计是否已存在?
- Searched codebase for similar interfaces/abstractions
- Checked project architecture docs for standard patterns
- Reviewed existing layers (domain, application, infrastructure)
- Considered extending existing abstractions instead
Action: If similar abstraction exists → Use it. Don't create a new one.
- 在代码库中搜索了类似的interface/抽象设计
- 查阅了项目架构文档中的标准模式
- 检查了现有层级(领域层、应用层、基础设施层)
- 考虑过扩展已有抽象设计而非创建新的
行动: 如果存在类似抽象设计 → 使用已有设计,不要创建新的。
Question 2: Do we have 2+ concrete implementations RIGHT NOW?
问题2:目前是否有2个及以上的具体实现?
- Count current implementations (not hypothetical future ones)
- Verify implementations are actually different (not just copy-paste)
- Check if "multiple implementations" are really needed
Action: If <2 implementations → Skip the abstraction. Use concrete implementation directly.
- 统计当前的实现数量(不包括假设的未来实现)
- 验证这些实现确实存在差异(而非简单复制粘贴)
- 确认是否真的需要“多个实现”
行动: 如果实现数量<2 → 跳过该抽象设计,直接使用具体实现。
Question 3: Is there a concrete business/technical requirement?
问题3:是否有具体的业务/技术需求?
- Can you name the specific requirement driving this abstraction?
- Is the requirement current (not speculative)?
- Would removing this abstraction make the code harder to maintain?
Action: If requirement is speculative → Don't build it yet. Wait for actual need.
- 你能否说出驱动该抽象设计的具体需求?
- 该需求是否是当前存在的(而非推测性的)?
- 如果移除该抽象设计,代码维护会变得更困难吗?
行动: 如果需求是推测性的 → 暂时不要构建,等待实际需求出现。
Question 4: What is the complexity cost?
问题4:复杂度成本是多少?
- Count files touched to add this abstraction
- Estimate lines of code added (interface + implementations + tests)
- Consider cognitive load for new team members
- Evaluate impact on debugging and tracing
Action: If cost > benefit → Simplify. Use direct solution.
- 统计添加该抽象设计需要修改的文件数量
- 估算新增代码行数(interface + 实现 + 测试)
- 考虑新团队成员的认知负担
- 评估对调试和追踪执行流程的影响
行动: 如果成本>收益 → 简化方案,使用直接的解决方案。
Question 5: Can we solve this with simpler patterns?
问题5:我们能用更简单的模式解决这个问题吗?
- Would a simple function work instead of an interface?
- Could dependency injection handle this without abstraction?
- Is this trying to solve a problem we don't have?
Action: If simpler solution exists → Use it.
- 用简单的函数替代interface是否可行?
- 不使用抽象设计,仅依赖依赖注入能否解决问题?
- 这是不是在解决一个我们根本不存在的问题?
行动: 如果存在更简单的解决方案 → 使用该方案。
Detection Patterns (Red Flags)
检测模式(红色预警信号)
Red Flag 1: Lonely Interface
红色预警1:孤立的Interface
python
undefinedpython
undefined❌ Over-engineered: Interface with only one implementation
❌ 过度设计:仅含一个实现的Interface
class DataProcessor(Protocol):
def process(self, data: dict) -> dict: ...
class JsonDataProcessor: # Only implementation
def process(self, data: dict) -> dict:
return transform_json(data)
**Why it's a red flag:** No actual polymorphism. The interface adds indirection without benefit.
**Better approach:**
```pythonclass DataProcessor(Protocol):
def process(self, data: dict) -> dict: ...
class JsonDataProcessor: # 唯一的实现
def process(self, data: dict) -> dict:
return transform_json(data)
**预警原因:** 没有实际的多态性。该Interface仅增加了间接调用,没有任何收益。
**更好的方案:**
```python✅ Simple: Direct implementation
✅ 简洁方案:直接实现
def process_json_data(data: dict) -> dict:
return transform_json(data)
undefineddef process_json_data(data: dict) -> dict:
return transform_json(data)
undefinedRed Flag 2: Wrapper with No Value
红色预警2:无价值的包装器
python
undefinedpython
undefined❌ Over-engineered: Wrapper that just forwards calls
❌ 过度设计:仅转发调用的包装器
class DatabaseWrapper:
def init(self, db: Database):
self._db = db
def query(self, sql: str) -> list:
return self._db.query(sql) # Just forwarding
**Why it's a red flag:** No transformation, validation, or added behavior. Pure indirection.
**Better approach:** Use the database directly or add actual value (caching, retry, validation).class DatabaseWrapper:
def init(self, db: Database):
self._db = db
def query(self, sql: str) -> list:
return self._db.query(sql) # 仅转发调用
**预警原因:** 没有进行转换、验证或添加任何实际行为,纯粹是间接调用。
**更好的方案:** 直接使用数据库,或者添加实际价值(缓存、重试、验证)。Red Flag 3: Layer for Layer's Sake
红色预警3:为了分层而分层
python
undefinedpython
undefined❌ Over-engineered: Unnecessary service layer
❌ 过度设计:不必要的服务层
class UserRepository: # Already exists
def get_user(self, id: int) -> User: ...
class UserService: # Adds nothing
def init(self, repo: UserRepository):
self.repo = repo
def get_user(self, id: int) -> User:
return self.repo.get_user(id) # Just forwarding
**Why it's a red flag:** Service layer adds no business logic, validation, or orchestration.
**Better approach:** Use repository directly until business logic is needed.class UserRepository: # 已存在的仓储类
def get_user(self, id: int) -> User: ...
class UserService: # 没有任何实际作用
def init(self, repo: UserRepository):
self.repo = repo
def get_user(self, id: int) -> User:
return self.repo.get_user(id) # 仅转发调用
**预警原因:** 服务层没有添加任何业务逻辑、验证或编排逻辑。
**更好的方案:** 在需要业务逻辑之前,直接使用仓储类。Red Flag 4: Pattern for Pattern's Sake
红色预警4:为了模式而模式
python
undefinedpython
undefined❌ Over-engineered: Factory for single type
❌ 过度设计:针对单一类型的工厂模式
class UserFactory:
@staticmethod
def create_user(name: str, email: str) -> User:
return User(name=name, email=email)
**Why it's a red flag:** Factory pattern used without variation or complexity justification.
**Better approach:**
```pythonclass UserFactory:
@staticmethod
def create_user(name: str, email: str) -> User:
return User(name=name, email=email)
**预警原因:** 在没有变化或复杂度支撑的情况下使用工厂模式。
**更好的方案:**
```python✅ Simple: Direct construction
✅ 简洁方案:直接实例化
user = User(name="Alice", email="alice@example.com")
undefineduser = User(name="Alice", email="alice@example.com")
undefinedRed Flag 5: Premature Generalization
红色预警5:过早的泛化
python
undefinedpython
undefined❌ Over-engineered: Generic solution for specific problem
❌ 过度设计:针对特定问题的通用解决方案
class ConfigLoader(Generic[T]):
def load(self, source: str, parser: Parser[T]) -> T: ...
class JsonParser(Parser[dict]): ...
class YamlParser(Parser[dict]): ...
**Why it's a red flag:** Generic abstraction built before knowing actual requirements.
**Better approach:** Start with simple JSON config loader. Generalize when second format is needed.class ConfigLoader(Generic[T]):
def load(self, source: str, parser: Parser[T]) -> T: ...
class JsonParser(Parser[dict]): ...
class YamlParser(Parser[dict]): ...
**预警原因:** 在了解实际需求之前就构建了通用抽象设计。
**更好的方案:** 从简单的JSON配置加载器开始,当需要支持第二种格式时再进行泛化。Examples: Good vs Over-Engineered
示例:合理设计 vs 过度设计
Example 1: Repository Pattern
示例1:仓储模式
Over-Engineered:
python
undefined过度设计:
python
undefinedUnnecessary: Abstract repository + generic base + implementation
不必要的设计:抽象仓储 + 通用基类 + 实现
class Repository(Protocol, Generic[T]):
def get(self, id: int) -> T: ...
def save(self, entity: T) -> None: ...
class BaseRepository(Generic[T]): # Generic base
def validate(self, entity: T) -> bool: ...
class UserRepository(BaseRepository[User]): # Concrete
def get(self, id: int) -> User: ...
def save(self, user: User) -> None: ...
**Right-Sized:**
```pythonclass Repository(Protocol, Generic[T]):
def get(self, id: int) -> T: ...
def save(self, entity: T) -> None: ...
class BaseRepository(Generic[T]): # 通用基类
def validate(self, entity: T) -> bool: ...
class UserRepository(BaseRepository[User]): # 具体实现
def get(self, id: int) -> User: ...
def save(self, user: User) -> None: ...
**合理设计:**
```pythonClean Architecture: Protocol in domain, implementation in infrastructure
整洁架构:领域层定义Protocol,基础设施层实现
domain/repositories.py
domain/repositories.py
class UserRepository(Protocol): # Interface for dependency inversion
def get_user(self, id: int) -> User: ...
def save_user(self, user: User) -> None: ...
class UserRepository(Protocol): # 用于依赖倒置的接口
def get_user(self, id: int) -> User: ...
def save_user(self, user: User) -> None: ...
infrastructure/repositories.py
infrastructure/repositories.py
class SqlUserRepository: # Concrete implementation
def get_user(self, id: int) -> User: ...
def save_user(self, user: User) -> None: ...
undefinedclass SqlUserRepository: # 具体实现
def get_user(self, id: int) -> User: ...
def save_user(self, user: User) -> None: ...
undefinedExample 2: Service Layer
示例2:服务层
Over-Engineered:
python
undefined过度设计:
python
undefinedUnnecessary: Service that just forwards to repository
不必要的设计:仅转发至仓储的服务层
class UserService:
def init(self, repo: UserRepository):
self.repo = repo
def get_user(self, id: int) -> User:
return self.repo.get_user(id) # No business logic!
**Right-Sized:**
```pythonclass UserService:
def init(self, repo: UserRepository):
self.repo = repo
def get_user(self, id: int) -> User:
return self.repo.get_user(id) # 没有任何业务逻辑!
**合理设计:**
```pythonUse repository directly until business logic emerges
在业务逻辑出现之前直接使用仓储类
class AuthenticationHandler:
def init(self, user_repo: UserRepository):
self.user_repo = user_repo
def authenticate(self, email: str, password: str) -> Result[User, AuthError]:
user = self.user_repo.get_user_by_email(email)
if not user:
return Err(AuthError.USER_NOT_FOUND)
if not verify_password(password, user.password_hash):
return Err(AuthError.INVALID_PASSWORD)
return Ok(user)undefinedclass AuthenticationHandler:
def init(self, user_repo: UserRepository):
self.user_repo = user_repo
def authenticate(self, email: str, password: str) -> Result[User, AuthError]:
user = self.user_repo.get_user_by_email(email)
if not user:
return Err(AuthError.USER_NOT_FOUND)
if not verify_password(password, user.password_hash):
return Err(AuthError.INVALID_PASSWORD)
return Ok(user)undefinedExample 3: Reusing Existing Abstractions
示例3:复用已有抽象设计
Over-Engineered:
python
undefined过度设计:
python
undefinedProject already has Repository pattern
项目已存在仓储模式
Adding NEW abstraction for similar purpose:
为类似用途添加新的抽象设计:
class DataAccessLayer(Protocol): # Duplicates Repository!
def fetch(self, id: int) -> Entity: ...
def persist(self, entity: Entity) -> None: ...
**Right-Sized:**
```pythonclass DataAccessLayer(Protocol): # 与仓储模式重复!
def fetch(self, id: int) -> Entity: ...
def persist(self, entity: Entity) -> None: ...
**合理设计:**
```pythonUse existing Repository pattern
使用已有的仓储模式
class ProductRepository(Protocol): # Follows project convention
def get_product(self, id: int) -> Product: ...
def save_product(self, product: Product) -> None: ...
undefinedclass ProductRepository(Protocol): # 遵循项目约定
def get_product(self, id: int) -> Product: ...
def save_product(self, product: Product) -> None: ...
undefinedIntegration with Architecture Validation
与架构验证的集成
This skill complements existing architecture validation skills:
Use with:
- - Check layer boundaries while avoiding unnecessary layers
architecture-validate-architecture - - Ensure layers are necessary and well-justified
architecture-validate-layer-boundaries - - Evaluate abstractions during PR review
quality-code-review
Integration pattern:
- Run architecture validation to check existing patterns
- Use minimal-abstractions to evaluate NEW abstractions
- Ensure new code follows project patterns (don't reinvent)
该能力可与现有架构验证能力互补:
搭配使用:
- - 检查边界的同时避免不必要的层级
architecture-validate-architecture - - 确保层级是必要且合理的
architecture-validate-layer-boundaries - - 在PR评审中评估抽象设计
quality-code-review
集成模式:
- 运行架构验证以检查现有模式
- 使用极简抽象设计能力评估新的抽象设计
- 确保新代码遵循项目模式(不要重新发明轮子)
Expected Outcomes
预期成果
Successful Simplification
成功简化后的效果
Before:
src/
├── domain/
│ ├── interfaces/user_repository.py
│ ├── interfaces/user_service.py
│ ├── interfaces/user_validator.py
├── application/
│ ├── services/user_service.py (forwards to repo)
│ ├── validators/user_validator.py (just calls validate())
├── infrastructure/
│ ├── repositories/user_repository.pyAfter (applying minimal-abstractions):
src/
├── domain/
│ ├── repositories.py (UserRepository protocol)
│ ├── models.py (User with validation)
├── application/
│ ├── handlers.py (CreateUserHandler with actual business logic)
├── infrastructure/
│ ├── repositories.py (SqlUserRepository)Metrics:
- 40% fewer files
- 60% less indirection
- Same functionality
- Clearer execution paths
简化前:
src/
├── domain/
│ ├── interfaces/user_repository.py
│ ├── interfaces/user_service.py
│ ├── interfaces/user_validator.py
├── application/
│ ├── services/user_service.py (转发至仓储)
│ ├── validators/user_validator.py (仅调用validate())
├── infrastructure/
│ ├── repositories/user_repository.py应用极简抽象设计后:
src/
├── domain/
│ ├── repositories.py (UserRepository protocol)
│ ├── models.py (包含验证逻辑的User)
├── application/
│ ├── handlers.py (包含实际业务逻辑的CreateUserHandler)
├── infrastructure/
│ ├── repositories.py (SqlUserRepository)指标:
- 文件数量减少40%
- 间接调用减少60%
- 功能保持不变
- 执行路径更清晰
Validation Output
验证输出示例
Abstraction Evaluation: ProductService
✅ Checklist Results:
❌ Does abstraction already exist? YES - Repository pattern exists
❌ 2+ implementations? NO - Only one service planned
❌ Concrete requirement? NO - "We might need microservices later"
⚠️ Complexity cost: +3 files, +200 LOC, +2 layers indirection
✅ Simpler solution exists? YES - Use repository + handler directly
Recommendation: SKIP THIS ABSTRACTION
- Use existing ProductRepository
- Add business logic to ProductHandler
- Wait for concrete multi-service requirement before abstracting抽象设计评估:ProductService
✅ 清单结果:
❌ 该抽象是否已存在?是 - 项目已存在仓储模式
❌ 是否有2个及以上实现?否 - 仅计划了一个服务实现
❌ 是否有具体需求?否 - “我们以后可能需要微服务”
⚠️ 复杂度成本:新增3个文件,200行代码,增加2层间接调用
✅ 是否存在更简单的方案?是 - 直接使用仓储 + 处理器
建议:跳过该抽象设计
- 使用已有的ProductRepository
- 在ProductHandler中添加业务逻辑
- 等到有具体的多服务需求时再进行抽象Red Flags to Avoid
需要避免的红色预警信号
Anti-Patterns
反模式
- ❌ "We might need it later" (YAGNI violation)
- ❌ Creating interfaces with only one implementation
- ❌ Wrappers that just forward calls without adding value
- ❌ Service layers that add no business logic
- ❌ Generic solutions for specific problems
- ❌ Design patterns used without understanding why
- ❌ Creating new abstractions when project patterns exist
- ❌ “我们以后可能会用到”(违反YAGNI原则)
- ❌ 创建仅含一个实现的interface
- ❌ 仅转发调用而不添加价值的包装器
- ❌ 不添加任何业务逻辑的服务层
- ❌ 针对特定问题的通用解决方案
- ❌ 在不理解原因的情况下使用设计模式
- ❌ 当项目已有模式时创建新的抽象设计
Good Practices
最佳实践
- ✅ Use existing project abstractions first
- ✅ Wait for 2+ concrete implementations before abstracting
- ✅ Justify every layer with concrete requirements
- ✅ Prefer simple, direct solutions
- ✅ Question every new abstraction
- ✅ Measure complexity cost vs benefit
- ✅ Remove abstractions when they're no longer needed
- ✅ 优先使用项目已有的抽象设计
- ✅ 等到有2个及以上具体实现时再进行抽象
- ✅ 用具体需求证明每个层级的合理性
- ✅ 优先选择简单、直接的解决方案
- ✅ 质疑每个新抽象设计
- ✅ 衡量复杂度成本与收益
- ✅ 当抽象设计不再需要时将其移除
Notes
注意事项
Key Principle: Every abstraction must justify its existence with concrete, current requirements - not hypothetical future needs.
Balance: This skill advocates for minimal abstractions, but respects architectural patterns when they provide real value (e.g., Clean Architecture's dependency inversion).
When in doubt: Start simple. Add abstractions when pain points emerge, not before.
核心原则: 每个抽象设计都必须用具体的、当前存在的需求来证明其合理性,而非假设的未来需求。
平衡: 该能力倡导极简抽象设计,但在架构模式能带来实际价值时(例如Clean Architecture的依赖倒置),仍需遵循这些模式。
存疑时的处理方式: 从简单方案开始。当痛点出现时再添加抽象设计,而非提前添加。