据我了解,YAGNI 建议我们不要不必要地提取抽象。也就是说,如果我们在这个特定的时刻不需要多态性,那么我们就不应该强调抽象,因为那是为什么呢?然而,OCP 和 DIP 都鼓励我们在这里强调抽象。OCP 建议这样做,以便如果我们突然需要更改类的行为,我们可以在不更改类型的情况下执行此操作,只需将抽象的新实现传递给该类型即可。另一方面,DIP 以纯文本的形式表示细节应该依赖于抽象,而不是相反。
同样突出抽象可以强制需要测试该类型的用户。但是在java的框架内,据我了解,是没有这个需求的。
那么,是否有必要立即突出抽象?我需要遵循 OCP 和 DIP 吗?
不同的设计原则旨在解决一个特定的设计问题,在某些情况下它们可能相互矛盾。
我们可以说不同的原则将设计“拉”向不同的方向,您需要找到在这种特殊情况下最有用的正确向量:-谈到,
SRP解决方案的简单性OCPDIPLSP遵循一项原则可能会导致违反另一项原则。因此,例如,任何继承都可以被视为违规
SPR,因为现在一组类负责一个职责(绘制形状)。跟随DIP并OCP可能导致出现额外的“接缝”,即。系统中的接口/基类,这又会破坏SRP和/或ISP.但是原则之间的这种关系并不是固定的。对于一个简单的情况,突出显示要绘制的形状的层次结构是一种违规行为
SRP,因为第一次迭代中的“绘制”可能包括将文本输出到控制台,并且将此信息涂抹在多个类中将是多余的。但随着解决方案变得越来越复杂,继承层次结构的出现从观点来看将是合理的SRP,因为显示每个单独图形的复杂性将如此之高,以至于“责任”的概念也会发生变化。如果一开始的“单一职责”是所有数字的显示,那么现在一个职责就会分成很多:“显示一个圆”,“显示一个正方形”等等。YAGNI 原则(你不会需要它)是一个更基本的原则(“高阶原则”或“元原则”),它将帮助你了解何时遵循原则/模式/规则,何时不遵循。
YAGNI 原则基于以下几个观察:
这些观察得出以下结论:在开发的早期阶段尝试创建灵活的解决方案注定会创建过于复杂的解决方案。这是因为在早期阶段还不知道需要对系统进行哪些更改,而且根本不清楚在哪里为未来的更改埋下稻草。
由于在早期阶段我们并不知道到底需要什么样的灵活性,所以我们会把灵活性放在错误的地方:我们会提供数据访问层的替换,但由于“泄漏抽象”,我们仍然会锁定特定数据库的解决方案,或者根本不需要这种灵活性。我们将创建一个“框架”来解析将在一个应用程序中使用的命令行参数,而将其拧入另一个应用程序的成本将如此之大,以至于没有人会这样做。
好的设计是在需求变化导致线性工作时易于解决。
实现这一目标的最简单方法是通过演化设计:我们首先将系统分解成大的组件,但我们不会全力以赴。如果现在没有至少 2-3 个继承人,则不需要基类。即使这样的继承者“可能在未来出现”,也有必要在这个未来到来时准确地挑选出类型层次结构。
原则
YAGNI可以表述如下:只有在未来分配不必要的抽象(以及任何其他并发症)的成本将比现在高得多的情况下,分配不必要的抽象(以及任何其他并发症)才是合理的。投资于一个深思熟虑的库编程接口 (API) 将是值得的,因为进行更改的成本非常高。为应用程序分配接口/基类的成本在今天或一年后几乎没有变化。
解决问题可以让您专注于今天相关的任务,并避免可能根本不需要的工作。
PS 好吧,在我看来,您对 和 的原则没有完全正确的理解,
OCP根本DIP没有减少到使用继承的需要。以下是一些相关文章:
另外,在“设计原则”一文中,我讨论的内容与此答案大致相同:盲目遵循原则将导致过于复杂且维护繁重的解决方案。