When do I want to declare interface over the actual class?
例如,我经常看到:
1 2 3 |
结束
1 2 3 |
前者与后者的优势/劣势是什么?
对我来说,这可以归结为几点。
你关心实施吗?您的代码需要知道
它还意味着,当我构建实现代码时,如果我公开一个返回map的方法,我可以在不影响任何依赖它的代码的情况下随时间更改实现(因此,尝试和强制转换这些类型的值是一个坏主意的原因)。
另一个原因是,在代码周围移动这些结构变得更容易,这样任何可以接受
约定(我遵循)基本上是使用满足API需求的最低功能接口。使用不提供API所需功能的接口是没有意义的(例如,如果您需要一个
IMHO
你应该阅读理解数据抽象,威廉·R·库克重温了这本书,以及他关于"对象"和"面向对象"的简化、现代定义的建议。
基本上:如果使用Java类作为工厂以外的任何东西,也就是说,如果在EDCOX1×7×操作符之后,任何地方都有一个类名,那么您就不做面向对象编程。遵循这条规则并不能保证您正在进行OO,但是违反这条规则意味着您没有这样做。
注意:不做OO没有什么问题。
通常,您希望声明具有实际使用行为的最一般的类型。这样,如果您决定采用不同的具体类,就不必更改那么多的代码。你可以让这个功能的用户更自由。
应用程序的维护成本是开发成本的三倍。这意味着您希望代码尽可能简单和清晰。
如果您使用列表而不是ArrayList,那么您将清楚地表明您没有使用任何对ArrayList特殊的方法,并且可以从另一个列表实现中更改它。在不必使用数组列表的情况下使用数组列表的问题是,要安全地确定它是否真的是一个列表需要很长时间。也就是说,很难证明你从不需要什么。(添加内容比删除内容相对容易)
一个类似的例子是在列表执行时使用向量。如果您看到您所说的向量;开发人员出于一个好的原因选择了一个向量,那么它是线程安全的。但我现在需要更改它并检查代码是否是线程安全的。你会说,但是我看不到它是如何以多线程的方式使用的,所以我必须检查所有可能使用它的方法,或者当我迭代它时,当它实际上不需要线程安全时,是否需要添加synchronized。在不需要时使用线程安全收集不仅浪费CPU时间,更重要的是浪费开发人员的时间。