Dan*_*ham 67 language-agnostic oop abstraction
在面向对象的程序中:抽象多少太多了?多少钱是对的?
我一直都是一个坚定的人.我理解高级封装和抽象背后的概念,但总觉得增加太多只会混淆程序.
我总是试图拍摄一些没有空类或层的抽象.如果有疑问,我会尝试在现有图层中添加一些新图层,而不是在层次结构中添加新图层.
然而,最近我遇到了更多高度抽象的系统.系统中可能需要在层次结构中稍后表示的所有内容都可以预先获得.这导致了很多空层,起初看起来像是糟糕的设计.然而,第二个想法我已经意识到,留下那些空白的层将为你提供更多的地方,以便将来不需要太多的重构.它使你能够更好地在旧版本之上添加新功能,而无需做太多调整旧版本的工作.
这样做的两个风险似乎是你可以得到你需要错误的图层.在这种情况下,人们最终还是需要进行大量的重构来扩展代码,并且仍然会有大量未使用的层.但是,根据您花费多少时间进行初始抽象,将其搞砸的可能性,以及如果您做得对,可以节省的时间 - 可能仍然值得尝试.
我能想到的另一个风险是过度做的风险,从不需要所有额外的层.但那真的很糟糕吗?额外的类层真的如此昂贵,如果从未使用它们会有很大的损失吗?这里最大的费用和损失将是前面提到的层丢失的时间.但是,当人们可以使用抽象代码而不是更低级别的代码时,大部分时间仍然可以保存.
那么什么时候太多了?空白层和额外的"可能需要"抽象在什么时候变得有点过分?太少了?甜蜜点在哪里?
您在职业生涯中是否有任何可靠的经验法则可以帮助您判断所需的抽象量?
Cal*_*ius 31
抽象的要点是从特定的属性中分解出公共属性,就像在数学运算中一样:
ab + ac => a(b + c)
Run Code Online (Sandbox Code Playgroud)
现在你用两个操作而不是三个操作做同样的事情.这种因素使我们的表达更简单.
抽象的典型示例是文件系统.例如,您希望您的程序能够写入多种存储设备:笔式驱动器,SD卡,硬盘驱动器等......
如果我们没有文件系统,我们需要实现直接磁盘写入逻辑,笔式驱动器写入逻辑和SD卡写入逻辑.但所有这些逻辑都有一些共同之处:它们创建文件和目录,因此可以通过创建抽象层来抽象掉这些常见的东西,并为硬件供应商提供一个接口来完成特定的工作.
事物共享共同财产的次数越多.抽象可能更有益:
ab + ac + ad + ae + af
Run Code Online (Sandbox Code Playgroud)
至:
a(b + c + d + e + f)
Run Code Online (Sandbox Code Playgroud)
这会将9次操作减少到5次.
基本上每个良好的抽象大致将系统的复杂性减半.
您总是需要至少两个共享公共属性的东西才能使抽象变得有用.当然,你撕开一个东西,所以它看起来像一个抽象,但它并不意味着它是有用的:
10 => 5 * 2
Run Code Online (Sandbox Code Playgroud)
如果您只有一个实体,则无法定义单词"common".
所以回答你的问题.如果他们使您的系统尽可能简单,您就有足够的抽象.
(在我的例子中,加法连接系统的各个部分,而乘法定义了抽象 - 具体的关系.)
小智 26
太少了?
当你在日常工作中继续使用"低级"元素时,你总是觉得你不想这样做.摘要'他们离开了.
那么什么时候太多了?
当你不能定期制作一些代码部分的零碎时,必须将它们调试到前一层.你觉得这个特定的层没有贡献任何东西,只是一个障碍.算了吧.
甜蜜点在哪里?
我喜欢运用务实的方法.如果您认为需要抽象并了解它将如何改善您的生活,那就去做吧.如果你听说应该"正式"一个额外的抽象层,但你不清楚为什么,不要做,但先研究.如果有人坚持抽象某些东西但却无法清楚地解释将会带来什么,请告诉他们消失.
ewe*_*nli 22
那么什么时候太多了?空白层和额外的"可能需要"抽象在什么时候变得有点过分?太少了?甜蜜点在哪里?
我不认为对这些问题有明确的答案.需要经验来培养"太多"和"太少"的感觉.也许使用某些指标或质量控制工具可能有所帮助,但很难概括.这主要取决于每个案例.
以下是一些可能会激发您寻求答案的链接:
开发就是要在任何软件工程工作中出现的各种紧张关系之间找到适当的平衡点.
从理论上讲,应该只使用三个(相当简单的)变量进行简单的数学运算:
如果S*P> C,则代码良好.如果S*P <C,则表示不好.
然而,纯粹理论上的原因是你通常无法猜测使用概率或使用它所带来的节省.更糟糕的是,你无法猜测或者甚至通常无法衡量其存在的成本.
至少有些人从中得出了结论.在TDD中,标准的口号是"你不需要它"(YAGNI).简而言之,任何不直接有助于满足当前要求的代码都被认为是一件坏事.从本质上讲,他们已经得出结论,使用概率很低,包括这样的额外代码从来都不合理.
其中一些回归到"自下而上"与"自上而下"的发展.我倾向于将自下而上的开发视为"库开发" - 也就是说,不是开发特定的应用程序,而是在为应用程序中需要的各种东西开发库.我们的想法是,通过一个足够好的库,您可以相对容易地开发几乎所有类型的应用程序.
很多还取决于项目的规模.几十年来一直使用的巨大项目证明了比小型项目更长期投资更多,这些项目被丢弃并且更快地被替换.这在现实生活中也有明显的类比.您不必担心一次性剃须刀的合身性,光洁度或工艺性,您将在不到一周的时间内扔掉,就像您将在未来几年内使用的新车一样.
简单地说,如果代码难以理解,那么抽象太多了.
现在这并不是说您应该对所有内容进行硬编码,因为这是最容易编写和读取的代码.
最简单的测试是要么把它放下几天,然后再回头问自己,这是否有意义.更好的方法是将其交给其他人,看看他们是否可以做出正面或反面.