void executeRequests() {
...
for (Request request in requests) {
if (request is Type1Request) {
...
} else if (request is Type2Request) {
...
} else if (...) {
} ...
}
}
所以基本上我有一个方法为请求列表执行一些常见的过程,然后遍历此列表并根据请求类型(其特定的类)进行一些特定的处理。
有人可能会争辩说我应该将每个if else
块分成一个单独的类,其中包含execute
方法,然后只需调用execute
内的for loop
,因为这会打破Separation of concerns
模式。并且我同意!我只是不知道为什么。
在这种情况下,我们假设我永远不会重用那些类或私有函数(或者我决定重构)。 有些人认为这种方式更易于阅读,因为您不必跳转到不同的文件或功能来理解所有内容。
所以我的问题是,为什么这段代码不好?
谢谢。
答案 0 :(得分:1)
简单地说,因为在代码中添加Type3Request
对象会强制您编辑现有代码。每次更改现有代码时,都应测试应用程序中的所有相关模块,以确保代码中不会出现回归错误。在javascript或其他松散类型的语言中,从if分支覆盖全局数据非常容易。在大多数强类型语言中,您通常可以避免此问题,但仍有可能覆盖本地数据。这意味着每次更改此executeRequests
方法时,都必须在应用程序中运行所有可能的请求,以确保您没有引入新问题。我想说明我说的所有请求,而不是所有请求类型。即使您只有少量请求类型,也可能需要运行数千个测试。
另一方面,将此代码作为多态方法保存在不同的类中可确保它不会更改executeRequests方法及其所有者类的数据。这使您只能使用相同的置信度来测试与您正在更改的类型相关的调用。换句话说,它减少了代码中的错误数量。
通过使用多态,所有"特定代码"需要为此请求执行的操作不仅会封装到Type3Request
对象中,而且实际上会包含此对象。没有其他代码文件可以更改,以便添加新的请求类型。
这意味着您可以像插件一样动态提供新的请求类型,只需在文件夹中添加dll,而无需重新编译现有代码。如果您不想这么做,它仍然可以让您通过避免与executeRequests
方法合并来更好地在所有团队成员之间分离您的工作量。
通过将紧密耦合的业务逻辑保持在一起,它还使测试代码变得更加简单。您可以直接从请求对象调用方法并断言结果,而不必让您的请求通过整个执行过程来测试此类型特定的代码。
所有这些都确保了如果项目中发生架构更改,您就会知道只有一个地方可以查找与请求相关的代码:相关的请求类型类。如果你让这个代码泄漏到其他类中,你可能会在估计更改的复杂性时错过这些代码的一些实例,甚至更糟糕的是,在一个可能触发错误的大型重构之后将其抛在后面。
答案 1 :(得分:0)
与特定请求相关联的操作与由于某些外部触发器而执行特定请求的对象无关。关注(处理后果)属于请求。因此,您将它与执行程序分开,因为它存在错误。内部的某种东西(某种类型的行为)被“外包”给其他阶级,而这个阶级主导着这个决定,这是一种负担和耦合。
这不是你为什么要选择这样做的问题。它是相反的..它是怎么可能是任何其他方式。如果我们做适当的面向对象编程。