>백엔드 개발 >PHP 문제 >이해하기 쉬운 PHP 종속성 주입 컨테이너

이해하기 쉬운 PHP 종속성 주입 컨테이너

silencement
silencement앞으로
2020-01-19 17:54:333647검색

이해하기 쉬운 PHP 종속성 주입 컨테이너

종속성 주입 컨테이너 이해

커플링

좋은 코드 구조 디자인은 느슨하게 결합되어야 합니다. 이는 많은 공통 디자인 패턴의 목적이기도 합니다. 이는 어디에나 흩어져 있는 동일한 기능을 가진 코드를 하나로 모으는 것입니다. , 작고 명확한 채널을 통해 서로 다른 모듈 간에 통신합니다.

실제로는 서로 다른 기능과 모듈 간의 상호의존성은 불가피하며, 이러한 종속성 간의 관계를 어떻게 처리하느냐가 코드 구조가 아름다워질 수 있는지 여부의 핵심입니다.

<?php
class User
{
    public function register($user)
    {
        // 注册操作
        ...
 
        // 发送确认邮件
        $notify = new Notify();
        $notify->sendEmail(&#39;register&#39;, $user);
    }
}
 
class Notify
{
    public function sendEmail($type, $data)
    {
        switch $type {
            case &#39;register&#39;:
                // 发送注册确认邮件
                $email = new Email($type);
                $email->send($data);
            ...
        }
    }
}
 
class Email
{
    public function send($data)
    {
        // 发送邮件
    }
}

위 코드에서는 세 클래스 사이에 계층별 종속성이 있습니다. 즉, 세 클래스의 인스턴스화 순서는 User -> Notify -> Email

즉, User를 인스턴스화합니다. 먼저 클래스를 생성하고 일부 코드를 실행할 수 있습니다. 그런 다음 알림 등 필요한 다른 클래스를 인스턴스화합니다.

이런 종류의 종속성으로 인해 필요한 종속성을 얻기 위해 몇 가지 준비 작업을 수행해야 하는 경우가 있습니다. 때로는 새로운 작업만으로는 충분하지 않을 수 있습니다. 이 작업 부분을 결합이라고 하며, 이는 독립적인 기능을 가진 클래스가 주요 기능과 관련이 없는 일부 작업을 처리하도록 강제합니다.

다른 클래스에 대한 한 클래스의 종속성 제거

이 문제를 해결하는 것도 매우 간단합니다. 먼저 Email 클래스를 인스턴스화한 다음 Notify를 인스턴스화하고 Email 개체를 Notify에 매개 변수로 전달하고 마지막으로 User class 를 입력한 다음 Notify를 전달합니다. 이것이 소위 종속성 주입입니다. 이 프로세스에서 클래스 인스턴스화 순서가 완전히 반대임을 알 수 있습니다. 이는 최종 필수 개체가 먼저 인스턴스화되는 것이 아니라 종속 개체가 먼저 인스턴스화되는 것입니다.

코드는 다음과 같습니다.

<?php
$email = new Email();
$notify = new Notify($email);
$user = new User($notify);

생성자를 통해 필요한 종속성을 주입하거나 다른 방법을 사용할 수 있습니다.

컨테이너를 사용하여 종속성 호스트

그러면 새로운 문제가 있습니다. 예제에는 세 개의 클래스만 있는데, 이는 괜찮습니다. 그러면 User 클래스가 이메일을 보내기 위해 Notify를 사용하는 경우 Model을 사용하여 데이터베이스를 저장합니다. , 캐싱을 위해 Redis에 의존합니다. 물론 종속성은 클래스 외부로 전송되지만 User를 인스턴스화하려고 할 때 여전히 많은 수동 준비 작업을 수행해야 하므로 코드가 혼란스러워집니다. 그래서 이때 컨테이너가 필요합니다. 이 컨테이너의 역할은 이러한 종속성을 관리하는 것입니다.

<?php
// 容器
class Container implements ArrayAccess
{
    protected $values = [];
 
    public function offsetGet($offset) 
    {
        return $this->values[$offset]($this);
    }
 
    public function offsetSet($offset, $value) 
    {
        $this->values[$offset] = $value;
    }
}

프로그램이 시작되면 일련의 기본 서비스를 한곳에서 등록할 수 있습니다.

<?php
$container = new Container();
 
$container[&#39;notify&#39;] = function($c) {
    return new Notify();
};
 
$container[&#39;email&#39;] = function($c) {
    return new Email();
};

이렇게 됩니다

<?php
class User
{
    public function register($user)
    {
        // 注册操作
        ...
 
        // 发送确认邮件
        $container(&#39;notify&#39;)->sendEmail(&#39;register&#39;, $user);
    }
}
 
class Notify
{
    public function sendEmail($type, $data)
    {
        switch $type {
            case &#39;register&#39;:
                // 发送注册确认邮件
                $email = $container[&#39;email&#39;];
                $email->send($data);
            ...
        }
    }
}
 
class Email
{
    public function send($data)
    {
        // 发送邮件
    }
}

즉, 사용자가 Notify가 필요할 때 Notify가 의존하는 다른 항목에 대해서는 걱정할 필요가 없습니다. Notify도 컨테이너로 이동하기 때문에 필요한 종속성이 필요합니다. 이러한 모든 종속성의 처리는 컨테이너에 의해 완전히 관리됩니다. 종속성 간의 계층적 관계를 신경 쓸 필요도 없고 종속성 간의 결합도 피할 필요가 없습니다.

종속성 주입 컨테이너는 일반적으로 인스턴스화된 개체가 아닌 익명 함수만 허용한다는 점에 유의해야 합니다. 익명 함수는 컨테이너에 개체를 얻는 방법을 알려주므로 서비스는 필요할 때만 사용할 수 있습니다.

위 내용은 이해하기 쉬운 PHP 종속성 주입 컨테이너의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 www.liqingbo.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제