百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>网页制作> php为何要用依赖注入?
分享文章到:

php为何要用依赖注入?

发布时间:09/01 来源:未知 浏览: 关键词:

由于依靠注入会落低依靠和被依靠类型间的耦合,在修改被依靠的类型实现时,不需要修改依靠类型的实现;同时,关于依靠类型的测试,可以更利便的使用“mocking object”替换原有的被依靠类型,以到达对依靠对象独立停止单元测试的目的。

0. 前言

在软件工程领域,依靠注入(Dependency Injection)是用于实现操纵反转(Inversion of Control)的最常见的方式之一。本文主要介绍依靠注入道理和常见的实现方式,重点在于介绍这种年轻的设计模式的适用处景及优势。

1. 为什么需要依靠注入

操纵反转用于解耦,解的毕竟是谁和谁的耦?这是我在最初理解依靠注入时候发生的第一个问题。

下面我援用Martin Flower在说明介绍注入时使用的一部分代码来说明这个问题。

public class MovieLister {
    private MovieFinder finder;

    public MovieLister() {
        finder = new MovieFinderImpl();
    }
    
    public Movie[] moviesDirectedBy(String arg) {
        List allMovies = finder.findAll();
        for (Iterator it = allMovies.iterator(); it.hasNext();) {
            Movie movie = (Movie) it.next();
            if (!movie.getDirector().equals(arg)) it.remove();
        }
        return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
    }
    ...
}
public interface MovieFinder {
    List findAll();
}

我们创立了一个名为MovieLister的类来供给需要的电影列表,它moviesDirectedBy办法供给按照导演名来搜索电影的方式。真正负责搜索电影的是实现了MovieFinder接口的MovieFinderImpl,我们的MovieLister类在结构函数中创立了一个MovieFinderImpl的对象。

当前看来,一切都不错。但是,当我们但愿修改finder,将finder更换为一种新的实现时(比方为MovieFinder增添一个参数表白Movie数据的来源是哪个数据库),我们不仅需要修改MovieFinderImpl类,还需要修改我们MovieLister中创立MovieFinderImpl的代码。

这就是依靠注入要处置的耦合。这种在MovieLister中创立MovieFinderImpl的方式,使得MovieLister不仅仅依靠于MovieFinder这个接口,它还依靠于MovieListImpl这个实现。 这种在一个类中直接创立另一个类的对象的代码,和硬编码(hard-coded strings)乃至硬编码的数字(magic numbers)一样,是一种致使耦合的坏味道,我们可以把这种坏味道称为硬初始化(hard init)。同时,我们也应当像记住硬编码一样记住,new(对象创立)是有毒的。

Hard Init带来的主要害处有两个方面:1)上文所述的修改其实现时,需要修改创立处的代码;2)不便于测试,这种方式创立的类(上文中的MovieLister)没法独自被测试,其行动和MovieFinderImpl紧紧耦合在一起,同时,也会致使代码的可读性问题(“假如一段代码不便于测试,那么它必然不便于阅读。”)。

2. 依靠注入的实现方式

依靠注入其实并不奇妙,我们日常的代码中许多都用到了依靠注入,但很少留意到它,也很少主动使用依靠注入停止解耦。这里我们简便介绍一下赖注入实现三种的方式。

2.1 结构函数注入(Contructor Injection)

这是我认为的最简便的依靠注入方式,我们修改一下上面代码中MovieList的结构函数,使得MovieFinderImpl的实此刻MovieLister类之外创立。这样,MovieLister就只依靠于我们定义的MovieFinder接口,而不依靠于MovieFinder的实现了。

public class MovieLister {
    private MovieFinder finder;

    public MovieLister(MovieFinder finder) {
        this.finder = finder;
    }
    ...
}

2.2 setter注入

相似的,我们可以增添一个setter函数来传入创立好的MovieFinder对象,这样一样可以幸免在MovieFinder中hard init这个对象。

public class MovieLister {
    s...
    public void setFinder(MovieFinder finder) {
        this.finder = finder;
    }
}

2.3 接口注入

接口注入使用接口来供给setter办法,其实现方式如下。

第一要创立一个注入使用的接口。

public interface InjectFinder {
    void injectFinder(MovieFinder finder);
}

之后,我们让MovieLister实现这个接口。

class MovieLister implements InjectFinder {
    ...
    public void injectFinder(MovieFinder finder) {
      this.finder = finder;
    }
    ...
}

最后,我们需要按照不一样的框架创立被依靠的MovieFinder的实现。

3. 最后

依靠注入落低了依靠和被依靠类型间的耦合,在修改被依靠的类型实现时,不需要修改依靠类型的实现,同时,关于依靠类型的测试,可以更利便的使用mocking object替换原有的被依靠类型,以到达对依靠对象独立停止单元测试的目的。

最后需要留意的是,依靠注入只是操纵反转的一种实现方式。操纵反转还有一种常见的实现方式称为依靠查寻。

以上就是php为什么要用依靠注入?的具体内容,更多请关注百分百源码网其它相关文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有150人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板