【发布时间】:2016-06-05 08:31:06
【问题描述】:
我有一个接口,它定义了一些用于数据检索的服务方法:
public interface DataReceiver {
public Data getData();
}
然后我有一个实现此接口并通过连接加载数据的类。我使用构造函数注入提供此连接:
public class ConnectionDataReceiver implements DataReceiver {
private Connection connection;
public ConnectionDataReceiver(Connection connection) {
this.connection = connection;
}
public Data getData() {
return connection.query("blabla");
}
}
这很好用。我可以使用构造函数实例化我的ConnectionDataReceiver 对象,或者我可以添加一个工厂方法/类,通过提供一个选项来选择用于连接设置的配置文件来扩展可用性。然后我通过我的接口使用我的新类,所以我可以轻松地换出实现(比如从文件而不是连接加载数据)。
但是如果我想在运行时更改我的连接,而不实例化一个新的ConnectionDataReceiver,该怎么办?我将不得不为我的班级添加 getter 和 setter。但是由于它们不是我的公共服务定义的一部分,所以我不能将它们放在我的界面中。我可以在我的代码中使用实现对象来设置一个新的连接,但是仅仅为了改变连接对象而挂在对原始对象的引用上感觉很尴尬:
ConnectionDataReceiver conDataRec = new ConnectionDataReceiver(myConnection);
DataReceiver dataRec = conDataRec;
// use dataRec
conDataRec.setConnection(myNewConnection);
// use dataRec again
在这个例子中,最简单的方法是实例化一个新的ConnectionDataReceiver 并重新分配dataRec,但是如果我的对象的实例化真的很昂贵怎么办?我如何为我的实现类提供额外的功能,同时仍然能够使用我的旧服务接口?或者当接口没有定义该功能时,它通常会在运行时更改数据时皱眉吗?
【问题讨论】:
-
我认为您需要将问题的解决方案移至另一层,即使用
DataReceiver接口实现的层。在那里,您可以在运行时“注入”另一个实现。你没有展示DataReceiver是如何使用的,所以很难更详细 -
我会在我的业务逻辑代码中的某处使用 DataReceiver(类似于 1. 获取数据 2. 处理 3. 存储在数据库中)。我获取 DataReceiver 的方式并不重要,DI、Service Locator 等等,只要我可以轻松地在业务逻辑代码中切换我的实现即可。