ホームページ > バックエンド開発 > PHPチュートリアル > PHP における依存関係の挿入とは何ですか、またそれがテストと保守性にとって重要である理由

PHP における依存関係の挿入とは何ですか、またそれがテストと保守性にとって重要である理由

Barbara Streisand
リリース: 2024-12-29 07:35:15
オリジナル
1013 人が閲覧しました

What is Dependency Injection in PHP and Why It

PHP における依存関係の挿入とは何ですか?また、それがテストとコードの保守性にとって重要である理由

Dependency Injection (DI) は、コードの柔軟性、テスト容易性、保守容易性を向上させるためにソフトウェア開発で使用される設計パターンです。 PHP などのオブジェクト指向プログラミング (OOP) で特に人気があります。 DI を使用すると、クラスは依存関係 (つまり、機能するために必要なオブジェクト) を内部で作成するのではなく、外部ソースから受け取ることができます。これにより、クラスがその依存関係から切り離され、よりモジュール化され、保守しやすく、テストしやすいコードベースが促進されます。

この記事では、依存関係注入とは何か、PHP で依存関係注入がどのように機能するか、保守可能でテスト可能なコードを作成するために依存関係注入が重要である理由について説明します。


1.依存関係の注入とは何ですか?

Dependency Injection は、クラスが必要とするオブジェクトやサービス (その依存関係) を、クラス自体が作成するのではなく、クラスの外部から渡すプロセスを指します。これらの依存関係は、クラスが操作を実行するために必要なデータベース接続、サービス、外部ライブラリなどのオブジェクトである可能性があります。

従来のオブジェクト指向プログラミングでは、クラスは依存するオブジェクトを直接インスタンス化することがあり、そのためクラスは依存関係と密接に結合されます。これにより、コードの変更、テスト、拡張が困難になる可能性があります。

Dependency Injection を使用すると、依存関係の作成と管理の責任がクラスの外に移されます。これにより、テスト時にモックの依存関係を注入できるため、コードがより柔軟になり、テストが容易になります。

依存関係の注入の例

DatabaseConnection クラスに依存する DatabaseService クラスの次の簡単な例を考えてみましょう。

依存関係の注入なし (密結合):

class DatabaseService {
    private $dbConnection;

    public function __construct() {
        $this->dbConnection = new DatabaseConnection(); // Creates its own dependency
    }

    public function fetchData() {
        // Uses the database connection to fetch data
        return $this->dbConnection->query('SELECT * FROM users');
    }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この例では、DatabaseService クラスが独自の DatabaseConnection インスタンスを作成します。これにより、DatabaseConnection を別のクラスに置き換えたり、テスト目的でモックしたりすることが困難になります。

依存性注入を使用する場合 (疎結合):

class DatabaseService {
    private $dbConnection;

    // Dependency is injected through the constructor
    public function __construct(DatabaseConnection $dbConnection) {
        $this->dbConnection = $dbConnection; // Dependency is passed in
    }

    public function fetchData() {
        // Uses the injected database connection to fetch data
        return $this->dbConnection->query('SELECT * FROM users');
    }
}
ログイン後にコピー
ログイン後にコピー

この改良された例では、DatabaseService クラスは DatabaseConnection インスタンスを作成しません。代わりに、DatabaseConnection オブジェクトが外部から渡されます (コンストラクターに挿入されます)。これにより、クラスがより柔軟になり、DatabaseConnection の特定の実装から切り離されます。これで、DatabaseConnection をモック オブジェクトまたは別のデータベース実装に簡単に置き換えることができます。


2. PHP における依存性注入の種類

依存関係の注入を実装するには、主に 3 つの方法があります。

  1. コンストラクターインジェクション: 依存関係はコンストラクターを通じてクラスに渡されます。これは、依存関係注入の最も一般的で推奨される方法です。
class DatabaseService {
    private $dbConnection;

    public function __construct() {
        $this->dbConnection = new DatabaseConnection(); // Creates its own dependency
    }

    public function fetchData() {
        // Uses the database connection to fetch data
        return $this->dbConnection->query('SELECT * FROM users');
    }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. Setter Injection: 依存関係は setter メソッドを介して渡されます。このメソッドは、オブジェクトの作成後に依存関係を挿入する場合に便利ですが、オブジェクトが完全に初期化されない可能性があります。
class DatabaseService {
    private $dbConnection;

    // Dependency is injected through the constructor
    public function __construct(DatabaseConnection $dbConnection) {
        $this->dbConnection = $dbConnection; // Dependency is passed in
    }

    public function fetchData() {
        // Uses the injected database connection to fetch data
        return $this->dbConnection->query('SELECT * FROM users');
    }
}
ログイン後にコピー
ログイン後にコピー
  1. インターフェイス注入: このクラスは、依存関係を注入するためのメソッドを定義するインターフェイスを実装します。このメソッドはあまり一般的には使用されませんが、オブジェクトが特定のインターフェイスを実装していることを確認したい特定の状況では便利です。
   class SomeClass {
       private $service;

       public function __construct(Service $service) {
           $this->service = $service;
       }
   }
ログイン後にコピー

3.依存関係の注入の利点

a.疎結合

DI は、クラス内に依存関係を作成するのではなく、依存関係を注入することにより、クラスを特定の実装から切り離します。これにより、依存関係に依存するクラスに影響を与えることなく、依存関係を交換または変更することが容易になります。この疎結合により、システムはよりモジュール化され、柔軟性が高まります。

b.テスト容易性の向上

依存関係の注入を使用すると、実際の依存関係をモックまたはスタブ オブジェクトに置き換えることができるため、テストが大幅に簡単になります。これは、テスト対象のクラスの動作を分離する単体テストに特に役立ちます。

たとえば、DatabaseService クラスをテストする場合は、データベースの動作をシミュレートするモック データベース接続を挿入でき、テスト中に実際のデータベース接続が必要なくなります。

   class SomeClass {
       private $service;

       public function setService(Service $service) {
           $this->service = $service;
       }
   }
ログイン後にコピー

c.メンテナンスとリファクタリングが簡単になりました

アプリケーションが成長するにつれて、リファクタリングが必要になります。 DI を使用すると、クラスの依存関係が明確かつ外部になるため、リファクタリングがはるかに簡単になります。依存クラスを変更せずに依存関係を更新または置換できるため、機能を損なうことなくシステムを簡単に拡張できます。

d.柔軟性と再利用性

クラスは特定の依存関係に厳密にバインドされていないため、さまざまなコンテキストで再利用できます。たとえば、DatabaseService クラスは、異なるデータベース接続オブジェクトを挿入するだけで、異なるデータベース接続 (MySQL、PostgreSQL、SQLite など) で使用できます。

え。依存関係の管理

大規模なコードベースを扱う場合、依存関係を手動で管理することが困難になる可能性があります。 PHP-DISymfony dependencyInjection などの DI フレームワークは、依存関係の挿入の自動化に役立ち、手動でインスタンス化して渡すことなく、依存関係の管理と相互接続が容易になります。


4.依存性注入コンテナ

依存関係注入コンテナ (または DI コンテナ) は、依存関係の作成と注入を自動的に管理する強力なツールです。コンテナはオブジェクトとその関係を管理し、必要に応じてオブジェクトをインスタンス化し、依存関係を注入し、オブジェクトのライフサイクルを管理するために使用できます。

一般的な PHP DI コンテナは Symfony の依存関係注入コンテナ です。以下はその仕組みの例です:

class DatabaseService {
    private $dbConnection;

    public function __construct() {
        $this->dbConnection = new DatabaseConnection(); // Creates its own dependency
    }

    public function fetchData() {
        // Uses the database connection to fetch data
        return $this->dbConnection->query('SELECT * FROM users');
    }
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この例では、DI コンテナーが DatabaseService の作成を管理し、そこに db_connection サービスを自動的に挿入します。


5.依存関係の挿入がテストとコードの保守性にとって重要なのはなぜですか?

a.単体テストを簡素化します

Dependency Injection を使用すると、テスト中に疑似依存関係を注入できるため、単体テストが容易になります。 DI がなければ、特に依存関係が外部操作 (データベース クエリ、ファイル I/O など) を実行する場合、テストしたいクラスを依存関係から分離するのは困難です。

b.コードの重複を削減

DI は依存関係の作成と管理を一元化することで、コードの重複を減らします。各メソッドまたはコンストラクターでクラスの新しいインスタンスを作成する代わりに、それらを一度作成して、必要な場所に注入します。

c.コードの可読性を向上させます

明確な外部依存関係 (DI 経由) を持つクラスは理解しやすいです。依存関係が注入されたクラスは、何が必要かを明示するため、コードがより読みやすく、自己文書化されます。

d.堅実な原則を推進します

Dependency Injection は、いくつかの SOLID 原則、特に 単一責任原則 (SRP)依存関係反転原則 (DIP) とよく調和しています。依存関係を挿入すると、依存関係を管理するクラスの責任が軽減され、コードの理解と保守が容易になります。


6.結論

依存関係の挿入は、コードの保守性、テスト容易性、柔軟性の向上に役立つ PHP の重要な設計パターンです。 DI では、クラスをその依存関係から切り離すことで、(モックの依存関係を挿入することにより) テストが容易になり、(依存関係を別の実装に置き換えることにより) モジュール性が向上します。

最新の PHP アプリケーションでは、テストやリファクタリングが簡単で、クリーンで保守可能なコードを作成するために DI を使用することが重要です。 DI を手動で実装する場合でも、DI コンテナを使用する場合でも、このパターンを採用すると、PHP プロジェクトの品質と寿命が大幅に向上します。


以上がPHP における依存関係の挿入とは何ですか、またそれがテストと保守性にとって重要である理由の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート