简体   繁体   English

在接口中创建具体实现的新实例 - 这是反模式吗?

[英]Creating new instance of concrete implementation in interface - is this an antipattern?

Let's say I have the interface AuthorDao with two different implementation classes for example MyAuthorDaoImpl1 and MyAuthorDaoImpl2 .假设我的接口AuthorDao具有两个不同的实现类,例如MyAuthorDaoImpl1MyAuthorDaoImpl2

In my interface AuthorDao I have some basic crud methods and one extra method which is static for getting a new instance of MyAuthorDaoImpl1 .在我的界面AuthorDao ,我有一些基本的 crud 方法和一个额外的方法,即static用于获取MyAuthorDaoImpl1的新实例。

It looks like this:它看起来像这样:

public interface AuthorDao {

    void methodA();
    void methodB();
    ...
   
    static MyAuthorDaoImpl getInstance() {
        return new MyAuthorDaoImpl1();
    }
}

Questions问题

  1. Is this static method getInstance() is not an anti-pattern?这个 static 方法getInstance()不是反模式吗? Because in my opinion we shouldn't depend our interface on concrete implementation class, but my friend says it's okay, and he is pretty sure, that this should be work like this.因为在我看来,我们的接口不应该依赖于具体的实现 class,但是我的朋友说没关系,他很确定,这应该是这样的。 He says it is factory method .他说这是工厂方法
  2. He says we can create instances of this interface by constructor, we don't have to use this static method, therefore this is nothing bad.他说我们可以通过构造函数创建这个接口的实例,我们不必使用这个static方法,因此这没什么不好。 Is it true, that this is nothing bad?真的吗,这没什么不好? I think it is example of tight coupling and interface should not depend on concrete implementation, but he says this is not the case.我认为这是紧耦合的例子,接口不应该依赖于具体的实现,但他说事实并非如此。
  3. He refers that this is the same case like in Calendar class, because there is also getInstance() method.他提到这与Calendar class 中的情况相同,因为还有getInstance()方法。

Edit编辑

Also, in his opinion this static method will simplify refactoring if we will decide to change MyAuthorDaoImpl1 to MyAuthorDaoImpl2 .此外,在他看来,如果我们决定将MyAuthorDaoImpl1 MyAuthorDaoImpl2则此 static 方法将简化重构。 Because the only change will be in getInstance() method.因为唯一的变化将在getInstance()方法中。

This implementation is a circular dependency , which roughly looks like:这个实现是一个循环依赖,大致如下:

循环依赖

While it will likely work in Java, imagine what would happen if you no longer included the class MyAuthorDaoImpl when later you decided to implement ABetterAuthorDaoImpl .虽然它可能会在 Java 中工作,但想象一下,如果您稍后决定实施ABetterAuthorDaoImpl时不再包含 class MyAuthorDaoImpl会发生什么。 Now you have to change the interface.现在您必须更改界面。 It is a minor change in this case, but imagine it on a larger scale.在这种情况下,这是一个微小的变化,但可以在更大的范围内想象它。

Normally a factory method returns the interface type rather than the implementation type.通常,工厂方法返回接口类型而不是实现类型。 Example:例子:

class AuthorDaoFactory {

    static AuthorDao getInstance() {
        return new MyAuthorDaoImpl1();
    }
}

This avoids the circular dependency, demonstrated by this diagram:这避免了循环依赖,如下图所示:

在此处输入图像描述

You'll note that there is no circular path in the dependencies.您会注意到依赖项中没有循环路径。 This may not matter for this simple example, but what if your factory method created an instance of a class that was dynamically loaded based on a config?对于这个简单的示例,这可能无关紧要,但是如果您的工厂方法创建了一个基于配置动态加载的 class 实例怎么办? This is a common example of Inversion of Control (IoC) and is often used to do things like provide a common interface to different hardware.这是控制反转 (IoC) 的一个常见示例,通常用于执行诸如为不同硬件提供通用接口之类的操作。 The implementation is hidden behind the interface.实现隐藏在接口后面。

You'll notice that the Java Calendar class method getInstance returns the type Calendar .您会注意到 Java Calendar class 方法getInstance返回类型Calendar The underlying implementation may be locale-specific.底层实现可能是特定于语言环境的。 If you look at the description of the method in the Java documentation it says:如果您查看 Java 文档中的方法描述,它会说:

Gets a calendar using the default time zone and locale.获取使用默认时区和语言环境的日历。 The Calendar returned is based on the current time in the default time zone with the default locale.返回的日历基于具有默认语言环境的默认时区中的当前时间。

What is the implementation then?那么具体的实现方式是什么? You don't know and don't care, you only know it is of type Calendar .你不知道也不在乎,你只知道它是Calendar类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM