将接口与其实现分离有什么意义?



这是企业Java级别中的常见设计(尽管大多数时间参考都会由某些框架/库注入):

我有一个接口

import java.util.*;
public interface ProductRepository {
    public List <Product> getAllProducts();
}

及其实施

public class ProductRepositoryImp implements ProductRepository {
    private List<Product> products = new ArrayList<Product>();
    public ProductRepositoryImp() {
        products.add(new Product("Blackberry", 24000));
        products.add(new Product("Nokia", 45000));
        products.add(new Product("Samsung", 91000));
    }
    @Override
    public List<Product> getAllProducts() {
        return this.products;
    }
    public int localMethod(){
        return 2;
    }
}

在主类(控制器)中i引用接口(ProductRepository)而不是实现(ProductRepositoryImp

public class ProductController {
    static ProductRepository productRepository;
    public static void main(String[] args) {
        productRepository = new ProductRepositoryImp();
        for (Product p : productRepository.getAllProducts()) {
            System.out.println(p.getName());
            System.out.println(p.getPrice());
            System.out.println("");
        } } }

为什么?

这是我在书中读到的解释:

连接两个的最佳做法不是 具有直接参考的图层(控制器和持久性)。相反,我们将来可以有一个 控制器中的接口参考,以便我们可以轻松切换到不同的实现 存储库的无需进行控制器类中的任何代码更改。

ProductRepository实例而不是ProductRepositoryImp的实例访问.getAllProducts()有什么好处?

在上面的引文中切换任何代码更改的情况下," "的意义是什么?我知道如果我们有可以说" AnotherProductRepositoryImp"?

如果我想大量访问某些 .localMethod() 而不是 ProductRepositoryImp实例中的

从 productRepository实例,而不是 productRepositoryImp?

producterTository是您数据层的接口。它完全不可知基础数据库。

"不做任何代码更改"切换的意义是什么 上面引用?我知道如果我们说这是相关的 "另一个productropositoryimp"?。

在这种情况下,它与AnotherProductRepositoryImp无关,但可以说基础数据库更改。每个数据库具有不同的查询格式,并且查询的相应实现在ProductRepositoryImpl类中。更改不会是AnotherProductRepositoryImp,而是ProductMongoRepositoryImpProductMySqlRepositoryImpProductFileRepositoryImp

如果您要编码到接口,则无需对控制器进行任何更改。只是注入另一个实现,您就完成了。

如果我想重新访问一些.localmethod(),那是 在productrepositoryimp实例中?

如果您使用的是任何不是接口的一部分而仅在实施中内部使用的方法,那么它不是与接口的合同的一部分,不必接触到外界(即将其私有化为私有)。如果要暴露于外界,则意味着它不在与接口的合同之外。您通常需要将正确的实例类型输入以访问该值。

好处是,您可以将另一个实现者注入控制器,例如用于测试的模拟存储库,或用于其他SQL方言的存储库。

将界面与实现分开也可以用来使其明确呼叫者使用哪种方法(参见信息隐藏,封装),尽管这也可以通过访问修饰符(例如private)来实现。重要的是团队同意他们用哪种信号机制避免误解。

虽然许多早期企业框架要求使用接口,但最著名的是EJB,直到版本3.1,现代框架不再执行。

今天,是否应该仅存在一个实现的接口,这是有些争议的。有些人说是一致性,有些人说否。

最新更新