我听过这句话,对我来说,这些争论听起来是完全疯狂的(抱歉,如果我在这里说的话,那不是我的意思),一般来说,它的大意是:
您不希望在了解一般情况之前创建一个抽象,否则,(1)您可能会将不属于您的抽象中的内容放入其中,或者(2)忽略一些重要的东西。
(1)在我看来,这听起来好像程序员不够务实,他们假设最终的程序中会有不存在的东西,所以他们处理的抽象程度很低,问题不是过早的抽象,而是过早的具体化。
(2)忽略重要的东西是一回事,完全有可能在规范中遗漏了一些后来被证明是重要的东西,解决这个问题的方法不是当你发现你猜错了,而是从客户那里获得更多的信息时想出你自己的具体和浪费资源。
我们应该从抽象到具体,因为这是最务实的做事方式,而不是相反。
如果我们不这样做,那么我们就冒着误解客户和创造需要改变的东西的风险,但是如果我们只构建客户用自己的语言定义的抽象,我们就永远不会遇到这种风险(至少最不可能像用某种具体化在黑暗中开枪一样),是的,客户可能会改变他们对细节的看法,但是他们最初用来传达他们想要的东西的抽象仍然有效。
下面是一个例子,假设一个客户希望您创建一个物品包装机器人:
public abstract class BaggingRobot() {
private Collection<Item> items;
public abstract void bag(Item item);
}
我们正在从客户使用的抽象中构建一些东西,而不对我们不知道的内容进行更详细的介绍。这是非常灵活的,我已经看到这被称为“过早的抽象”,而在现实中,假设打包是如何实现的还为时过早,让我们说,在与客户讨论之后,他们希望同时打包多个项目。为了更新我的类,我所需要的只是更改签名,但是对于那些自下而上的人来说,这可能需要进行大规模的系统大修。
没有过早的抽象,只有过早的具体化。这句话有什么不对?我推理中的缺陷在哪里?谢谢。
发布于 2019-02-04 03:52:44
至少在我看来,过早的抽象是相当普遍的,尤其是在OOP的早期。
至少从我看到的情况来看,出现的主要问题是人们阅读了面向对象层次结构的典型示例。他们被告知如何做好一切准备来应对未来可能出现的变化(尽管没有特别好的理由相信他们会这样做)。许多文章的另一个共同主题是像鸭嘴兽这样的东西,它违背了关于“哺乳动物都是这样的”或“鸟类都是这样”的简单规则。
因此,我们最终得到的代码实际上只需要处理员工的记录,但是如果你雇佣了一只蜘蛛或者甲壳类动物的话,我们会仔细编写这些代码来做好准备。
发布于 2019-02-04 07:23:11
重要的是要记住,抽象是达到目的的一种手段。您可以使用抽象来统一整个程序的行为,并且在您期望添加新类的情况下,将新类的添加变得简单明了,但只有在非常需要的时候才会添加新的类。
您不会仅仅因为需要抽象而添加抽象(没有真正的基础来思考将来需要添加新的类)。这里的一个恰当的比喻可能是管道。希望你会同意,一个6方向的管道,它允许水向上/向下,东/西,北/南将是你能拥有的最灵活的管道类型。理论上,你可以在需要管道的任何地方使用6方向的管道,并阻止不必要的方向,对吗?
如果你试图解决水槽下面漏水的问题,发现管道的所有部分都是6个方向的管件,你会想要把你的头发拔出来,因为那个人是这样设计的。您不仅不知道问题出在哪里,而且几乎可以肯定,简单地从零开始就以正确的方式进行比较简单。
当然,编码不是管道,但这个比喻仍然有效。抽象就像使用那些6方向的管道部件一样。当你诚实地相信你可能在不久的将来需要连接所有6个方向的管道时使用它们。否则,抽象只是简单的复杂,与使用不需要任何东西的模式或使用尝试完成一切的上帝类并没有太大的不同。如果它没有被使用,也不太可能被使用,那么最终您将添加一个额外的类。
诚然,编写程序的艺术在概念上是非常抽象的。值得一提的是,抽象并不是为了抽象而存在的,而是因为它们在某种程度上是实用的。如果你觉得有必要使用抽象,那就去吧,但以后不要让我检查你的管道。;)
发布于 2019-02-04 16:30:45
许多年前,当我了解到面向对象的分析和设计时,我们会从一个简单的英文描述开始,描述客户需要的系统。
综上所述,任何名词(或名词短语)都会被视为一种可能的类别。任何动词(或动词短语)都是类中潜在的方法。所以“袋装机器人”可以是BaggingRobot
级的。“打开一个袋子”可能成为方法OpenBag
。
经过几次迭代之后,这将变成一个类图。
此时,不存在抽象类。顾客不想要一个包装机器人的抽象概念。他们想要一个能把东西装进袋子的机器人。所有的类都是具体的,并且有一组方法。
只有在以下情况下才引入抽象类:
对我来说,“过早的抽象”是假设任何BaggingRobot
都必须继承某些BaseRobot
,更糟糕的是,在您还不知道所有机器人共有什么之前,就试图为BaseRobot
开发一组方法。
https://softwareengineering.stackexchange.com/questions/386570
复制相似问题