25 language-agnostic design-patterns interface
我读到的几乎所有Java书都谈到了使用接口作为共享对象之间的状态和行为的方式,当第一次"构造"似乎没有共享关系时.
但是,每当我看到架构师设计一个应用程序时,他们首先要做的就是开始编程接口.怎么会?您如何知道该界面中将出现的对象之间的所有关系?如果您已经了解这些关系,那么为什么不只是扩展一个抽象类?
Bri*_*haw 29
对接口进行编程意味着尊重使用该接口创建的"契约".因此,如果您的IPoweredByMotor接口有一个start()方法,那么实现该接口的未来类,无论是它们MotorizedWheelChair,Automobile还是SmoothieMaker在实现该接口的方法时,都会为您的系统增加灵活性,因为一段代码可以启动许多不同类型的电机.事情,因为所有一段代码需要知道的是他们的回应start().他们如何开始并不重要,只要他们必须开始.
Jon*_*han 23
好问题.我将把你推荐给Effective Java中的Josh Bloch,他写道(第16项)为什么更喜欢使用接口而不是抽象类.顺便说一句,如果你还没有这本书,我强烈推荐它!以下是他所说的内容摘要:
抽象类提供基本实现的优势如何?您可以为每个接口提供抽象骨架实现类.这结合了接口和抽象类的优点.骨架实现提供实现帮助,而不会强加抽象类在用作类型定义时强制施加的严格约束.例如,Collections Framework使用接口定义类型,并为每个接口提供骨架实现.
Joh*_*eff 20
接口编程提供了几个好处:
GoF类型模式必需,例如访客模式
允许替代实施.例如,对于抽象正在使用的数据库引擎的单个接口可能存在多个数据访问对象实现(AccountDaoMySQL和AccountDaoOracle都可以实现AccountDao)
Class可以实现多个接口.Java不允许具体类的多重继承.
摘要实现细节.接口可能只包含公共API方法,隐藏实现细节.好处包括清晰记录的公共API和记录良好的合同.
现代依赖注入框架(如http://www.springframework.org/)大量使用.
在Java中,接口可用于创建动态代理 - http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Proxy.html.这可以非常有效地用于诸如Spring之类的框架来执行面向方面编程.方面可以为类添加非常有用的功能,而无需直接向这些类添加Java代码.此功能的示例包括日志记录,审计,性能监视,事务划分等 .http://static.springframework.org/spring/docs/2.5.x/reference/aop.html.
模拟实现,单元测试 - 当依赖类是接口的实现时,可以编写也可以实现这些接口的模拟类.模拟类可用于促进单元测试.
怎么会?
因为这就是所有书籍所说的.与GoF模式一样,许多人认为它普遍适用,并且从未考虑它是否真的是正确的设计.
您如何知道该界面中将出现的对象之间的所有关系?
你没有,这是一个问题.
如果您已经了解这些关系,那么为什么不只是扩展一个抽象类?
不扩展抽象类的原因:
如果两者都不适用,请继续使用抽象类.它会为你节省很多时间.
你没问过的问题:
使用界面的缺点是什么?
你无法改变它们.与抽象类不同,界面是一成不变的.一旦你有一个使用它,扩展它将打破代码,期间.
我真的需要吗?
大多数时候,没有.在构建任何对象层次结构之前要认真思考.像Java这样的语言的一个大问题是,它使得创建大规模,复杂的对象层次结构变得非常容易.
考虑LameDuck继承自Duck的经典示例.听起来很简单,不是吗?
好吧,直到你需要表明鸭子已经受伤并且现在是跛脚.或者表明跛脚鸭已经愈合并且可以再次行走.Java不允许您更改对象类型,因此使用子类型来指示跛足实际上不起作用.