OOP 的缺点?[已关闭]

2022-09-01 03:28:48

通常,我不想知道OOP的缺点的具体情况,但是当我最近参加的一次面试中发生争吵时,感觉有点奇怪。发布给我的问题是告诉我面向对象编程(OOP)的一个缺点。当时,我觉得OOP是继过程和函数模型之后最成熟的编程水平。所以我回答他,我根本没有看到任何负面的东西。

但面试官说很少,如果他不介意的话,我让他列出一个。他举了一个我不太好消化的例子。他说,OOP模式没有严格执行继承规则,并引用了卫星/火箭的例子,其中身体部位在火箭发射过程中会定期分解以减轻重量,并表示继承不支持这一点。

他的例子对我来说有点奇怪,原因是继承对这个例子的应用。

我知道他举的例子几乎没有任何意义,但我有这个疑问——

我们是否可以在理想的面向对象设计中动态地拔出类层次结构(我对Java有点信心,这是不可能的)?


答案 1

仅仅因为你有一把锤子,并不意味着一切都是钉子。

我发现,当使用OOP作为编程风格时,许多人经常混淆何时应用组合继承你从面试问题中引用的例子似乎是这种混乱的一个例子。

我从经验中学到的一件事是,虽然继承是设计中实体之间表达“IS-A”关系的一个很好的范例,但通常更喜欢组合而不是继承

但是,让我们来看看面试官问题的症结所在:OOP什么时候是一个糟糕的范式选择?

OOP 最适合大规模、多开发人员、多模块项目。对于“小型开发”(例如脚本或转换处理),它可能需要大量的开销,而不必增加价值。但即使在这些情况下,除非你正在编写一次性代码,否则我认为大型解决方案通常会从较小的解决方案演变而来,因此尽早建立结构和分离关注点可以节省您以后的悲伤。

最终,OOP编程还需要一定程度的设计严谨性和规划,以及对面向对象的核心原则的理解。如果你不愿意花时间学习和理解这些原则......好吧,也许OOP编程不适合你。

除此之外,某些类型的问题也适合替代编程风格。例如,转换处理非常适合函数式编程风格 - 其中计算结果并将其传递给连续的转换步骤以产生最终结果。您必须在域中搜索或查询某些匹配信息的问题适用于查询语言(如SQL),在这种语言中,您可以声明性地而不是命令式地描述您的意图。

能够识别您正在解决哪种问题,对于选择使用哪种语言或工具有很长的路要走。正确的工具可以使工作变得容易得多...错误的一个会让它变得更难 - 或者不可能。


答案 2

我不完全理解他的例子。

但是,重要的是要了解OOP对于可以用它自然建模的事物非常有效,而对于其他事物(例如,跨领域关注点或方面)非常无效。这是OOP的一个缺点。另一个是,由于动态调度,它经常会产生一些运行时成本。

此外,滥用OOP来做不合理的抽象是非常容易的。从身体继承火箭就是一个例子。我的经验是,新手开发人员要么不信任也不使用继承,要么他们过于急切,并且在其他行为(如聚合)更合适时错误地使用它。随着时间的推移,经验和对机制的理解不断提高。

我不确定他所说的“OOP模式不严格实现继承规则”是什么意思,因为OOP不是一种模式。一个潜在的问题是,可以编写一个可能违反Liskov替换原则的子类型,因此覆盖方法的行为“至少”不像被覆盖的方法。没有办法自动检查这一点,因此可以编写违反OOP原则的代码。

至于你的最后一个问题“我们可以在理想的面向对象设计中拔掉类层次结构吗?”,我不确定你在这里是什么意思。如果您询问有关在运行时更改层次结构的问题,并使其从执行中的某个点不再存在子类型关系,那么是的。对于某些语言(例如Smalltalk)是可能的。有些人会认为这是“更多的OOP”。在 smalltalk 中,类型支持的“方法”是在方法调用点根据当前层次结构和每个类的当前内容确定的。虽然我喜欢 smalltalk,但这是一个我并不疯狂的功能,因为我更喜欢运行时惊喜较少的编译时检查。