旗下导航:搜·么
当前位置:网站首页 > PHP教程 > 正文

php为何要用依靠注入?【php教程】,php依赖注入

作者:搜教程发布时间:2019-12-01分类:PHP教程浏览:31评论:0


导读:0.媒介在软件工程范畴,依靠注入(DependencyInjection)是用于完成掌握反转(InversionofControl)的最罕见的体式格局之一。本文重要...

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为何要用依靠注入?的细致内容,更多请关注ki4网别的相干文章!

标签:php依赖注入


欢迎 发表评论: