DanLevy.net

命名要搞好

命名那些事:面向对象基础

Hero image for 命名要搞好

命名那些事:面向对象基础

让我们通过示例来探讨对象/类的设计……

场景

你是否曾经设计过数据模型(在代码、SQL或Excel工作表中)?下面这种情况是否似曾相识?

*** 反模式 - 请勿复制粘贴 ***
* User
- id
- avatarUrl
- name
- email
- password
* Agent
- id
- primaryPhoto
- name
- email
- agentEmail
- agentPhoneMain
- agentEmailPrimary
- agentPhonePrimary
- agentAddressFull
- agentCompanyName
- agentCompanyAddress
- *userEmail* - 指向 User 表的“指针” ^^^

问题在哪?

严格来说,这不算 bug,只是数据需要重新组织。

下面这些情况是否耳熟?

  1. 应用任何改动都需要耗费数小时进行痛苦的调试。
  2. 任何需求变更都会导致:

schema refactor

为什么把字段命名为 agentEmailPrimary 如此糟糕?

首先,你并没有在宇宙中创造一个全新的事物。过度具体化存在几个陷阱:

  1. “锁定”在高度具体的名称上,意味着 agentEmailPrimary 很可能让你的视图和相关代码零复用性,并且会带来令人恼火的重复性 bug,例如:
  1. agentEmailPrimary 可能表示几种不同的含义。用更短的名称来避免歧义。

丹,别废话了,那应该长什么样呢?

一种解决方案

// 整合后的 Schema:
User
- id
- role: ['agent', 'lead', 'admin']
- name
- phone
- address
- email
- password
- company
- name
- address

我移除了 Agent 表,因为它没有包含 Agent 独有的字段。而 User.company 对象(包含 .name.address)在清理命名后自然浮现出来。

一些指导原则:

  1. 消除不必要的表。你真的需要一个 statuses 表吗?当你可以直接在 User 表上加一个 status::VARCHAR(8) 字段时?没关系,多用几个字节每行。
  2. 尝试合并相关的表。数据
  3. 删除冗余的数据收集(例如,如果已被分析方案替代,就移除 ActivityLogs 表)。
  4. 尽量让所有字段名保持单个单词/名词/代词。依赖表提供的上下文是没问题的(例如 PersonalAccount.email vs BusinessAccount.email —— 上下文由表名提供)。
  5. 根本不存在 Agent.agentEmailAgent.agentPhonePrimary 这种东西。句号。跟我念:“它是 emailphone。”
  6. 使用高度具体的名称,你就把特定级别的代码可复用性持久性刻在了石头上,具体来说就是零百分比
  7. User.profileSummaryEmail 这种垃圾对你没有任何好处。💞

推荐阅读:

  1. 也许规范化并不规范
  2. 数据库规范化和反规范化之间的权衡
  3. http://phlonx.com/resources/nf3/
  4. https://en.wikipedia.org/wiki/Database_normalization