程序员技术干货

剖析DI

2017-08-03  本文已影响49人  落叶飞逝的恋

0x00.前言

当我们研究一些晦涩的源码,上网查阅资料的时候,映入眼帘的总有这么些名词:DIP、IOC、DI、DL、IOC容器这些专业名词。如果不懂这些名词背后的含义,我们内心有可能是这样的:

image

0x01.小例子

/**
 * 餐厅类
 */
public class Restaurant {

    //后台收银系统
    private WeChatPay pay = new WeChatPay();

    //收款操作
    public void transact(double money) {
        pay.receiveMoney(money);
    }
}

import java.util.Date;

/**
 * 微信
 */
public class WeChatPay {
    public void receiveMoney(double money) {
        System.out.println(new Date() + ",已用微信收款:" + money + "元");
    }
}

image
这时候Restaurant类就依赖于WeChatPay,两个类产生依赖

0x02.DIP

DIP的英文名:Dependency Inversion Principle,中文名:依赖倒转原则

定义:

理解:

它仅仅是面向对象软件设计的一种原则。它仅仅告诉你两个模块之间如何协调依赖关系,但是并没有告诉你如何做!

举个例子

我们经常所说的三层架构(UI、BLL、DAL)

image image

图二的版本,就是高层模块依赖于低层模块的抽象,就好像依赖“倒置”。这样可以使得整体的架构更加的稳定,灵活,及自如的面对需求的变化。

0x03.IOC

0x04.DI

DI注入有三种方式

Demo讲解

/**
 * di Ipay 接口
 */
public interface IPay {
    void receiveMoney(double money);
}

/**
 * 重构后的微信支付
 */
public class WebChatPay implements IPay {
    public void receiveMoney(double money) {
        Date now = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(format.format(now) + ",已用重构后的微信收款:" + money + "元");
    }
}
/**
 * 重构后的餐厅类构造器注入
 */
public class Restaurant {

    private IPay _pay;

    public Restaurant(IPay pay) {
        this._pay = pay;
    }

    //收款操作
    public void transact(double money) {
        _pay.receiveMoney(money);
    }
}

0x01.构造器注入

System.out.println("==========通过构造函数注入开始==============");
IPay pay = new WebChatPay();//在外部创建依赖对象
Restaurant restaurant = new Restaurant(pay);
restaurant.transact(10);
System.out.println("==========通过构造函数注入结束==============");
image

这时候我们就看到Restaurant将依赖的WeChatPay对象的创建和绑定转移到Restaurant类外部来实现了。这样就解除了Restaurant类与WeChatPay类的耦合关系。如果将支付方式改成Alipay,只需要定义一个Alipay类,然后在外部重新绑定依赖。不需要修改Restaurant类。

0x02.属性注入

System.out.println("==========通过属性注入开始==============");
IPay paySetter = new WebChatPay();
RestaurantBySetter restaurantSetter = new RestaurantBySetter();
restaurantSetter.setPay(paySetter);
restaurantSetter.transact(10);
System.out.println("==========通过属性注入结束==============");
image

0x03.接口注入

System.out.println("==========通过接口注入开始==============");
IPay payInterface = new WebChatPay();
RestaurantByInterface restaurantInterface = new RestaurantByInterface();
restaurantInterface.extraInstance(payInterface);
restaurantInterface.transact(10);
System.out.println("==========通过接口注入结束==============");
image

0x05.IOC容器

DI框架,用来自动创建、维护依赖对象,并管理其生命周期。

常使用的IOC容器有:
Net:Ninject、Spring.NET、Unity、Autofac等
Java:Spring等

0x06.总结

IOC带来好处:

上一篇下一篇

猜你喜欢

热点阅读