目次
依存関係反転原則 (DIP)
これが意味するもの:
DIP なし
Python の例
TypeScript の例
ディップあり
DIP の利点:
制御の反転 (IoC)
Python の例: IoC なし
TypeScript の例: IoC なし
Python の例: IoC を使用した場合
TypeScript の例: IoC を使用した場合
IoC の利点:
依存性注入 (DI)
Python の例: DI フレームワーク (injector ライブラリを使用)
TypeScript の例: DI フレームワーク (tsyringe ライブラリを使用)
DI の利点:
ホームページ バックエンド開発 Python チュートリアル 依存関係の逆転、IoC、DI の詳細

依存関係の逆転、IoC、DI の詳細

Jan 20, 2025 pm 04:26 PM

Breaking Down Dependency Inversion, IoC, and DI

NestJS の依存関係注入システムを調べることで、依存関係の反転、制御の反転、および依存関係の注入についてさらに深く知ることができました。 これらの概念は似ているように見えますが、さまざまな問題に対して明確な解決策を提供します。 この説明は個人的な復習として機能し、これらの用語に取り組む他の人にとって役立つガイドになることを願っています。


  1. 依存関係反転原則 (DIP)

定義: 高レベルのモジュールは低レベルのモジュールに依存すべきではありません。どちらも抽象化に依存する必要があります。抽象化は詳細に依存すべきではありません。詳細は抽象化に依存する必要があります。

これが意味するもの:

ソフトウェアでは、高レベルのモジュールがコア ビジネス ロジックをカプセル化し、低レベルのモジュールが特定の実装 (データベース、API など) を処理します。 DIP がないと、高レベルのモジュールが低レベルのモジュールに直接依存するため、柔軟性が妨げられ、テストとメンテナンスが複雑になり、低レベルの詳細の置き換えや拡張が困難になる密結合が生じます。

DIP はこの関係を逆転させます。直接制御する代わりに、高レベルと低レベルのモジュールは両方とも共有抽象化 (インターフェイスまたは抽象クラス) に依存します。


DIP なし

Python の例

class EmailService:
    def send_email(self, message):
        print(f"Sending email: {message}")

class Notification:
    def __init__(self):
        self.email_service = EmailService()

    def notify(self, message):
        self.email_service.send_email(message)
ログイン後にコピー
ログイン後にコピー

TypeScript の例

class EmailService {
    sendEmail(message: string): void {
        console.log(`Sending email: ${message}`);
    }
}

class Notification {
    private emailService: EmailService;

    constructor() {
        this.emailService = new EmailService();
    }

    notify(message: string): void {
        this.emailService.sendEmail(message);
    }
}
ログイン後にコピー
ログイン後にコピー

問題:

  1. 密結合: NotificationEmailService に直接依存します。
  2. 拡張性の制限: SMSService に切り替えるには、Notification を変更する必要があります。

ディップあり

Python の例

from abc import ABC, abstractmethod

class MessageService(ABC):
    @abstractmethod
    def send_message(self, message):
        pass

class EmailService(MessageService):
    def send_message(self, message):
        print(f"Sending email: {message}")

class Notification:
    def __init__(self, message_service: MessageService):
        self.message_service = message_service

    def notify(self, message):
        self.message_service.send_message(message)

# Usage
email_service = EmailService()
notification = Notification(email_service)
notification.notify("Hello, Dependency Inversion!")
ログイン後にコピー
ログイン後にコピー

TypeScript の例

interface MessageService {
    sendMessage(message: string): void;
}

class EmailService implements MessageService {
    sendMessage(message: string): void {
        console.log(`Sending email: ${message}`);
    }
}

class Notification {
    private messageService: MessageService;

    constructor(messageService: MessageService) {
        this.messageService = messageService;
    }

    notify(message: string): void {
        this.messageService.sendMessage(message);
    }
}

// Usage
const emailService = new EmailService();
const notification = new Notification(emailService);
notification.notify("Hello, Dependency Inversion!");
ログイン後にコピー
ログイン後にコピー

DIP の利点:

  • 柔軟性: 実装を簡単に交換できます。
  • テスト容易性: テストにはモックを使用します。
  • 保守性: 低レベルのモジュールの変更は高レベルのモジュールに影響を与えません。

  1. 制御の反転 (IoC)

IoC は、依存関係の制御をクラス内で管理するのではなく、外部システム (フレームワーク) に移す設計原則です。 従来、クラスはその依存関係を作成および管理します。 IoC はこれを逆に、外部エンティティが依存関係を注入します。


Python の例: IoC なし

class SMSService:
    def send_message(self, message):
        print(f"Sending SMS: {message}")

class Notification:
    def __init__(self):
        self.sms_service = SMSService()  # Dependency created internally

    def notify(self, message):
        self.sms_service.send_message(message)
ログイン後にコピー

TypeScript の例: IoC なし

class SMSService {
    sendMessage(message: string): void {
        console.log(`Sending SMS: ${message}`);
    }
}

class Notification {
    private smsService: SMSService;

    constructor() {
        this.smsService = new SMSService(); // Dependency created internally
    }

    notify(message: string): void {
        this.smsService.sendMessage(message);
    }
}
ログイン後にコピー

IoC がない場合の問題:

  1. 密結合。
  2. 柔軟性が低い。
  3. テストは困難です。

Python の例: IoC を使用した場合

class EmailService:
    def send_email(self, message):
        print(f"Sending email: {message}")

class Notification:
    def __init__(self):
        self.email_service = EmailService()

    def notify(self, message):
        self.email_service.send_email(message)
ログイン後にコピー
ログイン後にコピー

TypeScript の例: IoC を使用した場合

class EmailService {
    sendEmail(message: string): void {
        console.log(`Sending email: ${message}`);
    }
}

class Notification {
    private emailService: EmailService;

    constructor() {
        this.emailService = new EmailService();
    }

    notify(message: string): void {
        this.emailService.sendEmail(message);
    }
}
ログイン後にコピー
ログイン後にコピー

IoC の利点:

  1. 疎結合。
  2. 実装の切り替えが簡単。
  3. テスト容易性の向上

  1. 依存性注入 (DI)

DI は、オブジェクトが外部ソースから依存関係を受け取る手法です。 これは IoC の実用的な実装であり、次の方法で依存関係を注入します。

  1. コンストラクターのインジェクション
  2. セッターインジェクション
  3. インターフェースインジェクション

Python の例: DI フレームワーク (injector ライブラリを使用)

from abc import ABC, abstractmethod

class MessageService(ABC):
    @abstractmethod
    def send_message(self, message):
        pass

class EmailService(MessageService):
    def send_message(self, message):
        print(f"Sending email: {message}")

class Notification:
    def __init__(self, message_service: MessageService):
        self.message_service = message_service

    def notify(self, message):
        self.message_service.send_message(message)

# Usage
email_service = EmailService()
notification = Notification(email_service)
notification.notify("Hello, Dependency Inversion!")
ログイン後にコピー
ログイン後にコピー

TypeScript の例: DI フレームワーク (tsyringe ライブラリを使用)

interface MessageService {
    sendMessage(message: string): void;
}

class EmailService implements MessageService {
    sendMessage(message: string): void {
        console.log(`Sending email: ${message}`);
    }
}

class Notification {
    private messageService: MessageService;

    constructor(messageService: MessageService) {
        this.messageService = messageService;
    }

    notify(message: string): void {
        this.messageService.sendMessage(message);
    }
}

// Usage
const emailService = new EmailService();
const notification = new Notification(emailService);
notification.notify("Hello, Dependency Inversion!");
ログイン後にコピー
ログイン後にコピー

DI の利点:

  • 簡略化されたテスト。
  • スケーラビリティの向上
  • 保守性の向上

この詳細な説明では、DIP、IoC、DI の関係と区別を明確にし、堅牢で保守可能なソフトウェアの構築に対するそれぞれの貢献を強調します。

以上が依存関係の逆転、IoC、DI の詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は? LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は? Apr 01, 2025 pm 05:09 PM

LinuxターミナルでPythonバージョンを表示する際の許可の問題の解決策PythonターミナルでPythonバージョンを表示しようとするとき、Pythonを入力してください...

中間の読書にどこでもfiddlerを使用するときにブラウザによって検出されないようにするにはどうすればよいですか? 中間の読書にどこでもfiddlerを使用するときにブラウザによって検出されないようにするにはどうすればよいですか? Apr 02, 2025 am 07:15 AM

fiddlereveryversings for the-middleの測定値を使用するときに検出されないようにする方法

あるデータフレームの列全体を、Python内の異なる構造を持つ別のデータフレームに効率的にコピーする方法は? あるデータフレームの列全体を、Python内の異なる構造を持つ別のデータフレームに効率的にコピーする方法は? Apr 01, 2025 pm 11:15 PM

PythonのPandasライブラリを使用する場合、異なる構造を持つ2つのデータフレーム間で列全体をコピーする方法は一般的な問題です。 2つのデータがあるとします...

プロジェクトの基本と問題駆動型の方法で10時間以内にコンピューター初心者プログラミングの基本を教える方法は? プロジェクトの基本と問題駆動型の方法で10時間以内にコンピューター初心者プログラミングの基本を教える方法は? Apr 02, 2025 am 07:18 AM

10時間以内にコンピューター初心者プログラミングの基本を教える方法は?コンピューター初心者にプログラミングの知識を教えるのに10時間しかない場合、何を教えることを選びますか...

uvicornは、serving_forever()なしでhttpリクエストをどのように継続的に聞いていますか? uvicornは、serving_forever()なしでhttpリクエストをどのように継続的に聞いていますか? Apr 01, 2025 pm 10:51 PM

UvicornはどのようにしてHTTPリクエストを継続的に聞きますか? Uvicornは、ASGIに基づく軽量のWebサーバーです。そのコア機能の1つは、HTTPリクエストを聞いて続行することです...

Investing.comの反クローラーメカニズムをバイパスするニュースデータを取得する方法は? Investing.comの反クローラーメカニズムをバイパスするニュースデータを取得する方法は? Apr 02, 2025 am 07:03 AM

Investing.comの反クラウリング戦略を理解する多くの人々は、Investing.com(https://cn.investing.com/news/latest-news)からのニュースデータをクロールしようとします。

See all articles