PHP 종속성 주입과 제어 반전의 두 가지 개념을 이해하려면 다음 두 가지 문제를 이해해야 합니다.
DI —— 종속성 주입
-
IoC —— 제어 반전
의존성 주입이란 무엇입니까
당신 없이는 살 수 없습니다. 그렇다면 당신은 나의 의존성입니다. 직설적으로 말하면:
그것은 내 것이 아니지만 나에게 필요하고 의지하는 것입니다. 외부적으로 제공되어야 하는 모든 것에는 종속성 주입이 필요합니다.
종속성 주입의 예
1
2
3
4
5
6
7 8 9 101112 131415161718
|
class 소년 {
class Boy {
protected $girl ;
public function __construct(Girl $girl ) {
$this ->girl = $girl ;
}
}
class Girl {
...
}
$boy = new Boy();
$girl = new Girl();
$boy = new Boy( $girl ); 보호됨 $girl ;
|
공개
함수 <code class="php plain">__construct(소녀
$girl
) {
$this
->girl =
$girl
;
🎜🎜
}
🎜🎜
}
🎜🎜🎜🎜
클래스
여자 {
🎜🎜
...
🎜🎜
} code >🎜🎜 🎜🎜<code class="php 변수">$boy
=
새
Boy(); 🎜🎜 🎜🎜🎜🎜
$girl
=
새
Girl();
🎜🎜🎜🎜
$boy
=
새
소년(
$girl
)
🎜🎜🎜🎜🎜🎜
위 코드에서 Boy
는 Girl
에 크게 의존하고 Girl
인스턴스는 생성 중에 삽입되어야 함을 알 수 있습니다.
Boy
强依赖
Girl
必须在构造时注入
Girl
的实例才行。
那么为什么要有依赖注入
这个概念,依赖注入
到底解决了什么问题?
我们将上述代码修正一下我们初学时都写过的代码:
1
2
3
4
5
6
7
|
class Boy {
protected $girl ;
public function __construct() {
$this ->girl = new Girl();
}
}
|
这种方式与前面的方式有什么不同呢?
我们会发现Boy
的女朋友被我们硬编码到Boy
的身体里去了。。。 每次Boy
重生自己想换个类型的女朋友都要把自己扒光才行。
某天Boy
特别喜欢一个LoliGirl
,非常想让她做自己的女朋友。。。怎么办? 重生自己。。。扒开自己。。。把Girl
扔了。。。把 LoliGirl
塞进去。。。
1
2
3
4
5
6
7
8
9
10
11
12
|
class LoliGirl {
}
class Boy {
protected $girl ;
public function __construct() {
$this ->girl = new LoliGirl();
}
} 그렇다면 종속성 주입 이라는 개념이 왜 있는 걸까요? 종속성 주입 은 어떤 문제를 해결하나요? 위 코드를 우리가 처음에 작성했던 코드로 수정해 보겠습니다:
6🎜 7🎜🎜
클래스 소년 { 🎜
보호됨 $girl ; 🎜 🎜
공개 함수 __construct() { 🎜
$this ->girl = new Girl(); 🎜
} 🎜
} 🎜🎜🎜🎜🎜🎜🎜🎜🎜이 방법과 이전 방법의 차이점은 무엇인가요? 🎜우리는 소년 의 여자친구가 소년 의 몸에 하드코딩되어 있음을 발견하게 됩니다. . . 소년 이 다시 태어나서 다른 유형의 여자친구를 원할 때마다 그는 발가벗겨야 합니다. 🎜어느 날 소년 은 롤리걸 을 정말 좋아하고 그녀가 자신의 여자친구가 되기를 진심으로 원합니다. . . 무엇을 해야 할까요? 자신을 다시 태어나십시오. . . 자신을 발견하세요. . . 소녀 를 버리세요. . . 롤리걸 을 안에 넣어주세요. . . 1🎜 2🎜 3🎜 4🎜 5🎜 6🎜 7🎜 8🎜 9🎜 10🎜 11🎜 12🎜🎜
클래스 로리걸 { 🎜 🎜
} 🎜 🎜
클래스 소년 { 🎜
보호됨 $girl ; 🎜 🎜 code><code class="php 키워드">공개 함수 __construct() { 🎜
🎜
$this ->girl = new LoliGirl(); 🎜
어느 날 소년 은 유 자매와 사랑에 빠졌습니다.... 소년 은 너무 짜증났습니다. . .
Boy 迷恋上了御姐.... Boy 好烦。。。 是不是感觉不太好?每次遇到真心相待的人却要这么的折磨自己。。。
Boy 说,我要变的强大一点。我不想被改来改去的!
好吧,我们让Boy 强大一点:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
interface Girl {
}
class LoliGril implement Girl {
}
class Vixen implement Girl {
}
class Boy {
protected $girl ;
public function __construct(Girl $girl ) {
$this ->girl = $girl ;
}
}
$loliGirl = new LoliGirl();
$vixen = new Vixen();
$boy = new Boy( $loliGirl ); 기분 좋지 않나요? 나를 진심으로 대해주는 사람을 만날 때마다 나는 이렇게 나 자신을 고문해야 한다. . .
소년 은 "나는 더 강해지고 싶다"고 말했다. 나는 몇 번이고 변하고 싶지 않습니다! 🎜좋아요, Boy 를 좀 더 강력하게 만들어 보겠습니다.
|
인터페이스 소녀 { 🎜
🎜 } 🎜 🎜 클래스 LoliGril 구현 소녀 { 🎜
🎜 } code >🎜<div class="line number8 index7 alt1"> 🎜<div class="line number9 index8 alt2">
<code class="php 키워드">클래스 빅센 Girl 구현 { 🎜
🎜
} 🎜 🎜
클래스 소년 { 🎜 보호됨 $girl ; 🎜 🎜
공개 함수 __construct(소녀 $girl ) { 🎜
$ this ->girl = $girl ;🎜<div class="line number18 index17 alt1">
<code class="php space"> } 🎜
} 🎜 🎜
$loliGirl = 새 LoliGirl();🎜<div class="line number22 index21 alt1">
<code class="php 변수">$vixen = new Vixen(); 🎜 🎜 $boy = 새 소년( $loliGirl ); 🎜
$boy = new Boy( $vixen );
|
Boy 很高兴,终于可以不用扒开自己就可以体验不同的人生了。。。So Happy!
依赖注入方式
1、构造器 注入
1
2
3
4
5
6
7
8
|
<?php class Book {
private $db_conn ;
public function __construct( $db_conn ) {
$this ->db_conn = $db_conn ;
}
}
|
2、세터 注入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2 4
25
26
27
|
<?php <?php class Book {
private $db ;
private $file ;
function setdb( $db ) {
$this ->db = $db ;
}
function setfile( $file ) {
$this ->file = $file ;
}
}
class file {
}
class db {
}
class test {
$book = new Book();
클래스 책 { 🎜 🎜 비공개 $db ; 🎜🎜 비공개 $file ; 🎜🎜 🎜🎜 함수 setdb( $db ) { 🎜🎜 $this ->db = $db ; 🎜🎜 } 🎜🎜 🎜 🎜 함수 setfile( $file ) { 🎜🎜 $this->file = $file ; 🎜🎜} } 🎜🎜} 🎜🎜 🎜🎜클래스 파일 { 🎜🎜 } 🎜🎜 🎜🎜 클래스 db { 🎜🎜 } 🎜🎜 🎜🎜 // ... 🎜🎜 🎜🎜 클래스 테스트 { 🎜🎜 $book = new Book(); 🎜
$book ->setdb( new db());
$book ->setfile( new file());
}
|
요약:
대부분의 애플리케이션은 비즈니스 로직을 구현하기 위해 서로 협력하는 두 개 이상의 클래스로 구성되기 때문에 각 개체는 자신이 협력하는 개체(즉, 자신이 속한 개체)를 얻어야 합니다. 종속 개체에 대한 참조)와 협력합니다. 이 획득 프로세스가 자체적으로 구현되면 코드가 고도로 결합되어 유지 관리 및 디버깅이 어려워집니다.
그래서 우리는 종속성 주입이라는 개념을 갖게 되었습니다. 종속성 주입은 다음과 같은 문제를 해결합니다.
종속성 간의 분리
Mock에 편리한 단위 테스트
위 두 가지 방법의 코드는 매우 하지만 많은 종속성을 주입해야 하는 경우에는 많은 줄을 추가해야 한다는 의미이므로 관리하기가 더 어려워집니다.
더 나은 솔루션은 모든 종속성에 대한 컨테이너로 클래스를 생성하는 것입니다. 이 클래스에서는 필요한 종속성을 저장, 생성, 획득 및 찾을 수 있습니다. 먼저 IOC
제어 반전(IOC)
제어 반전은 컴퓨터 코드 간의 결합을 줄이는 데 사용할 수 있는 객체 지향 프로그래밍의 설계 원리입니다. 가장 일반적인 방법은 DependencyInjection(DI)이고 다른 하나는 "Dependency Lookup"입니다. 제어 역전을 통해 객체가 생성되면 시스템의 모든 객체를 제어하는 외부 엔터티가 자신이 의존하는 객체의 참조를 전달합니다. 의존성이 객체에 주입된다고도 말할 수 있습니다. ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 11 12 13
14
<?php 클래스 Ioc {< /code></div><div class="line number6 index5 alt1"><code class="php space"> 보호됨 $db_conn ;
공개 static 함수 make_book() {
</code code> 코드><code class="php 변수">$new_book = 새 Book();
$new_book ->set_db(self:: $db_conn );
반환 $new_book ; 코드 >
|
} }
}
<?php class Ioc {
protected $db_conn ;
public static function make_book() {
$new_book = new Book();
$new_book ->set_db(self:: $db_conn );
return $new_book ;
}
} |
이때, book 인스턴스를 얻으려면 $newone = Ioc::makebook();
만 실행하면 됩니다. 위는 컨테이너의 특정 인스턴스이므로 구체적으로 작성하지 않는 것이 가장 좋습니다. 의존성 주입 방법을 사용하여 레지스트리에 등록하고 얻는 것이 좋습니다. 21 22 2324 2526272829 30313233 34353637 38394041 42434445 4647
& lt;?php
코드><code class="php 주석">*/
클래스 Ioc {
*/
보호됨 정적 $registry = 배열 code><code class="php plain">();
public static function register( $name , Closure $resolve ) {
static :: $registry [ $name ] = $resolve ;
}
public static function resolve( $name ) {
if ( static ::registered( $name )) {
$name = static :: $registry [ $name ];
return $name ();
}
throw new Exception( "Nothing registered with that name" );
}
public static function registered( $name ) {
return array_key_exists ( $name , static :: $registry );
}
}
|
现在就可以通过如下方式来注册和注入一个
1
2
3
4
5
6
7
8
9
10
11
|
<?php Ioc::register( "book" , function () {
$book = new Book();
$book ->setdb( 'db' );
$book ->setfile( 'file' );
return $book ;
});
$book = Ioc::resolve( 'book' );
|
질문요약
1. 참가자는 누구인가요?
답변: 일반적으로 세 부분이 있는데, 하나는 객체이고, 다른 하나는 객체의 외부 리소스입니다. 명사에 대해 다시 설명하겠습니다. 객체는 일반적인 Java 객체를 참조하며, IoC/DI 컨테이너는 단순히 IoC/DI 기능을 구현하는 데 사용되는 프레임워크 프로그램을 참조합니다. 개체 외부에서 개체에 필요한 다른 개체 또는 개체에 필요한 파일 리소스 등과 같이 집합적으로 리소스라고 합니다.
2. 의존성: 누가 누구에게 의존하나요? 종속성이 있는 이유는 무엇입니까?
답변: 객체는 IoC/DI 컨테이너에 따라 다릅니다. 프로젝트에서는 다양한 클래스 사이에 다양한 관계가 존재하며, 이들 모두가 완전히 독립적일 수는 없으므로 종속성을 형성합니다. 기존 개발에서는 다른 클래스를 사용할 때 직접 호출을 사용했는데, 이는 강력한 결합을 형성하므로 피해야 합니다. 종속성 주입은 컨테이너를 빌려 종속 개체를 전송하여 분리를 달성합니다.
3. 주사: 누가 누구에게 주사하나요? 정확히 무엇을 주입하나요?
답변: 컨테이너를 통해 객체에 필요한 외부 리소스를 주입합니다
4. 제어 역전: 누가 누구를 제어합니까? 무엇을 통제하나요? 왜 반전이라고 불리는가?
답변: IoC/DI 컨테이너 제어 객체는 주로 객체 인스턴스 생성을 제어합니다. 반전은 양의 방향에 상대적이므로 양의 방향으로 간주되는 것은 무엇입니까? 일반적인 상황에서 애플리케이션을 생각해 보세요. A 내부에서 C를 사용하려면 어떻게 하시겠습니까? 물론 C의 객체는 직접 생성된다. 즉, 필요한 외부자원 C를 클래스 A에서 적극적으로 획득하는 상황을 포워드(forward)라고 한다. 그렇다면 반전은 무엇인가? 즉, 클래스 A는 더 이상 C를 적극적으로 획득하지 않고 IoC/DI 컨테이너가 C의 인스턴스를 획득할 때까지 수동적으로 기다린 다음 이를 역으로 클래스 A에 주입합니다.
5. 의존성 주입과 제어 역전은 동일한 개념인가요?
답변: 위에서 볼 수 있듯이 종속성 주입은 애플리케이션의 관점에서 설명됩니다. 종속성 주입은 더 자세히 설명할 수 있습니다. 애플리케이션은 컨테이너에 의존하여 필요한 외부 리소스를 생성하고 주입합니다. 제어 반전은 컨테이너의 관점에서 설명이 완료됩니다. 컨테이너는 애플리케이션을 제어하고, 컨테이너는 역으로 애플리케이션에 필요한 외부 리소스를 애플리케이션에 주입합니다.
|
|
|
|
|
위 내용은 PHP 종속성 주입(DI) 및 제어 반전(IoC) 예제 튜토리얼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!