有时我会在企业应用程序架构中遇到关于继承“超出风格”的评论,但我没有看到描述竞争理论的文章的链接。另外,如果应用程序已经构建而不是从头开始,那么实现是否存在差异?我认为这可能与严重依赖接口有关,但我不确定。
答案 0 :(得分:7)
我认为你指的是设计原则:
“赞成组合而不是继承。”
答案 1 :(得分:3)
继承的一种非常流行的替代方法(如子类化)是对象组合和委托。
所以而不是
public class B extends A implements I {
// now I have all the methods from A
}
你做了
public class B implements I {
private I a;
// delegate all methods
public void methodOne(){
a.methodOne();
}
}
组合比子类化更灵活:
答案 2 :(得分:2)
这是一个工具
组成
每当我读到这样的毯子时,我都会想:
十字螺丝比Flatheads好。
当你需要钉子或焊接时,两者都没有任何好处,当你知道自己在做什么时,其中一种或两种都很好。
两者之间的区别是鲜明而简单 - “is-a”与“has-a” - 虽然组合可用于模拟继承(使用 lot 的额外工作)相反的情况通常不正确。这是不反对继承的参数,也不是组合的参数。
模型的语义远比用于表示模型的机制重要。如果说“爬行动物有动物并使用授权来揭露它的方法和属性”,而不是“爬行动物是一种动物”,那不是很愚蠢吗?那么为什么对一个不必要的对象做同样的事情而不仅仅是愚蠢的呢?
继承非常有用,是面向对象编程的基础。它不会消失,直到有更好的东西出现,我还没有发表; - )
[让火焰开始!]
答案 3 :(得分:0)
这不是一个架构问题,而是一个非常严谨的类设计问题。实现继承有两个难点:fragile base class problem和继承关系的静态特性。
这种情况下的经典替代方案是具有组合的接口实现的decorator pattern:新对象包含对它包装的低级对象的引用,并转发对它的调用,可能包含或替换了一些调用顾左右而言他。单个包装类可以使其实例包装不同的底层服务实现,并且包装器不太可能被脆弱的基类问题打破,因为它无法访问受保护的成员。
答案 4 :(得分:0)
还有Traits& Smalltalk中的角色& Perl的。它们让您重用功能。看看这个article。
答案 5 :(得分:0)
Allen Holub描述in this article如何实现接口优于子类化。虽然这是在2003年写的,但仍然是主题。有趣的是,2009年有很多评论!
答案 6 :(得分:0)
如果您使用的是C ++,那么您应该认真考虑使用mixins(注意:其他一些语言声称支持某种形式的mixin):
Wikipedia: http://en.wikipedia.org/wiki/Mixin
Dr. Dobbs: http://www.ddj.com/cpp/184404445.
更有趣的是“奇怪的重复出现的模板模式”(CRTP):
Wikipedia: http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern.
我认为CRTP是mixins的一个非常有用的应用程序。
一旦你“得到它”(这需要一段时间),你会发现mixins是非常pwerful。它们为您提供了一种代码重用方法,它不会受到继承重用的问题,但比使用组合和委托更灵活,更有效。
有趣的是,CRTP允许您模拟虚函数调用,消除实际虚函数调用的开销(时间和空间),而不需要特定的语言功能。删除虚函数调用允许编译器提供更好的优化,从而提高性能。
好处列表一直在继续...在不利方面,它在语法上是丑陋的C ++,但你学会了这个。使用宏来形成mixin链可以使代码更具可读性。
在我看来,我将mixins视为可重复使用的代码片段,可用于构建类。通常,它们可以帮助您实现接口,提供常用的方法实现。你最终觉得你可以只是“去购物”了解构成你班级的部分,并且很少有“管道工作”来使部件协同工作。