简而言之 从大局来看,这不是一个明智的想法。
- 事实上,一个人感到需要询问或搜索这个问题已经说明了一些问题。
- 很少有人关心这个问题,这表明可能有一种方法可以避免你需要开始询问这个问题的情况。
- 这最后两点至少应该促使你重新考虑一些事情,无论它们看起来多么不相关。
考虑尽早为软件组件的所有输入分配类型,并将其放在域逻辑之外。这样,我们通常称之为“领域模型”的东西就不必担心这个问题了。
在您的情况下,这意味着将所有分数都包装在
Score
对象中。因为它们就是分数。做出例外的需要始终至少是可疑的,并且可以作为代码异味的标志。
下一步是将您的“领域模型”视为普通模块集合。将使用有形原语的(太常见的)I/O接口视为履行不同/独立角色。这将自然而然地(几乎像魔术一样)降低所有组件(例如类)的个体复杂性。
这样做的一个副作用是,您可能会发现这个问题变得毫无意义。“如果我甚至不确定整数是否为分数,为什么要比较分数和原始整数?如果我确定了,那么为什么之前没有这样说(例如通过装箱)?”
更进一步,您可能会意识到,您的许多算法甚至不需要知道如何计分:很可能它们中的大部分只需要能够比较它们,以查看它们是否相等或哪个更高。我并不是说修改得分的方式的灵活性将来会有用,但作为一个规则,如果它不应该重要,则没有必要仅仅为了可爱而将代码绑定到实现上。也许令人惊讶的是,这也适用于原始类型,例如整数,甚至数字的概念(您不需要在所有需要比较两个分数的情况下关心它)。SOLID原则提供了一个很好的指南,直到您可以自己形成直觉。
反驳:人们总是可以引用性能的论点来反驳这种思路。根据我的经验,我发现JIT会优化和内联任何影响性能的东西(尤其是对于像相等比较之类的琐碎事情),当它不这样做时,几乎总有一种以明智的方式抽象出性能关键代码的方法。如果派遣是一个问题,不要犹豫地封装您的类型。
在测量和找到瓶颈之后,如果一个正确的设计无法通过替代但同样合理的设计来修复,那么就需要诚实地承认自己遇到了语言限制。在这种情况下,应该考虑将代码提取出来并用更适合的语言编写,或者在现有语言中进行修改,但要对该代码进行详细注释。
最后,我想说我以前确实做过你建议的事情,而且我只能感激那段代码从未进入生产环境。一次似乎不会有什么害处,但如果到处都这样做,那种不安的感觉就会落定,并且只会产生挫败感,直到你最终意识到为什么这是错误的(根据上述考虑)。如果你好奇,我是为几乎总是包装单个基元的实体键表示类型做的。再次强调,这似乎是个明智的想法,你可能仍然这么认为,但我坚信现在不是,尽管我以前没有听说过。也许这是你需要亲身经历才能真正领悟的事情。