注册
登录
新闻动态
其他科技
返回
好的设计就是不完美的设计第 1 部分:诚实的名字
作者:
糖果
发布时间:
2024-03-19 11:57:50 (9天前)
来源:
imperfect-design-part-1-honest-names/
通过埃里克·埃文斯 完美主义是个陷阱。对于像我一样喜欢优雅设计并看到其实用性的人来说,当令人满意的设计没有在合理的时间内出现时,就会有一个滑坡等待。认识到这一点并接受、放手、发货并继续前进——或者在以后的周期中返回,如果重要的话,需要不断的自律。它并不总是重要的。对于我们系统的许多部分,一个足够好的设计就足够了。对于少数具有战略意义的部分,精辟的模型和清晰的设计实际上可能会影响项目的结果,出色的初始设计通常不会立即出现。我们需要迭代和实验。我们的任何目标都不是通过磨练和磨蹭来实现的,等待我们可以在第一版中引以为豪的设计。 就我个人而言,我试图超越接受。当我为设计的某些部分苦苦挣扎时,我经常做出明确回应设计问题本身的设计选择。这有助于我放手继续前进,并且可以提高在以后的迭代中进行更改的机会。 在这个简短的系列中,我将描述我使用的一些技术,这些技术可以帮助我采取措施交付我不满意的东西,同时也可能为未来的迭代改进留下良好的途径。 我们将从非常细粒度的设计决策开始这个系列。 第 1 部分:诚实的名字 一个诚实的名字并不总是一个揭示意图的名字。只有当我们通过设计元素成功实现我们的意图时,情况才会如此。但这并不总是发生。在本文中,我们正在考虑那些没有好的解决方案的不幸时期。 我需要一个具体的例子来说明这种方法。挑出一些设计不佳的软件很容易,但检查通常设计良好的软件的缺陷更有趣。JodaTime 是一个用于日期/时间的 Java 库,被广泛用作开源库,并最终以修改的形式采用作为 Java 的标准库。它设计精良——当然,并不完美。(毕竟,它发货了!) 考虑“加号” JodaTime 库允许我们声明时间,例如日期和时间段:对于许多应用程序,这些值的存储本身就是一项重要功能。当然,常见的时间相关的操作还有很多,库中也实现了其中的一些,比如:Nice!在 JodaTime 中,所有的值都被设计为值对象。没有突变或副作用。所以在上面的例子中,执行t.plus(p)后,t的值不变:2021-01-20,并且操作返回了一个新的值2021-01-23。 t = 2021-01-20 p = 3 days t.plus(p) 2021-01-20.plus(3 days) ⇒ 2021-01-23 “加号”操作是通用的。它可以与不同类型的时期无缝协作: 2021-01-20.plus(2 days) ⇒ 2021-01-22 2021-01-20.plus(2 months) ⇒ 2021-03-20 代码看起来非常有表现力和清晰。然而...... 你认为以下会返回什么? 2021-01-30.plus(1 month) ⇒ ? 请记住,二月是一个短暂的月份!我能想到至少三种似是而非的反应。为了知道它实际上做了什么,我运行了代码: 2021-01-30.plus(1 month) ⇒ 2021-02-28 这似乎是一个合理的默认行为,但并不明显。我必须运行代码(或在某处查找文档)才能知道会发生什么,即使在使用该操作的一些经验之后,这一事实凸显了模型中的缺陷。但它有什么问题,可以做些什么呢? 在本文中,我将重点介绍名称。“加”这个词似乎符合我前几个例子中发生的情况,但它没有暗示我们如何处理不规则的情况,例如不同长度的月份。 这给我们带来了“诚实的名字”。如果操作的行为很复杂,像“plus”这样的简单名称实际上可能会产生误导。它可以被称为什么? 探索重要事物名称的许多选项通常是一种很好的做法。让我们尝试一些: t.plusRounded(p) t.constrainedPlus(p) t.plusWithCeiling(p) t.monthAwarePlus(p) 这些中的任何一个至少会给我一个线索。他们也很尴尬! 我们不喜欢笨拙的设计。但我们需要诚实的名字。 给难听的概念取难听的名字 让我们多看看 JodaTime 中的“plus”操作,以及为什么“plus”是一个令人困惑的名字。(这里我将'plus' 写为'+' 以便于阅读。) 2021-03-30 + 1 month ⇒ 2021-04-30 2021-03-31 + 1 month ⇒ 2021-04-30 这两个表达式实际上应该具有相同的值吗? 猜一下这两个表达式的值: 2021-03-31 + 2 months ⇒ ? 2021-03-31 + 1 month + 1 month ⇒ ? 看起来答案应该是一样的吗? 以下是实际答案: 2021-03-31 + 2 months ⇒ 2021-05-31 2021-03-31 + 1 month + 1 month ⇒ 2021-05-30 句号也可以与“加号”组合,所以 1 month + 1 month ⇒ 2 months 因此, 2021-03-31 + 1 month + 1 month ⇒ 2021-05-30 2021-03-31 + (1 month + 1 month) ⇒ 2021-05-31 在这里,我们深入了解称这个“加号”有什么问题:该名称的含义在我们的上下文中不适用!在数学中,“加”运算具有关联性等属性: (a + b) + c = a + (b + c) 当我们使用这个名称时,我们向读者(使用库的程序员或阅读使用它的代码的程序员)暗示该运算是关联的。但事实并非如此!许多定义明确的操作都不是关联的。但是我们应该称它们为“加号”吗? 顺便说一句,我喜欢不断地将事物的可能替代名称添加到我的列表中。以下是我此时想到的更多信息: t.plusRounded(p) t.constrainedPlus(p) t.plusWithCeiling(p) t.monthAwarePlus(p) t.plusNonAssociative(p) t.plusIsh(p) 我们必须发货!JodaTime 的设计者当时可能已经注意到了这个问题。(我对那个项目的内部一无所知。)如果他们注意到了,在我看来,他们仍然做出了正确的决定。他们发布了一个非常有用且通常非常干净的库——这并不完美。他们一定做过很多次类似的决定。有些问题他们注意到了,有些则没有。 但是,如果您决定运送一些您认识的笨拙的东西,请考虑给它一个诚实的、笨拙的名字。这可以与未来的用户进行交流,并且可以帮助设计的未来迭代。 一个干净的名字会关闭我们的思维。 t.plus(p) ⇒ t (很舒服……) 一个尴尬的名字会激发新的想法。 t.plusIshRoundCeiling(p) ⇒ t (拜托,拜托!我的代码太丑了!) 它在我们的脑海中挥之不去,可能是通过软件的后期迭代。同时,它将向代码的用户传达一个现实的期望。 进入第 2 部分:在以后的迭代中进行改进 接受我们设计中的缺陷并不意味着我们会忘记它!在第二部分中,我们将快速浏览一个替代概念,该概念可能会在以后的迭代中出现以缓解尴尬。
收藏
举报
1 条回复
动动手指,沙发就是你的了!
登录
后才能参与评论