refactor

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Refactor

重构

Overview

概述

Improve code structure and readability without changing external behavior. Refactoring is gradual evolution, not revolution. Use this for improving existing code, not rewriting from scratch.
在不改变外部行为的前提下,改进代码结构与可读性。重构是渐进式的演化,而非彻底革新。适用于优化现有代码,而非从零重写。

When to Use

适用场景

Use this skill when:
  • Code is hard to understand or maintain
  • Functions/classes are too large
  • Code smells need addressing
  • Adding features is difficult due to code structure
  • User asks "clean up this code", "refactor this", "improve this"

在以下场景使用该技能:
  • 代码难以理解或维护
  • 函数/类过于庞大
  • 需要处理代码异味
  • 因代码结构问题导致新增功能困难
  • 用户提出“清理这段代码”“重构这个”“优化这段代码”等需求

Refactoring Principles

重构原则

The Golden Rules

黄金准则

  1. Behavior is preserved - Refactoring doesn't change what the code does, only how
  2. Small steps - Make tiny changes, test after each
  3. Version control is your friend - Commit before and after each safe state
  4. Tests are essential - Without tests, you're not refactoring, you're editing
  5. One thing at a time - Don't mix refactoring with feature changes
  1. 保留行为 - 重构仅改变代码的实现方式,不改变代码的功能
  2. 小步迭代 - 每次只做微小修改,修改后立即测试
  3. 善用版本控制 - 在每个安全状态前后都进行提交
  4. 测试是核心 - 没有测试的话,你不是在重构,只是在修改代码
  5. 一次只做一件事 - 不要将重构与功能开发混在一起

When NOT to Refactor

不适合重构的场景

- Code that works and won't change again (if it ain't broke...)
- Critical production code without tests (add tests first)
- When you're under a tight deadline
- "Just because" - need a clear purpose

- 运行正常且不会再变更的代码(如果没坏就别修...)
- 没有测试的核心生产代码(先添加测试)
- 处于紧迫截止日期时
- “只是想重构” - 需要明确的目的

Common Code Smells & Fixes

常见代码异味及修复方案

1. Long Method/Function

1. 过长方法/函数

diff
undefined
diff
undefined

BAD: 200-line function that does everything

糟糕:200行的全能函数

  • async function processOrder(orderId) {
  • // 50 lines: fetch order
  • // 30 lines: validate order
  • // 40 lines: calculate pricing
  • // 30 lines: update inventory
  • // 20 lines: create shipment
  • // 30 lines: send notifications
  • }
  • async function processOrder(orderId) {
  • // 50行:获取订单
  • // 30行:验证订单
  • // 40行:计算定价
  • // 30行:更新库存
  • // 20行:创建物流单
  • // 30行:发送通知
  • }

GOOD: Broken into focused functions

良好:拆分为专注单一功能的函数

  • async function processOrder(orderId) {
  • const order = await fetchOrder(orderId);
  • validateOrder(order);
  • const pricing = calculatePricing(order);
  • await updateInventory(order);
  • const shipment = await createShipment(order);
  • await sendNotifications(order, pricing, shipment);
  • return { order, pricing, shipment };
  • }
undefined
  • async function processOrder(orderId) {
  • const order = await fetchOrder(orderId);
  • validateOrder(order);
  • const pricing = calculatePricing(order);
  • await updateInventory(order);
  • const shipment = await createShipment(order);
  • await sendNotifications(order, pricing, shipment);
  • return { order, pricing, shipment };
  • }
undefined

2. Duplicated Code

2. 重复代码

diff
undefined
diff
undefined

BAD: Same logic in multiple places

糟糕:多处存在相同逻辑

  • function calculateUserDiscount(user) {
  • if (user.membership === 'gold') return user.total * 0.2;
  • if (user.membership === 'silver') return user.total * 0.1;
  • return 0;
  • }
  • function calculateOrderDiscount(order) {
  • if (order.user.membership === 'gold') return order.total * 0.2;
  • if (order.user.membership === 'silver') return order.total * 0.1;
  • return 0;
  • }
  • function calculateUserDiscount(user) {
  • if (user.membership === 'gold') return user.total * 0.2;
  • if (user.membership === 'silver') return user.total * 0.1;
  • return 0;
  • }
  • function calculateOrderDiscount(order) {
  • if (order.user.membership === 'gold') return order.total * 0.2;
  • if (order.user.membership === 'silver') return order.total * 0.1;
  • return 0;
  • }

GOOD: Extract common logic

良好:提取公共逻辑

  • function getMembershipDiscountRate(membership) {
  • const rates = { gold: 0.2, silver: 0.1 };
  • return rates[membership] || 0;
  • }
  • function calculateUserDiscount(user) {
  • return user.total * getMembershipDiscountRate(user.membership);
  • }
  • function calculateOrderDiscount(order) {
  • return order.total * getMembershipDiscountRate(order.user.membership);
  • }
undefined
  • function getMembershipDiscountRate(membership) {
  • const rates = { gold: 0.2, silver: 0.1 };
  • return rates[membership] || 0;
  • }
  • function calculateUserDiscount(user) {
  • return user.total * getMembershipDiscountRate(user.membership);
  • }
  • function calculateOrderDiscount(order) {
  • return order.total * getMembershipDiscountRate(order.user.membership);
  • }
undefined

3. Large Class/Module

3. 过大的类/模块

diff
undefined
diff
undefined

BAD: God object that knows too much

糟糕:无所不知的上帝对象

  • class UserManager {
  • createUser() { /* ... */ }
  • updateUser() { /* ... */ }
  • deleteUser() { /* ... */ }
  • sendEmail() { /* ... */ }
  • generateReport() { /* ... */ }
  • handlePayment() { /* ... */ }
  • validateAddress() { /* ... */ }
  • // 50 more methods...
  • }
  • class UserManager {
  • createUser() { /* ... */ }
  • updateUser() { /* ... */ }
  • deleteUser() { /* ... */ }
  • sendEmail() { /* ... */ }
  • generateReport() { /* ... */ }
  • handlePayment() { /* ... */ }
  • validateAddress() { /* ... */ }
  • // 还有50多个方法...
  • }

GOOD: Single responsibility per class

良好:每个类单一职责

  • class UserService {
  • create(data) { /* ... */ }
  • update(id, data) { /* ... */ }
  • delete(id) { /* ... */ }
  • }
  • class EmailService {
  • send(to, subject, body) { /* ... */ }
  • }
  • class ReportService {
  • generate(type, params) { /* ... */ }
  • }
  • class PaymentService {
  • process(amount, method) { /* ... */ }
  • }
undefined
  • class UserService {
  • create(data) { /* ... */ }
  • update(id, data) { /* ... */ }
  • delete(id) { /* ... */ }
  • }
  • class EmailService {
  • send(to, subject, body) { /* ... */ }
  • }
  • class ReportService {
  • generate(type, params) { /* ... */ }
  • }
  • class PaymentService {
  • process(amount, method) { /* ... */ }
  • }
undefined

4. Long Parameter List

4. 过长参数列表

diff
undefined
diff
undefined

BAD: Too many parameters

糟糕:参数过多

  • function createUser(email, password, name, age, address, city, country, phone) {
  • /* ... */
  • }
  • function createUser(email, password, name, age, address, city, country, phone) {
  • /* ... */
  • }

GOOD: Group related parameters

良好:分组相关参数

  • interface UserData {
  • email: string;
  • password: string;
  • name: string;
  • age?: number;
  • address?: Address;
  • phone?: string;
  • }
  • function createUser(data: UserData) {
  • /* ... */
  • }
  • interface UserData {
  • email: string;
  • password: string;
  • name: string;
  • age?: number;
  • address?: Address;
  • phone?: string;
  • }
  • function createUser(data: UserData) {
  • /* ... */
  • }

EVEN BETTER: Use builder pattern for complex construction

更优:复杂构造使用建造者模式

  • const user = UserBuilder
  • .email('test@example.com')
  • .password('secure123')
  • .name('Test User')
  • .address(address)
  • .build();
undefined
  • const user = UserBuilder
  • .email('test@example.com')
  • .password('secure123')
  • .name('Test User')
  • .address(address)
  • .build();
undefined

5. Feature Envy

5. 特性依恋

diff
undefined
diff
undefined

BAD: Method that uses another object's data more than its own

糟糕:方法使用其他对象的数据远多于自身数据

  • class Order {
  • calculateDiscount(user) {
  • if (user.membershipLevel === 'gold') {
  •   return this.total * 0.2;
  • }
  • if (user.accountAge > 365) {
  •   return this.total * 0.1;
  • }
  • return 0;
  • }
  • }
  • class Order {
  • calculateDiscount(user) {
  • if (user.membershipLevel === 'gold') {
  •   return this.total * 0.2;
  • }
  • if (user.accountAge > 365) {
  •   return this.total * 0.1;
  • }
  • return 0;
  • }
  • }

GOOD: Move logic to the object that owns the data

良好:将逻辑移至拥有数据的对象

  • class User {
  • getDiscountRate(orderTotal) {
  • if (this.membershipLevel === 'gold') return 0.2;
  • if (this.accountAge > 365) return 0.1;
  • return 0;
  • }
  • }
  • class Order {
  • calculateDiscount(user) {
  • return this.total * user.getDiscountRate(this.total);
  • }
  • }
undefined
  • class User {
  • getDiscountRate(orderTotal) {
  • if (this.membershipLevel === 'gold') return 0.2;
  • if (this.accountAge > 365) return 0.1;
  • return 0;
  • }
  • }
  • class Order {
  • calculateDiscount(user) {
  • return this.total * user.getDiscountRate(this.total);
  • }
  • }
undefined

6. Primitive Obsession

6. 基本类型偏执

diff
undefined
diff
undefined

BAD: Using primitives for domain concepts

糟糕:使用基本类型表示领域概念

  • function sendEmail(to, subject, body) { /* ... */ }
  • sendEmail('user@example.com', 'Hello', '...');
  • function createPhone(country, number) {
  • return
    ${country}-${number}
    ;
  • }
  • function sendEmail(to, subject, body) { /* ... */ }
  • sendEmail('user@example.com', 'Hello', '...');
  • function createPhone(country, number) {
  • return
    ${country}-${number}
    ;
  • }

GOOD: Use domain types

良好:使用领域类型

  • class Email {
  • private constructor(public readonly value: string) {
  • if (!Email.isValid(value)) throw new Error('Invalid email');
  • }
  • static create(value: string) { return new Email(value); }
  • static isValid(email: string) { return /^[^\s@]+@[^\s@]+.[^\s@]+$/.test(email); }
  • }
  • class PhoneNumber {
  • constructor(
  • public readonly country: string,
  • public readonly number: string
  • ) {
  • if (!PhoneNumber.isValid(country, number)) throw new Error('Invalid phone');
  • }
  • toString() { return
    ${this.country}-${this.number}
    ; }
  • static isValid(country: string, number: string) { /* ... */ }
  • }
  • // Usage
  • const email = Email.create('user@example.com');
  • const phone = new PhoneNumber('1', '555-1234');
undefined
  • class Email {
  • private constructor(public readonly value: string) {
  • if (!Email.isValid(value)) throw new Error('Invalid email');
  • }
  • static create(value: string) { return new Email(value); }
  • static isValid(email: string) { return /^[^\s@]+@[^\s@]+.[^\s@]+$/.test(email); }
  • }
  • class PhoneNumber {
  • constructor(
  • public readonly country: string,
  • public readonly number: string
  • ) {
  • if (!PhoneNumber.isValid(country, number)) throw new Error('Invalid phone');
  • }
  • toString() { return
    ${this.country}-${this.number}
    ; }
  • static isValid(country: string, number: string) { /* ... */ }
  • }
  • // 使用示例
  • const email = Email.create('user@example.com');
  • const phone = new PhoneNumber('1', '555-1234');
undefined

7. Magic Numbers/Strings

7. 魔法数字/字符串

diff
undefined
diff
undefined

BAD: Unexplained values

糟糕:无注释的神秘值

  • if (user.status === 2) { /* ... */ }
  • const discount = total * 0.15;
  • setTimeout(callback, 86400000);
  • if (user.status === 2) { /* ... */ }
  • const discount = total * 0.15;
  • setTimeout(callback, 86400000);

GOOD: Named constants

良好:使用命名常量

  • const UserStatus = {
  • ACTIVE: 1,
  • INACTIVE: 2,
  • SUSPENDED: 3
  • } as const;
  • const DISCOUNT_RATES = {
  • STANDARD: 0.1,
  • PREMIUM: 0.15,
  • VIP: 0.2
  • } as const;
  • const ONE_DAY_MS = 24 * 60 * 60 * 1000;
  • if (user.status === UserStatus.INACTIVE) { /* ... */ }
  • const discount = total * DISCOUNT_RATES.PREMIUM;
  • setTimeout(callback, ONE_DAY_MS);
undefined
  • const UserStatus = {
  • ACTIVE: 1,
  • INACTIVE: 2,
  • SUSPENDED: 3
  • } as const;
  • const DISCOUNT_RATES = {
  • STANDARD: 0.1,
  • PREMIUM: 0.15,
  • VIP: 0.2
  • } as const;
  • const ONE_DAY_MS = 24 * 60 * 60 * 1000;
  • if (user.status === UserStatus.INACTIVE) { /* ... */ }
  • const discount = total * DISCOUNT_RATES.PREMIUM;
  • setTimeout(callback, ONE_DAY_MS);
undefined

8. Nested Conditionals

8. 嵌套条件语句

diff
undefined
diff
undefined

BAD: Arrow code

糟糕:箭头代码

  • function process(order) {
  • if (order) {
  • if (order.user) {
  •   if (order.user.isActive) {
  •     if (order.total > 0) {
  •       return processOrder(order);
  •     } else {
  •       return { error: 'Invalid total' };
  •     }
  •   } else {
  •     return { error: 'User inactive' };
  •   }
  • } else {
  •   return { error: 'No user' };
  • }
  • } else {
  • return { error: 'No order' };
  • }
  • }
  • function process(order) {
  • if (order) {
  • if (order.user) {
  •   if (order.user.isActive) {
  •     if (order.total > 0) {
  •       return processOrder(order);
  •     } else {
  •       return { error: 'Invalid total' };
  •     }
  •   } else {
  •     return { error: 'User inactive' };
  •   }
  • } else {
  •   return { error: 'No user' };
  • }
  • } else {
  • return { error: 'No order' };
  • }
  • }

GOOD: Guard clauses / early returns

良好:卫语句/提前返回

  • function process(order) {
  • if (!order) return { error: 'No order' };
  • if (!order.user) return { error: 'No user' };
  • if (!order.user.isActive) return { error: 'User inactive' };
  • if (order.total <= 0) return { error: 'Invalid total' };
  • return processOrder(order);
  • }
  • function process(order) {
  • if (!order) return { error: 'No order' };
  • if (!order.user) return { error: 'No user' };
  • if (!order.user.isActive) return { error: 'User inactive' };
  • if (order.total <= 0) return { error: 'Invalid total' };
  • return processOrder(order);
  • }

EVEN BETTER: Using Result type

更优:使用Result类型

  • function process(order): Result<ProcessedOrder, Error> {
  • return Result.combine([
  • validateOrderExists(order),
  • validateUserExists(order),
  • validateUserActive(order.user),
  • validateOrderTotal(order)
  • ]).flatMap(() => processOrder(order));
  • }
undefined
  • function process(order): Result<ProcessedOrder, Error> {
  • return Result.combine([
  • validateOrderExists(order),
  • validateUserExists(order),
  • validateUserActive(order.user),
  • validateOrderTotal(order)
  • ]).flatMap(() => processOrder(order));
  • }
undefined

9. Dead Code

9. 死代码

diff
undefined
diff
undefined

BAD: Unused code lingers

糟糕:残留的未使用代码

  • function oldImplementation() { /* ... */ }
  • const DEPRECATED_VALUE = 5;
  • import { unusedThing } from './somewhere';
  • // Commented out code
  • // function oldCode() { /* ... */ }
  • function oldImplementation() { /* ... */ }
  • const DEPRECATED_VALUE = 5;
  • import { unusedThing } from './somewhere';
  • // 注释掉的代码
  • // function oldCode() { /* ... */ }

GOOD: Remove it

良好:删除未使用代码

  • // Delete unused functions, imports, and commented code
  • // If you need it again, git history has it
undefined
  • // 删除未使用的函数、导入和注释代码
  • // 如果之后需要,Git历史记录里会有
undefined

10. Inappropriate Intimacy

10. 过度亲密

diff
undefined
diff
undefined

BAD: One class reaches deep into another

糟糕:一个类深入访问另一个类的内部

  • class OrderProcessor {
  • process(order) {
  • order.user.profile.address.street;  // Too intimate
  • order.repository.connection.config;  // Breaking encapsulation
  • }
  • }
  • class OrderProcessor {
  • process(order) {
  • order.user.profile.address.street;  // 过于亲密
  • order.repository.connection.config;  // 破坏封装
  • }
  • }

GOOD: Ask, don't tell

良好:请求,而非命令

  • class OrderProcessor {
  • process(order) {
  • order.getShippingAddress();  // Order knows how to get it
  • order.save();  // Order knows how to save itself
  • }
  • }

---
  • class OrderProcessor {
  • process(order) {
  • order.getShippingAddress();  // Order知道如何获取地址
  • order.save();  // Order知道如何保存自己
  • }
  • }

---

Extract Method Refactoring

提取方法重构

Before and After

重构前后对比

diff
undefined
diff
undefined

Before: One long function

重构前:单一长函数

  • function printReport(users) {
  • console.log('USER REPORT');
  • console.log('============');
  • console.log('');
  • console.log(
    Total users: ${users.length}
    );
  • console.log('');
  • console.log('ACTIVE USERS');
  • console.log('------------');
  • const active = users.filter(u => u.isActive);
  • active.forEach(u => {
  • console.log(`- ${u.name} (${u.email})`);
  • });
  • console.log('');
  • console.log(
    Active: ${active.length}
    );
  • console.log('');
  • console.log('INACTIVE USERS');
  • console.log('--------------');
  • const inactive = users.filter(u => !u.isActive);
  • inactive.forEach(u => {
  • console.log(`- ${u.name} (${u.email})`);
  • });
  • console.log('');
  • console.log(
    Inactive: ${inactive.length}
    );
  • }
  • function printReport(users) {
  • console.log('USER REPORT');
  • console.log('============');
  • console.log('');
  • console.log(
    Total users: ${users.length}
    );
  • console.log('');
  • console.log('ACTIVE USERS');
  • console.log('------------');
  • const active = users.filter(u => u.isActive);
  • active.forEach(u => {
  • console.log(`- ${u.name} (${u.email})`);
  • });
  • console.log('');
  • console.log(
    Active: ${active.length}
    );
  • console.log('');
  • console.log('INACTIVE USERS');
  • console.log('--------------');
  • const inactive = users.filter(u => !u.isActive);
  • inactive.forEach(u => {
  • console.log(`- ${u.name} (${u.email})`);
  • });
  • console.log('');
  • console.log(
    Inactive: ${inactive.length}
    );
  • }

After: Extracted methods

重构后:提取方法

  • function printReport(users) {
  • printHeader('USER REPORT');
  • console.log(
    Total users: ${users.length}\n
    );
  • printUserSection('ACTIVE USERS', users.filter(u => u.isActive));
  • printUserSection('INACTIVE USERS', users.filter(u => !u.isActive));
  • }
  • function printHeader(title) {
  • const line = '='.repeat(title.length);
  • console.log(title);
  • console.log(line);
  • console.log('');
  • }
  • function printUserSection(title, users) {
  • console.log(title);
  • console.log('-'.repeat(title.length));
  • users.forEach(u => console.log(
    - ${u.name} (${u.email})
    ));
  • console.log('');
  • console.log(
    ${title.split(' ')[0]}: ${users.length}
    );
  • console.log('');
  • }

---
  • function printReport(users) {
  • printHeader('USER REPORT');
  • console.log(
    Total users: ${users.length}\n
    );
  • printUserSection('ACTIVE USERS', users.filter(u => u.isActive));
  • printUserSection('INACTIVE USERS', users.filter(u => !u.isActive));
  • }
  • function printHeader(title) {
  • const line = '='.repeat(title.length);
  • console.log(title);
  • console.log(line);
  • console.log('');
  • }
  • function printUserSection(title, users) {
  • console.log(title);
  • console.log('-'.repeat(title.length));
  • users.forEach(u => console.log(
    - ${u.name} (${u.email})
    ));
  • console.log('');
  • console.log(
    ${title.split(' ')[0]}: ${users.length}
    );
  • console.log('');
  • }

---

Introducing Type Safety

引入类型安全性

From Untyped to Typed

从无类型到强类型

diff
undefined
diff
undefined

Before: No types

重构前:无类型

  • function calculateDiscount(user, total, membership, date) {
  • if (membership === 'gold' && date.getDay() === 5) {
  • return total * 0.25;
  • }
  • if (membership === 'gold') return total * 0.2;
  • return total * 0.1;
  • }
  • function calculateDiscount(user, total, membership, date) {
  • if (membership === 'gold' && date.getDay() === 5) {
  • return total * 0.25;
  • }
  • if (membership === 'gold') return total * 0.2;
  • return total * 0.1;
  • }

After: Full type safety

重构后:完全类型安全

  • type Membership = 'bronze' | 'silver' | 'gold';
  • interface User {
  • id: string;
  • name: string;
  • membership: Membership;
  • }
  • interface DiscountResult {
  • original: number;
  • discount: number;
  • final: number;
  • rate: number;
  • }
  • function calculateDiscount(
  • user: User,
  • total: number,
  • date: Date = new Date()
  • ): DiscountResult {
  • if (total < 0) throw new Error('Total cannot be negative');
  • let rate = 0.1; // Default bronze
  • if (user.membership === 'gold' && date.getDay() === 5) {
  • rate = 0.25; // Friday bonus for gold
  • } else if (user.membership === 'gold') {
  • rate = 0.2;
  • } else if (user.membership === 'silver') {
  • rate = 0.15;
  • }
  • const discount = total * rate;
  • return {
  • original: total,
  • discount,
  • final: total - discount,
  • rate
  • };
  • }

---
  • type Membership = 'bronze' | 'silver' | 'gold';
  • interface User {
  • id: string;
  • name: string;
  • membership: Membership;
  • }
  • interface DiscountResult {
  • original: number;
  • discount: number;
  • final: number;
  • rate: number;
  • }
  • function calculateDiscount(
  • user: User,
  • total: number,
  • date: Date = new Date()
  • ): DiscountResult {
  • if (total < 0) throw new Error('Total cannot be negative');
  • let rate = 0.1; // 默认bronze等级
  • if (user.membership === 'gold' && date.getDay() === 5) {
  • rate = 0.25; // 黄金会员周五额外折扣
  • } else if (user.membership === 'gold') {
  • rate = 0.2;
  • } else if (user.membership === 'silver') {
  • rate = 0.15;
  • }
  • const discount = total * rate;
  • return {
  • original: total,
  • discount,
  • final: total - discount,
  • rate
  • };
  • }

---

Design Patterns for Refactoring

重构常用设计模式

Strategy Pattern

策略模式

diff
undefined
diff
undefined

Before: Conditional logic

重构前:条件逻辑

  • function calculateShipping(order, method) {
  • if (method === 'standard') {
  • return order.total > 50 ? 0 : 5.99;
  • } else if (method === 'express') {
  • return order.total > 100 ? 9.99 : 14.99;
  • } else if (method === 'overnight') {
  • return 29.99;
  • }
  • }
  • function calculateShipping(order, method) {
  • if (method === 'standard') {
  • return order.total > 50 ? 0 : 5.99;
  • } else if (method === 'express') {
  • return order.total > 100 ? 9.99 : 14.99;
  • } else if (method === 'overnight') {
  • return 29.99;
  • }
  • }

After: Strategy pattern

重构后:策略模式

  • interface ShippingStrategy {
  • calculate(order: Order): number;
  • }
  • class StandardShipping implements ShippingStrategy {
  • calculate(order: Order) {
  • return order.total > 50 ? 0 : 5.99;
  • }
  • }
  • class ExpressShipping implements ShippingStrategy {
  • calculate(order: Order) {
  • return order.total > 100 ? 9.99 : 14.99;
  • }
  • }
  • class OvernightShipping implements ShippingStrategy {
  • calculate(order: Order) {
  • return 29.99;
  • }
  • }
  • function calculateShipping(order: Order, strategy: ShippingStrategy) {
  • return strategy.calculate(order);
  • }
undefined
  • interface ShippingStrategy {
  • calculate(order: Order): number;
  • }
  • class StandardShipping implements ShippingStrategy {
  • calculate(order: Order) {
  • return order.total > 50 ? 0 : 5.99;
  • }
  • }
  • class ExpressShipping implements ShippingStrategy {
  • calculate(order: Order) {
  • return order.total > 100 ? 9.99 : 14.99;
  • }
  • }
  • class OvernightShipping implements ShippingStrategy {
  • calculate(order: Order) {
  • return 29.99;
  • }
  • }
  • function calculateShipping(order: Order, strategy: ShippingStrategy) {
  • return strategy.calculate(order);
  • }
undefined

Chain of Responsibility

责任链模式

diff
undefined
diff
undefined

Before: Nested validation

重构前:嵌套验证

  • function validate(user) {
  • const errors = [];
  • if (!user.email) errors.push('Email required');
  • else if (!isValidEmail(user.email)) errors.push('Invalid email');
  • if (!user.name) errors.push('Name required');
  • if (user.age < 18) errors.push('Must be 18+');
  • if (user.country === 'blocked') errors.push('Country not supported');
  • return errors;
  • }
  • function validate(user) {
  • const errors = [];
  • if (!user.email) errors.push('Email required');
  • else if (!isValidEmail(user.email)) errors.push('Invalid email');
  • if (!user.name) errors.push('Name required');
  • if (user.age < 18) errors.push('Must be 18+');
  • if (user.country === 'blocked') errors.push('Country not supported');
  • return errors;
  • }

After: Chain of responsibility

重构后:责任链模式

  • abstract class Validator {
  • abstract validate(user: User): string | null;
  • setNext(validator: Validator): Validator {
  • this.next = validator;
  • return validator;
  • }
  • validate(user: User): string | null {
  • const error = this.doValidate(user);
  • if (error) return error;
  • return this.next?.validate(user) ?? null;
  • }
  • }
  • class EmailRequiredValidator extends Validator {
  • doValidate(user: User) {
  • return !user.email ? 'Email required' : null;
  • }
  • }
  • class EmailFormatValidator extends Validator {
  • doValidate(user: User) {
  • return user.email && !isValidEmail(user.email) ? 'Invalid email' : null;
  • }
  • }
  • // Build the chain
  • const validator = new EmailRequiredValidator()
  • .setNext(new EmailFormatValidator())
  • .setNext(new NameRequiredValidator())
  • .setNext(new AgeValidator())
  • .setNext(new CountryValidator());

---
  • abstract class Validator {
  • abstract validate(user: User): string | null;
  • setNext(validator: Validator): Validator {
  • this.next = validator;
  • return validator;
  • }
  • validate(user: User): string | null {
  • const error = this.doValidate(user);
  • if (error) return error;
  • return this.next?.validate(user) ?? null;
  • }
  • }
  • class EmailRequiredValidator extends Validator {
  • doValidate(user: User) {
  • return !user.email ? 'Email required' : null;
  • }
  • }
  • class EmailFormatValidator extends Validator {
  • doValidate(user: User) {
  • return user.email && !isValidEmail(user.email) ? 'Invalid email' : null;
  • }
  • }
  • // 构建责任链
  • const validator = new EmailRequiredValidator()
  • .setNext(new EmailFormatValidator())
  • .setNext(new NameRequiredValidator())
  • .setNext(new AgeValidator())
  • .setNext(new CountryValidator());

---

Refactoring Steps

重构步骤

Safe Refactoring Process

安全重构流程

1. PREPARE
   - Ensure tests exist (write them if missing)
   - Commit current state
   - Create feature branch

2. IDENTIFY
   - Find the code smell to address
   - Understand what the code does
   - Plan the refactoring

3. REFACTOR (small steps)
   - Make one small change
   - Run tests
   - Commit if tests pass
   - Repeat

4. VERIFY
   - All tests pass
   - Manual testing if needed
   - Performance unchanged or improved

5. CLEAN UP
   - Update comments
   - Update documentation
   - Final commit

1. 准备阶段
   - 确保存在测试用例(如果没有则编写)
   - 提交当前代码状态
   - 创建功能分支

2. 识别阶段
   - 找出需要处理的代码异味
   - 理解代码的功能
   - 规划重构方案

3. 重构(小步迭代)
   - 做出一个微小修改
   - 运行测试
   - 测试通过则提交
   - 重复上述步骤

4. 验证阶段
   - 所有测试通过
   - 如有需要进行手动测试
   - 性能无下降或有所提升

5. 清理阶段
   - 更新注释
   - 更新文档
   - 最终提交

Refactoring Checklist

重构检查清单

Code Quality

代码质量

  • Functions are small (< 50 lines)
  • Functions do one thing
  • No duplicated code
  • Descriptive names (variables, functions, classes)
  • No magic numbers/strings
  • Dead code removed
  • 函数体积小(少于50行)
  • 函数单一职责
  • 无重复代码
  • 命名具有描述性(变量、函数、类)
  • 无魔法数字/字符串
  • 已删除死代码

Structure

结构

  • Related code is together
  • Clear module boundaries
  • Dependencies flow in one direction
  • No circular dependencies
  • 相关代码集中在一起
  • 模块边界清晰
  • 依赖单向流动
  • 无循环依赖

Type Safety

类型安全性

  • Types defined for all public APIs
  • No
    any
    types without justification
  • Nullable types explicitly marked
  • 所有公共API都定义了类型
  • 无无理由的
    any
    类型
  • 可空类型已明确标记

Testing

测试

  • Refactored code is tested
  • Tests cover edge cases
  • All tests pass

  • 重构后的代码已覆盖测试
  • 测试覆盖边缘情况
  • 所有测试通过

Common Refactoring Operations

常见重构操作

OperationDescription
Extract MethodTurn code fragment into method
Extract ClassMove behavior to new class
Extract InterfaceCreate interface from implementation
Inline MethodMove method body back to caller
Inline ClassMove class behavior to caller
Pull Up MethodMove method to superclass
Push Down MethodMove method to subclass
Rename Method/VariableImprove clarity
Introduce Parameter ObjectGroup related parameters
Replace Conditional with PolymorphismUse polymorphism instead of switch/if
Replace Magic Number with ConstantNamed constants
Decompose ConditionalBreak complex conditions
Consolidate ConditionalCombine duplicate conditions
Replace Nested Conditional with Guard ClausesEarly returns
Introduce Null ObjectEliminate null checks
Replace Type Code with Class/EnumStrong typing
Replace Inheritance with DelegationComposition over inheritance
操作名称描述
Extract Method将代码片段提取为方法
Extract Class将行为移至新类
Extract Interface从实现中提取接口
Inline Method将方法体移回调用处
Inline Class将类的行为移回调用处
Pull Up Method将方法移至父类
Push Down Method将方法移至子类
Rename Method/Variable重命名以提升清晰度
Introduce Parameter Object分组相关参数
Replace Conditional with Polymorphism用多态替代switch/if条件判断
Replace Magic Number with Constant使用命名常量替代魔法数字
Decompose Conditional拆分复杂条件
Consolidate Conditional合并重复条件
Replace Nested Conditional with Guard Clauses用卫语句替代嵌套条件
Introduce Null Object消除空值检查
Replace Type Code with Class/Enum使用强类型替代类型码
Replace Inheritance with Delegation用组合替代继承