2011-04-28 37 views
6

我正在浏览Effective Java并阅读用于创建对象的静态工厂方法。它的第2章第1项。 3,作者提到像什么是基于接口的框架?

以这种方式隐藏实现类可能会导致一个非常紧凑的API。这种技术适用于基于接口的框架,其中接口为静态工厂方法提供自然返回类型。

我不明白基于接口的框架是什么?

回答

6

也许改写这一点会有所帮助:

一个基于接口的框架是一个fr只有在实际交付实现这些接口的类时,才允许用户/客户端lib访问接口。

这种方法的好处在于让实现者完全控制实现并同时为客户端提供稳定的API。

我最近遇到一个例子,客户端从API方法获得XmlProcessor。在框架内部,有三种完全不同的处理器实现:一个DomXmlProcessor,SaxXmlProcessor和一个VtdXmlProcessor。单个实现的细节不受客户关注,可以随时切换。

+0

对不起编辑错误答案:) – Bozho 2011-04-28 10:55:12

+0

@Bozho继续前进,我的也可以用一些:) – kostja 2011-04-28 11:29:48

+0

太棒了!一个例子值得超过一千个解释! – dellasavia 2017-01-10 18:42:43

4

基于接口的框架是那些使用接口及其实现设计的框架。

Collection framework是基于接口的框架的一个很好的例子。以这种方式

隐藏实现类可能会导致一个非常紧凑的API

你只需要创建一个接口

interface Animal{ 
public void eat();//hiding the implementation 
public Animal getAnimalInstance();//factory method 
} 

您的实施者将采取落实照顾。

您的API消费者将direcrtly使用的界面,就像我们在收集

List<String> list = new ArrayList<String>(); 

做另请参见

+2

我不认为你已经解释了什么基于接口的框架。你刚刚没有蛋糕就结了冰。 – 2011-04-28 10:54:38

+0

确定接口允许声明静态方法吗? – darkapple 2011-04-28 11:06:35

+0

我有点困惑。但是这条线索表明我们不能。 http://stackoverflow.com/questions/21817/why-cant-i-declare-static-methods-in-an-interface – darkapple 2011-04-28 11:12:30

1

框架,主要暴露接口,它们的用户(而非具体实现)

既然你提到布洛赫,我会给与集合框架的例子。你可以看到Collections类有synchronizedX(..)unmodifiableX(..),singletonX(..)方法。这些都是静态工厂方法,并且有很多这些方法,但它们只返回接口 - ListMap,SetSortedMap。在幕后,有大量的实现你不需要知道。

另一个例子(但没有关注静态工厂)是JDBC API。这里几乎没有类 - Connection,Stetement,PreparedStatement,ResultSet等都是接口。这允许许多实现针对不同的数据库而存在,而用户没有任何区别。 (想象一下,如果您必须在您的代码类中使用,如MySQLStatementOracleConnection等)

1

当您设计软件时,有核心设计原则来帮助管理复杂任务中涉及的复杂性。

其中一个核心原则是将复杂的问题细分成更小的问题,更易于管理和理解。

接口实际上是一个合同。它定义了一个类必须符合的服务以及如何使用它。该界面隐藏了合同的一个或几个可能实现的实现细节。

一个典型的Java应用程序将被设计为具有接口来模拟由软件的不同部分提供的核心契约。实现细节是隐藏的,因此可以降低复杂性。

更具体一点,可以说你设计一个会计应用程序。所有账户都提供相同的基本服务:获得当前余额,信贷或提取资金,请求过去操作的摘要。您可以定义一个接口一样,所有类型的帐户将符合:

public interface Account { 

    double getBalance(); 

    void credit(double amount); 

    void withdraw(double amount); 

    List<Operation> getOperations(Date startDate, Date endDate); 

} 

根据这个定义,很容易例如提供一个用户界面,允许用户来管理它的帐户。实际上支票账户和信用卡账户之间存在差异。你将不得不直接在银行数据库中管理不同的账户,或者远离其他银行的账户。一个是直接操作,另一个是使用某种网络协议来执行操作。

但从您的角度来看,您只需要满足合同。你可以在账户上工作。关于如何完成特定帐户操作的详细信息不是您的问题。

这是花哨和不错,但仍然存在问题。你如何获得你的账户?这是来自另一家银行的折扣账户肯定不同于本地账户。代码是不同的。还有创建它的方法。对于远程帐户,您需要例如其他银行服务器的网络地址......另一个可能需要数据库ID。

每次您需要拥有一个帐户时,您都可以明确地重新创建它,或者使用所有实现细节获取它。获得一个遥远的帐户或本地帐户是非常不同的。

在应用程序的一部分中分离这种复杂性是一种很好的做法。它符合将复杂任务细分为更小,更简单的任务。

我给出了会计应用的例子,但实际上我们可以更一般。在任何软件中创建对象和检索已经创建的对象是一个非常普遍的问题。所以我们有一个可以保持清洁的方式来做这件事的共同“好方法”。

管理创建获取特定对象的复杂性的代码隐藏了实际上对象是如何构造或给定的,称为工厂。

如果Java程序员使用工具来管理软件复杂性,那么将工厂(隐藏创建/查找对象的复杂性)和接口(隐藏每个对象实现的复杂性)相结合。