技術共有

デザインパターン利用シナリオの実装例とメリット・デメリット(構造パターン~プロキシパターン、出現パターン)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

構造パターン

プロキシパターン

プロキシ パターンは、プロキシ オブジェクトを導入することで別のオブジェクトへのアクセスを制御する構造的な設計パターンです。このプロキシ オブジェクトは、アクセス制御、遅延初期化、ロギング、ネットワーク アクセスなどの追加機能をプロキシ オブジェクトに提供できます。

該当シーン

  1. リモートエージェント

    • さまざまなアドレス空間でオブジェクトのローカル表現を提供します。
  2. 仮想エージェント

    • 必要に応じて高価なオブジェクトを作成します。
  3. 保護剤

    • 元のオブジェクトへのアクセスを制御します。
  4. スマートな誘導

    • オブジェクトにアクセスするときに、カウント操作や参照検出などの追加操作を実行します。

実装例(Java)

以下は、プロキシ パターンの簡単な実装例で、プロキシ オブジェクトを通じて実際のオブジェクトへのアクセスを制御する方法を示しています。

1. テーマインターフェイスを定義する
public interface Subject {
    void request();
}
  • 1
  • 2
  • 3
  • 説明するSubject インターフェースは、request メソッド。これは、実際のオブジェクトとプロキシ オブジェクトの両方が実装する必要があるメソッドです。
2. 実サブジェクトクラス (RealSubject) を定義します。
public class RealSubject implements Subject {
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 説明するRealSubject 実装されたクラスSubject インターフェースrequest 実際にリクエストを処理するクラスを表すメソッド。
3. プロキシクラス(Proxy)を定義する
public class Proxy implements Subject {
    private RealSubject realSubject;

    public Proxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    public void request() {
        if (this.checkAccess()) {
            this.realSubject.request();
            this.logAccess();
        }
    }

    private boolean checkAccess() {
        // 检查访问权限
        System.out.println("Proxy: Checking access prior to firing a real request.");
        return true;
    }

    private void logAccess() {
        // 记录请求日志
        System.out.println("Proxy: Logging the time of request.");
    }
}
  • 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
  • 説明する
    • Proxy 実装されたクラスSubject インターフェースを持ち、RealSubject 物体。
    • 存在する request このメソッドでは、プロキシ クラスは最初にアクセス許可をチェックし、次に実際のオブジェクトのrequest メソッドを実行し、最後にリクエスト ログを記録します。
4. クライアントコード
public class Client {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        Proxy proxy = new Proxy(realSubject);
        
        proxy.request();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 説明する
    • Client クラスが作成されましたRealSubject そしてProxy オブジェクト、を通してProxy オブジェクト呼び出しrequest を制御する方法RealSubject アクセス。

アドバンテージ

  1. 分離

    • プロキシ モードは、呼び出し元と実際のオブジェクトの間の仲介者として機能し、システム コンポーネント間の結合を軽減し、オブジェクト間の分離を強化します。
  2. 安全性

    • 実際のオブジェクトへのアクセスはプロキシを通じて制御できるため、セキュリティ チェックや詳細な検証が可能になります。
  3. スケーラビリティ

    • プロキシモードでは、特定のオブジェクトコードを変更することなく、柔軟に機能を追加できます。
  4. 知的

    • 遅延初期化やアクセス ログなどの追加操作は、サービス オブジェクト インターフェイスを変更せずに実装できます。

欠点がある

  1. コードの複雑さ

    • エージェントの導入は、システムの複雑さの増加を意味し、場合によっては新しいクラスやインターフェイスが導入され、コードの理解とメンテナンスのコストが増加します。
  2. 反応時間

    • プロキシ モードでは、特に多くの処理ロジックがプロキシ操作に追加されている場合、システムの動作が遅くなる可能性があります。
  3. 設計の難易度

    • プロキシ パターンを適切に設計および実装するには、システムのパフォーマンスに悪影響が及ばないようにシステム全体の設計を慎重に検討する必要があります。

クラス図

Client
  |
  v
Subject <---- Proxy <---- RealSubject
  • 1
  • 2
  • 3
  • 4

要約する

プロキシ パターンは、オブジェクトへのアクセスを制御および管理する効率的な方法を提供します。プロキシを使用すると、ビジネス オブジェクトの責任を明確にしたまま、さまざまな機能を追加できます。このモードは、ビジネス オブジェクトに対するアクセス制御やその他の前処理操作が必要なシナリオに特に適しています。

ファサードパターン

ファサード パターンは、サブシステム内のインターフェイスのグループにアクセスするための統一インターフェイスを提供することで、複雑なサブシステムを使いやすくする構造設計パターンです。ファサード パターンは、このサブシステムを使いやすくする高レベルのインターフェイスを定義します。

該当シーン

  1. 複雑なシステムへのインターフェースを簡素化

    • 複雑なサブシステムにシンプルなインターフェイスを提供して、サブシステムとの外部対話の複雑さを軽減します。
  2. 階層

    • 多層システム構造では、出現パターンを使用して各層への入り口を定義し、層間の依存関係を簡素化できます。
  3. 分離されたシステム

    • 出現パターンを導入することにより、サブシステムとクライアントの間の結合が軽減されます。

実装例(Java)

以下は、ファサード パターンの簡単な実装例であり、ファサード クラスを通じてサブシステムの使用を簡素化する方法を示しています。

1. サブシステム クラスを定義する
public class SubsystemA {
    public void operationA() {
        System.out.println("SubsystemA: operationA");
    }
}

public class SubsystemB {
    public void operationB() {
        System.out.println("SubsystemB: operationB");
    }
}

public class SubsystemC {
    public void operationC() {
        System.out.println("SubsystemC: operationC");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
2. 外観クラスを定義する
public class Facade {
    private SubsystemA subsystemA;
    private SubsystemB subsystemB;
    private SubsystemC subsystemC;

    public Facade() {
        this.subsystemA = new SubsystemA();
        this.subsystemB = new SubsystemB();
        this.subsystemC = new SubsystemC();
    }

    public void operation1() {
        System.out.println("Facade: operation1");
        subsystemA.operationA();
        subsystemB.operationB();
    }

    public void operation2() {
        System.out.println("Facade: operation2");
        subsystemB.operationB();
        subsystemC.operationC();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
3. クライアントコード
public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.operation1();
        facade.operation2();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

ノート

  1. サブシステムクラス

    • SubsystemA, SubsystemB、 そして SubsystemC サブシステムの固有の実装クラスであり、クラスごとに独自の操作メソッドを持ちます。
  2. 外観クラス

    • Facade クラスはサブシステム オブジェクトを保持し、簡素化されたインターフェイスを提供しますoperation1 そしてoperation2 サブシステム関数を呼び出します。
  3. クライアントコード

    • Client 合格したクラスFacade 呼び出すクラスoperation1 そしてoperation2したがって、複雑なサブシステムの使用が簡素化されます。

アドバンテージ

  1. 簡素化されたインターフェース

    • 外観パターンはサブシステムにシンプルなインターフェイスを提供し、サブシステムとの対話の複雑さを軽減します。
  2. 疎結合

    • 出現パターンにより、サブシステムとクライアント間の結合が軽減され、システムの保守性と拡張性が向上します。
  3. より良いレイヤリング

    • 出現パターンは、明確な階層構造を確立するのに役立ち、各レベルへの入り口を定義します。

欠点がある

  1. 開閉原理に従わない

    • 新しいサブシステム関数を追加する場合、外観クラスの変更が必要になる場合がありますが、これはオープンクローズ原則 (拡張に対してオープン、変更に対してクローズ) に違反します。
  2. パフォーマンスの問題が発生する可能性がある

    • 場合によっては、ファサード パターンを使用すると、すべてのリクエストがファサード クラスを通過する必要があるため、システムのパフォーマンスが低下する可能性があります。

クラス図

Client
  |
  v
Facade ----> SubsystemA
          ----> SubsystemB
          ----> SubsystemC
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

要約する

Facade パターンは、簡素化されたインターフェイスを提供することで、複雑なサブシステムの操作を容易にします。これは、サブシステム インターフェイスを簡素化し、クライアントとサブシステム間の直接対話を減らし、システム階層を分離する必要があるシナリオに適しています。オープンクローズの原則に違反する可能性がありますが、ほとんどの場合、その利点が欠点をはるかに上回り、システム設計がより明確になり、保守が容易になります。