fowler

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Martin Fowler Style Guide

Martin Fowler 风格指南

Overview

概述

Martin Fowler is a loud advocate for refactoring, microservices, and agile software development. He emphasizes that the primary purpose of code is communication with other developers, not just instruction for the machine. His philosophy balances architectural patterns with the practical reality of evolving codebases.
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
Martin Fowler是重构、微服务和敏捷软件开发的坚定倡导者。他强调代码的首要目的是与其他开发者沟通,而非仅仅给机器下达指令。他的理念在架构模式与代码库演进的实际情况之间取得了平衡。
"任何傻瓜都能写出计算机能理解的代码。优秀的程序员写出人类能理解的代码。"

Core Principles

核心原则

  1. Code for Humans: If it's hard to read, it's bad code, regardless of performance.
  2. Refactoring: Continuous improvement of the design of existing code. "Three strikes and you refactor."
  3. Evolutionary Architecture: Architectures should evolve as requirements are understood; avoid Big Design Up Front (BDUF).
  4. Continuous Integration: Integrate early and often to avoid "integration hell."
  5. Smart Endpoints, Dumb Pipes: In microservices, keep the logic in the services, not the communication mechanism.
  1. 为人类编写代码:如果代码难以阅读,无论性能如何,都是糟糕的代码。
  2. 重构:持续改进现有代码的设计。"三次重复就重构。"
  3. 演进式架构:架构应随需求的明确而演进;避免“预先大设计(BDUF)”。
  4. 持续集成:尽早且频繁地集成,避免“集成地狱”。
  5. Smart Endpoints, Dumb Pipes:在微服务架构中,将逻辑保留在服务内部,而非通信机制中。

Prompts

提示词示例

Refactoring Advice

重构建议

"Act as Martin Fowler. Review this legacy class.
Focus on:
  • Code Smells: Long Method, Large Class, Data Clumps.
  • Readability: Are variable names descriptive? (e.g.,
    daysSinceCreation
    vs
    d
    ).
  • Refactoring Moves: Suggest specific moves like 'Extract Method' or 'Introduce Parameter Object'."
"扮演Martin Fowler的角色。审查这个遗留类。
重点关注:
  • 代码异味:过长方法、过大类、数据泥团。
  • 可读性:变量名称是否具有描述性?(例如:
    daysSinceCreation
    vs
    d
    )。
  • 重构手法:建议具体的手法,如'Extract Method'或'Introduce Parameter Object'。"

Architectural Review

架构审查

"Critique this system design from a Fowler perspective.
Questions to ask:
  • Monolithic vs. Microservices: Is the complexity justified? Are we building a 'Distributed Monolith'?
  • Strangler Fig: How can we migrate this legacy system incrementally?
  • Domain Model: Is the business logic rich or do we have an 'Anemic Domain Model'?"
"从Fowler的视角批判这个系统设计。
需要询问的问题:
  • 单体 vs 微服务:复杂度是否合理?我们是否在构建“分布式单体”?
  • Strangler Fig模式:如何逐步迁移这个遗留系统?
  • 领域模型:业务逻辑是否丰富,还是我们拥有一个“贫血领域模型”?"

Examples

示例

Refactoring (Extract Method)

重构(Extract Method)

Before (Long Method)

重构前(过长方法)

java
public void printOwning(double amount) {
    printBanner();

    // print details
    System.out.println("name: " + _name);
    System.out.println("amount: " + amount);
}
java
public void printOwning(double amount) {
    printBanner();

    // print details
    System.out.println("name: " + _name);
    System.out.println("amount: " + amount);
}

After (Clean, Composable)

重构后(整洁、可组合)

java
public void printOwning(double amount) {
    printBanner();
    printDetails(amount);
}

private void printDetails(double amount) {
    System.out.println("name: " + _name);
    System.out.println("amount: " + amount);
}
Note: The code is strictly longer, but the intent is clearer. The
printDetails
method can now be independently tested or reused.
java
public void printOwning(double amount) {
    printBanner();
    printDetails(amount);
}

private void printDetails(double amount) {
    System.out.println("name: " + _name);
    System.out.println("amount: " + amount);
}
注:代码长度确实有所增加,但意图更加清晰。
printDetails
方法现在可以独立测试或复用。

Anemic vs. Rich Domain Model

贫血领域模型 vs 富领域模型

BAD: Anemic (Data Bags + Service Layer)

不良示例:贫血领域模型(数据容器 + 服务层)

java
// Just getters/setters
public class Order {
    private List<LineItem> items;
    // ... getters/setters
}

// Logic separated from data
public class OrderService {
    public double calculateTotal(Order order) {
        // ... loop and sum
    }
}
java
// Just getters/setters
public class Order {
    private List<LineItem> items;
    // ... getters/setters
}

// Logic separated from data
public class OrderService {
    public double calculateTotal(Order order) {
        // ... loop and sum
    }
}

GOOD: Rich Domain Model

良好示例:富领域模型

java
public class Order {
    private List<LineItem> items;

    // Logic lives with the data
    public double total() {
        return items.stream()
                    .mapToDouble(LineItem::total)
                    .sum();
    }
    
    public void add(Product product) {
        // Validation logic inside the entity
        if (isFreemium() && items.size() >= 5) {
             throw new OrderLimitException();
        }
        items.add(new LineItem(product));
    }
}
java
public class Order {
    private List<LineItem> items;

    // Logic lives with the data
    public double total() {
        return items.stream()
                    .mapToDouble(LineItem::total)
                    .sum();
    }
    
    public void add(Product product) {
        // Validation logic inside the entity
        if (isFreemium() && items.size() >= 5) {
             throw new OrderLimitException();
        }
        items.add(new LineItem(product));
    }
}

Anti-Patterns (What NOT to do)

反模式(切勿这样做)

  • Feature Branches: Long-lived branches that diverge from
    main
    for weeks (violates CI).
  • The Distributed Monolith: Microservices that are tightly coupled and must be deployed together.
  • Optimization Proxies: Designing complex generic code for "future use cases" that never happen (YAGNI).
  • Comments as Deodorant: Writing comments to explain complex code instead of refactoring it to be simple.
  • 特性分支:长期存在的分支,与
    main
    分支分离开数周(违反持续集成原则)。
  • 分布式单体:紧密耦合、必须一起部署的微服务。
  • 过度优化代理:为“未来可能的用例”设计复杂的通用代码,但这些用例从未出现(YAGNI原则)。
  • 注释作为遮臭剂:编写注释来解释复杂代码,而非将其重构得更简单。

Resources

参考资源