php为什么要用依赖注入?-php教程

资源魔 31 0

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为何要用依赖注入?的具体内容,更多请存眷资源魔其它相干文章!

标签: php开发教程 php开发资料 php开发自学 php依赖注入

抱歉,评论功能暂时关闭!