![](/img/trans.png)
[英]Creating spring bean in xml configuration for an interface without concrete implementation
[英]Creating new instance of concrete implementation in interface - is this an antipattern?
假设我的接口AuthorDao
具有两个不同的实现类,例如MyAuthorDaoImpl1
和MyAuthorDaoImpl2
。
在我的界面AuthorDao
,我有一些基本的 crud 方法和一个额外的方法,即static
用于获取MyAuthorDaoImpl1
的新实例。
它看起来像这样:
public interface AuthorDao {
void methodA();
void methodB();
...
static MyAuthorDaoImpl getInstance() {
return new MyAuthorDaoImpl1();
}
}
问题
getInstance()
不是反模式吗? 因为在我看来,我们的接口不应该依赖于具体的实现 class,但是我的朋友说没关系,他很确定,这应该是这样的。 他说这是工厂方法。static
方法,因此这没什么不好。 真的吗,这没什么不好? 我认为这是紧耦合的例子,接口不应该依赖于具体的实现,但他说事实并非如此。Calendar
class 中的情况相同,因为还有getInstance()
方法。编辑
此外,在他看来,如果我们决定将MyAuthorDaoImpl1
MyAuthorDaoImpl2
则此 static 方法将简化重构。 因为唯一的变化将在getInstance()
方法中。
这个实现是一个循环依赖,大致如下:
虽然它可能会在 Java 中工作,但想象一下,如果您稍后决定实施ABetterAuthorDaoImpl
时不再包含 class MyAuthorDaoImpl
会发生什么。 现在您必须更改界面。 在这种情况下,这是一个微小的变化,但可以在更大的范围内想象它。
通常,工厂方法返回接口类型而不是实现类型。 例子:
class AuthorDaoFactory {
static AuthorDao getInstance() {
return new MyAuthorDaoImpl1();
}
}
这避免了循环依赖,如下图所示:
您会注意到依赖项中没有循环路径。 对于这个简单的示例,这可能无关紧要,但是如果您的工厂方法创建了一个基于配置动态加载的 class 实例怎么办? 这是控制反转 (IoC) 的一个常见示例,通常用于执行诸如为不同硬件提供通用接口之类的操作。 实现隐藏在接口后面。
您会注意到 Java Calendar
class 方法getInstance
返回类型Calendar
。 底层实现可能是特定于语言环境的。 如果您查看 Java 文档中的方法描述,它会说:
获取使用默认时区和语言环境的日历。 返回的日历基于具有默认语言环境的默认时区中的当前时间。
那么具体的实现方式是什么? 你不知道也不在乎,你只知道它是Calendar
类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.