java 设计模式之 -- 依赖注入

1,347 阅读2分钟
原文链接: zhuanlan.zhihu.com

Author:Bob(林补)
Date:2016/04/30
代码托管在开源中国:hws/JavaDesignPatterns

依赖注入的设计模式允许我们移除硬编码的依赖让我们的应用程序更加具有可拓展性和维护性。我们可以实现依赖注入模式,以实现从编译时到运行时的依赖。

依赖注入模式似乎很难用理论来把握,所以我会拿一个简单的例子,然后我们将看到如何使用依赖注入模式来实现应用程序中的松散耦合和扩展性。

在任何Java程序,我们经常会遇到以下两个事件。

但是,平时我们混淆了两者导致紧耦合和不必要的依赖从而使得维护以及单元测试的痛苦。让我尝试用一个非常简单的例子来解释一下:

class MyClass{
    private A a;//A是一个接口
    private B b;//B是一个接口

    MyClass(A a,B b){
        a = new AImpl();//AImpl是A接口的一个实现类
        b = new BImpl();//BImpl是B接口的一个实现类
    }   

    public void doSomething(){
        C c = new CImpl();//在该方法内部创建对象
    }
}

MyClass类的问题是:

1.它尚未能从业务逻辑中分离出来对象的创建导致紧密的耦合。

2.代码中已经完成面向实现编程,但没有面向接口编程。a = new AImpl();这句代码可以体现这个意思。如果某一天需要实现A,B或C中的不同实现方式,那么MyClass类中的代码必须要改变。

3.给测试带来不便。测试MyClass类需要先测试A,B,C;

接下来尝试修复该类存在的问题。

class MyClass{
    private A a;
    private B b;
    private C c;

    MyClass(A a, B b, C c){
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public void doSomething(){
        //实现业务逻辑代码
        a.doSomething();
    }
}

//工厂类
class MyFactory{
    public MyClass createMyClass(){
        return new MyClass(new AImpl(),new BImpl(),new CImpl());
    }

}

//测试类
class ApplicatoinTest{
    public static void main(String args[]){
        MyClass mc = new MyFactory().createMyClass();
        mc.doSomething();
    }
}

通过修改代码后实现了以下几点:

1.结构体方法没有new()方法存在。
对象没有在MyClass类中的构造方法方法中创建。构造方法只是被用于字段(A,B,C)的指向。这里的构造方法将依赖的对象作为参数,但是没有创建对象。实际上MyClass内部依赖的A,B,C实现对象应该交给MyFactory工厂类的来创建对象,然后再交给MyClass调用。

2.工厂类(MyFactory)负责对象的创建:
所有创建对象的操作应该属于工厂类来实现。该类不应该包含更多的其他逻辑(没有IO等)。这样就可减少对象之间的耦合。