HotfixHero 代码宣言:七条准则

发布: (2025年12月20日 GMT+8 04:20)
6 min read
原文: Dev.to

Source: Dev.to

请提供您希望翻译的正文内容,我将为您翻译成简体中文并保持原有的格式、Markdown 语法以及技术术语不变。

介绍

我懂你的感受。你想要技术规范,帮助你不再让团队尴尬。好吧。编写可扩展且不致让人头疼的代码,关键在于纪律,而不是魔法。先把复杂的模式抛到一边——先掌握基础。

以下是我遵循的七条戒律。阅读它们,付诸实施,也许,只有也许,你的代码审查就不会像一份战争罪行报告一样。

1. DRY(Don’t Repeat Yourself)

每一段逻辑、每一条业务规则以及每一个数据定义都必须只存在于唯一的位置。如果你复制‑粘贴,你并不是在写代码,而是在制造技术债务。修复一个 bug 的成本会随你重复的次数成倍增长。这是非常糟糕的投资回报率。

错误示例(重复验证)

function createUser(data) {
  if (data.password.length  // The goal is to solve the problem, not win a Turing Award for the most convoluted solution. Simple code is cheaper to maintain, easier to test, and less likely to introduce subtle bugs. Your complexity doesn't impress anyone but junior developers.

错误示例(过于复杂的条件)

function getDiscount(user) {
  let status = user.isPremium ? 0.20 : 
               (user.totalOrders > 5 && user.joinedYear  10 ? 0.10 : 0;

  // Now try debugging that nested ternary hell at 3 AM.
  return status;
}

HH 方法(使用清晰的逻辑)

function getDiscount(user) {
  if (user.isPremium) {
    return 0.20;
  }

  if (user.totalOrders > 5 && user.joinedYear  10) {
    return 0.10;
  }

  return 0; // The default, simple case
}

3. YAGNI(You Aren’t Gonna Need It)

停止猜测产品负责人明年可能会提出什么需求。只构建今天所需的功能。每一行不是在解决当前问题的代码都是浪费时间,并会导致不必要的复杂性。

糟糕示例(为未来功能预先构建)

# The current requirement is only 'File' storage.
# The developer adds hooks for 'S3' and 'Azure' just in case.
class StorageManager:
    def __init__(self, storage_type='FILE'):  #  A class or function should have only **one** reason to change. If your function is responsible for fetching data, formatting it, and sending an email, it’s doing too much. When the email format changes, the fetching function shouldn’t have to change.

糟糕示例(上帝函数)

function processAndFormatUserData(id) {
  // 1. Fetch data (reason to change: database schema)
  const user = database.fetchUser(id); 

  // 2. Calculate Age (reason to change: calculation logic)
  const age = new Date().getFullYear() - new Date(user.dob).getFullYear();

  // 3. Format output (reason to change: UI/API requirement)
  return { id: user.id, fullName: `${user.first} ${user.last}`, age };
}

HH 方式(职责分离)

// 1. Data Retrieval
function fetchUserFromDB(id) {
  return database.fetchUser(id);
}

// 2. Business Logic / Calculation
function calculateAge(dob) {
  return new Date().getFullYear() - new Date(dob).getFullYear();
}

// 3. Formatting / Presentation
function formatUserPresentation(user) {
  return {
    id: user.id,
    fullName: `${user.first} ${user.last}`,
    age: calculateAge(user.dob) // Calls focused logic
  };
}

5. 关注点分离

将应用程序划分为尽可能少重叠的独立功能。数据访问层不应了解 HTTP 请求头,控制器也不应包含复杂的格式化逻辑。

错误示例(混合数据访问和业务逻辑)

// Inside a Web Controller/Endpoint
@GetMapping("/users/{id}")
public UserDetails getUserDetails(@PathVariable Long id) {
    // Concern 1: Database Access is mixed here
    UserEntity user = entityManager.find(UserEntity.class, id); 

    // Concern 2: Business Logic is mixed here
    if (user.getBalance()  // Optimize only when you have evidence that a piece of code is a bottleneck. Writing clever, low‑level loops for the sake of “speed” often sacrifices readability and maintainability.

错误示例(不必要的低层循环导致可读性受损)

// Bad: Using a manual `for` loop where a higher‑level method would be clearer
let result = [];
for (let i = 0; i  item.active);

结论

掌握这些基础,你将花更少的时间与自己的代码作斗争,花更多的时间提供价值。上述原则是永恒的——始终如一地应用它们,你的未来的自己(以及你的团队成员)会感谢你的。

长度递减用于微优化

可读性不如原生方法,且现代引擎对 mapforEach 的优化同样出色。

let i = items.length;
while (i--) {
  processed.push(items[i].toUpperCase());
}

HH 方案(可读且易维护)

优点:意图明确,依赖已优化的内置方法。

// Using the built-in `map` method
const processed = items.map(item => item.toUpperCase());

Demeter 法则(最少知识原则)

“不要和陌生人说话。”
对象只应与其直接的朋友(它创建的对象、它的参数、它的属性)通信。
通过方法链深入内部结构会使代码耦合,导致脆弱。

错误示例(方法链违规)

// We are asking the `user` object for its `wallet`, then the `wallet` for its `card`,
// then the `card` for its `security code`. Too much knowledge.
String code = user.getWallet()
                  .getPrimaryCard()
                  .getSecurityCode();

HH 方式(委托)

// We only ask the `user` to perform the action. The `user` object handles the internal structure.
String code = user.getSecurityCodeForPrimaryCard();
Back to Blog

相关文章

阅读更多 »

为什么要使用设计模式?

重要的是要理解,Design Patterns 从来不是为了被随意拼凑的捷径,也不是以草率的“一刀切”方式应用于……