本文转载自公众号《读书芯》(ID:AI_Discovery)。我经常看到许多分支发生在枚举或其他离散值上,甚至在一些开发人员被要求不要使用if-then-else时感到恼火。if-else和switch肯定会产生简洁的代码,你的软件不应该包含最少的行数,而不牺牲可读性、可维护性或灵活性。在if-then-else语句中使用枚举会产生什么后果?基于离散值的分支使得软件难以改变。每个新功能都需要跟踪分支发生的位置,并相应地修改现有代码。这绝对不是我们想要的方式。这可能是让您的代码正常工作的第一步,但随着您改进代码,switch和if-then-else肯定早已不复存在。我必须说,使用if-else和switch进行分支的传统方式已经过时了。它不可靠且不灵活。传统方法中没有面向对象的内容。但它仍在蓬勃发展,因为学生被迫认为它是正确的,甚至是最佳实践。该代码有效,但您可以做得更好。考虑这个问题。假设出于某种原因必须有一种更新用户的方法。为简单起见,用户只需要在系统中进行更新,原因有二。对于这两个简单案例,您可以在以下代码片段中实现原始要求集。花点时间阅读这段设计糟糕的代码,许多高级开发人员将其视为噩梦,甚至被认为是导致“井绳十年恐惧”的蛇。是的,我见过这样的狂野代码。这是一个非常幼稚的操作,它假定用户永远不会有那么多理由进行更改。带有无用if-else指令的糟糕代码示例这段代码的唯一好处是它试图实现一个半CQS式的设计模式。如果您倾向于说“那应该是一个开关”,那么您应该花点时间想想在软件开发中什么是重要的。Switch与if-else完全无关。您每时每刻都受到新需求的冲击,谁会想到呢?你会认为什么都不会发生。现在对你的要求是这样的:你真的想通过添加其他枚举值和附加两个else-if语句来实现这两个新原因下的用户更新吗?如果你决定走这条错误的路,结果就会是这样。复杂的、令人头疼的分支实现本质上是缺乏多态性的。除了不断添加额外的分支(这本身就是一种有问题的做法)之外,每当您需要调试或执行错误修复时,您都会被完全不相关的代码所包围。还有一个问题。这个方法标签在欺骗我们,因为它不只是更新用户。它还根据更新的原因选择执行哪种算法,甚至知道每个实现。现在很明显,这种方法伴随着巨大的责任。我相信这个例子加强了对if-else和switch的恐惧。让我们看看如何避免这种讨厌的方法。重构为多态执行非常容易。将基于分支的杂乱代码重构为内聚、简单、实用的类。在有人说他们害怕使用类之前,我想澄清一件事。实例化一个新类的成本通常可以忽略不计,在遇到瓶颈之前不要尝试优化您的代码。我们可以做得更好,编写可读、可维护、灵活的代码。通过用多态执行取代传统的分支,类和它管理的需求之间有一个明确的联系。具有明确职责的简单、高度内聚的类易于维护。检测和纠正缺陷轻而易举。最重要的是,软件可以轻松地适应新功能而无需修改现有类。让我们开始重构。让我们看看在没有if-then-else或switch的情况下我们能做得多好。UpdateAsync(Reason,User)现在非常简单。简化的UpdateAsync方法实现请注意,您现在使用的是接口参数而不是枚举。此方法现在委派了了解如何对特定对象执行更新的责任。IUpdateReason的具体实现如下所示,构造函数参数和方法实现细节不再赘述。UpdateReason接口的每一类及其具体实现都完全满足其管理的要求。调试、修复错误和测试现在比过时的方法容易得多。在这种情况下,任何新需求都会产生一个专用类。我们可以轻松地在这里停下来结束我们的一天。您重构了繁琐的分支并将其替换为多态性。您的代码现在是面向对象的并且易于维护。但您也可以选择转到最后一步。UpdateAsync(Reason,User)现在有点多余了。为了解决这个问题,我们不再进行重构——我们正在重新设计系统的某些部分。在这种情况下,创建命令对象和命令处理程序是有意义的。它将简化调用代码,因为它只分派像UpdateUserAddress这样的命令,并且将调用相应的处理程序的操作。来源:unsplash在发现更合适的多态方法之前,传统的分支通常是学生的工具。但毫无疑问,if-then-else和switch会使代码难以阅读、难以维护和调整。下次您想使用传统的多路分支来实现功能时,请花点时间分析一下多态性和现代方法如何帮助您事半功倍。
