1.ブリッジモード
Bridge パターンは、抽象化を実装から切り離す構造設計パターンです。インターフェイスをブリッジとして使用して、抽象クラスのコードをその実装クラスから分離し、それらが独立して変更できるようにします。ブリッジ パターンの核となる考え方は、「継承よりも合成の方が優れている」ということです。
簡単に言うと、クラスの機能は 2 つの次元によって制御され、両方の次元には異なる実装があり、それらを自由に組み合わせることができます。
抽象部と実装部を独立して変化させるという目的を達成するために、抽象部は実装部のインターフェースオブジェクトを持ち、実装部のインターフェースオブジェクトを持った後、具体的な実装部の機能を実現することができます。このインターフェイスを通じて呼び出されます。ブリッジングは、実装部分を所有する抽象部分を持つインターフェイス オブジェクトとしてプログラムに組み込まれ、ブリッジ関係を実現します。ブリッジモードにおけるブリッジは一方向の関係であり、実装部のオブジェクトは抽象部のみが利用可能である。
抽象化の役割 抽象化: 抽象化によって与えられる定義。実現されたオブジェクトへの参照を保持します。
抽象化ロールの改訂 洗練された抽象化: 抽象化ロールを拡張し、親クラスによる抽象化の定義を変更および修正します。
実現されたロールの実装者: 実現されたロールのインターフェイスを提供しますが、特定の実装は提供しません。このインターフェイスは、抽象ロールのインターフェイス定義と必ずしも同じである必要はなく、実際、2 つのインターフェイスは大きく異なる場合があることに注意してください。実現されたロールは基礎となる操作のみを提供する必要がありますが、抽象ロールは基礎となる操作に基づいた高レベルの操作のみを提供する必要があります。
ConcreteImplementor: ConcreteImplementor: 実現されたロールのインターフェイスの具体的な実装。
要約部分:
パブリック抽象クラスの抽象化 {
private Implementorimplementor; //抽象部分は実装部分のインターフェースオブジェクトを持ち、インターフェースはブリッジとして機能し、抽象実装クラスの機能をインターフェース実装クラスから独立させます。
public Abstraction(実装者 インプリメンタ
this.implementor = 実装者;
}
public void 操作() {
実装者.operationImpl();
}
}
public class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(実装者 インプリメンタ) {
スーパー(実装者);
}
public void generatedOperation() {
//演算メソッドを抽象化で拡張する
}
}
実装部分:
パブリック インターフェイスの実装者 {
void 操作Impl();
}
public class ConcreteImplementorA は Implementor{ を実装します
@オーバーライド
public void OperationImpl() {
//実装
}
}
public class ConcreteImplementorB は Implementor{ を実装します
@オーバーライド
public void OperationImpl() {
//実装
}
}
この構造を見ると、抽象クラス Abstraction が RefinedAbstraction と Implementor をつなぐ橋のようなものであることがはっきりとわかります。
2. ブリッジモードの利用シーン
① システムが構築された抽象的な役割と具体的な役割の間に柔軟性を追加する必要があり、2 つのレベル間に静的な継承関係を確立することを回避する必要がある場合、ブリッジ モードを通じて抽象層で関連付け関係を確立できます。
②抽象ロールと実現ロールは、相互に影響を与えずに独立して継承拡張することができ、プログラム実行時に、抽象サブクラスのオブジェクトと実現サブクラスのオブジェクトを動的に組み合わせることができます。実現の役割と実現の役割を動的に結合します。
③ クラスには独立して変化する 2 つの次元があり、両方の次元を拡張する必要があります。
④ システム内で継承を利用することは問題ありませんが、抽象的な役割と具体的な役割は独立して変化する必要があるため、設計要件は両者を独立して管理する必要があります。
⑤ブリッジモードは、継承を使用したくないシステムや、多層継承によりシステムクラス数が急増するシステムに特に適しています。
3. ブリッジモードのメリットとデメリット
1) 利点:
①抽象部と実装部の分離
ブリッジモードは抽象部分と実装部分を分離するため、システムの柔軟性が大幅に向上し、抽象部分と実装部分を独立させ、インターフェイスを個別に定義することで、システムの階層設計の実行が容易になり、より適切に構造化されたシステムが得られます。 。システムの高レベル部分については、抽象部分と実装部分の間のインターフェイスを理解するだけで済みます。
② 拡張性の向上
ブリッジモードでは、抽象部と実装部のインターフェースをそれぞれ定義するため、抽象部と実装部を相互に影響を与えることなく独立して拡張することができ、システムの拡張性が大幅に向上します。
③ダイナミックなスイッチングが実現可能
ブリッジモードは抽象化と実装の分離を実現しているため、ブリッジモード実装時に特定の実装を動的に選択して利用することが可能です。
④実装内容はクライアントに対して透過的であり、実装内容はユーザーからは隠すことができます。
2) 短所:
①ブリッジモードの導入によりシステムの理解・設計の難易度が高まり、抽象層で集約関係が構築されるため、開発者は抽象化に向けた設計・プログラミングが必要となります。
②ブリッジモードでは、システム内で独立して変化する 2 つの次元を正確に識別する必要があるため、その使用範囲には一定の制限があります。
4. ブリッジモードの例
ブリッジ パターンをより深く理解するために、簡単な例を見てみましょう。 color プロパティを持つシェイプ クラスがあるとします。この時点で、継承を使用してさまざまな色の形状クラスを実装すると、多くのサブクラスを作成する必要があり、コード構造が複雑になり、保守が困難になります。ブリッジ モードを使用すると、形状と色を別々に抽象化し、独立したものにすることができます。
パブリック インターフェイス カラー {
文字列 getColor();
}
パブリック クラス Red は Color { を実装します。
@オーバーライド
public String getColor() {
「赤」を返します。
}
}
public class Blue は Color { を実装します。
@オーバーライド
public String getColor() {
「青」を返します。
}
}
パブリック抽象クラス Shape {
保護された色 color;
public Shape(カラー color) {
this.color = 色;
}
パブリック抽象 void 描画();
}
パブリック クラス Rectangle extends Shape {
public Rectangle(カラー color) {
スーパー(カラー);
}
@オーバーライド
public voiddraw() {
System.out.println("" + color.getColor() + "の長方形を描画します");
}
}
パブリック クラス Circle extends Shape {
公開サークル(カラーカラー) {
スーパー(カラー);
}
@オーバーライド
public voiddraw() {
System.out.println("「 + color.getColor() + " の円を描く」);
}
}
上記のコードでは、最初にカラー インターフェイスが定義され、赤と青がそれぞれ実装されます。次に、color 属性と抽象メソッドdraw()を持つ抽象形状クラスが定義されます。最後に、具体的な四角形と円のクラスが実装され、カラー オブジェクトがコンストラクターに渡されます。
このようにして、形状と色が別々に抽象化され、分離が実現されます。異なる色のシェイプを作成する必要がある場合は、異なる色のオブジェクトを作成して渡すだけです。
5. Android ソースコードでの使用
ブリッジ モードは、Window と WindowManager の間で使用されます。
このうち、Window と PhoneWindow はウィンドウの抽象部分を構成し、Window は抽象部分のインターフェース、PhoneWindow は抽象部分の具体的な実装と拡張、WindowManager は実装部分の基本クラス、WindowManagerImpl は特定のロジック実装の実装部分。IWindowManager インターフェイスを介して WindowMangerGlobal を使用します。IWindowManager インターフェイスは WMS と通信し、最終的に WMS は特定のウィンドウの管理を完了します。典型的なブリッジング関連モードです。