今日も引き続き、23のデザインパターンのうちの7つ目、ブリッジング・パターンについて勉強しましょう。いわゆるブリッジング・パターンとは、抽象的な部分と実装の部分を分離し、それぞれが独立して変更できるようにすることです。ブリッジング・パターンは、継承関係を連想関係に変換し、変更をカプセル化し、デカップリングを完成させ、システム内のクラス数を減らし、コード量も減らします。
概念
ブリッジング・パターンは、抽象化と現実化を切り離し、両者が独立して変化できるようにするために使われます。このタイプのデザイン・パターンは、抽象化と現実化を分離する構造パターンで、両者の間に橋渡し構造を提供します。
システムが複数の視点から分類でき、それぞれの分類が変化する可能性がある場合、必要なことは、これらの複数の視点が独立して変化できるように分離し、それらの間の結合を減らすことであり、この分離プロセスにはブリッジングモデルが使用されます。
特徴
::
- 抽象化と実装が分離されているため、拡張性に優れています。
- 顧客に対する実現内容の透明性
- 抽象化レイヤーに集約関係が構築されているため、開発者は抽象化レイヤーに対応した設計やプログラミングを行う必要があり、システムの理解や設計の難易度が上がります。
クラス図の分析
コード
携帯電話ブランドのインターフェース
package.ppdxzz.bridge;
/**
* Description:携帯電話のブランド・インターフェース
*
*/
public interface Brand {
void open(); //
void call(); //
void close(); //
}
OPPOブランドの携帯電話
package.ppdxzz.bridge;
/**
* Description:OPPOブランド携帯電話
*
*/
public class Oppo implements Brand {
@Override
public void open() {
System.out.println("oppo携帯電話の電源が入っている」);
}
@Override
public void call() {
System.out.println("oppo携帯電話");
}
@Override
public void close() {
System.out.println("oppo携帯電話の電源は切ってある」);
}
}
Vivoブランドの携帯電話
package.ppdxzz.bridge;
/**
* Description:vivoブランド携帯電話
*
*/
public class Vivo implements Brand {
@Override
public void open() {
System.out.println("vivo携帯電話の電源が入っている」);
}
@Override
public void call() {
System.out.println("vivo携帯電話の電源が入っている」);
}
@Override
public void close() {
System.out.println("vivo携帯電話の電源が入っている」);
}
}
携帯電話抽象クラス
package.ppdxzz.bridge;
/**
* Description:携帯電話抽象クラス
*
*/
public abstract class Phone {
//携帯電話へのブランド注入
private Brand brand;
public Phone() {
}
public Phone(Brand brand) {
this.brand = brand;
}
protected void open() {
brand.open();
}
protected void call() {
brand.call();
}
protected void close() {
brand.close();
}
}
タッチスクリーン携帯電話
package.ppdxzz.bridge;
/**
* Description:タッチ式携帯電話
*
*/
public class TouchPhone extends Phone {
public TouchPhone(Brand brand) {
super(brand);
}
@Override
public void open() {
super.open();
System.out.println("タッチ携帯電話");
}
@Override
public void call() {
super.call();
System.out.println("タッチ携帯電話");
}
@Override
public void close() {
super.close();
System.out.println("タッチ携帯電話");
}
}
折りたたみ式携帯電話
package.ppdxzz.bridge;
/**
* Description:折りたたみ式携帯電話
*
*/
public class FoldedPhone extends Phone {
public FoldedPhone(Brand brand) {
super(brand);
}
@Override
public void open() {
super.open();
System.out.println("折りたたみ式携帯電話");
}
@Override
public void call() {
super.call();
System.out.println("折りたたみ式携帯電話");
}
@Override
public void close() {
super.close();
System.out.println("折りたたみ式携帯電話");
}
}
携帯電話
package.ppdxzz.bridge;
/**
* Description:ブリッジング・パターン
*
*/
public class Client {
public static void main(String[] args) {
System.out.println("(=====oppoブランド携帯電話=====)");
Phone phone1 = new TouchPhone(new Oppo());
phone1.open();
phone1.call();
phone1.close();
System.out.println("(=====vivoブランド携帯電話=====)");
Phone phone2 = new FoldedPhone(new Vivo());
phone2.open();
phone2.call();
phone2.close();
}
}
デモ:
JDBCにおけるブリッジパターンのソースコード解析
分析
まとめ:
- ブリッジング・パターンは抽象化と実装の分離を可能にし、システムの柔軟性を大幅に向上させます。
- ブリッジパターンは、多層継承スキームに取って代わるもので、サブクラスの数を減らし、システムの管理・保守コストを削減します。
- ブリッジング・パターンを導入することで、システムの理解や設計の難易度が上がります。 集約されたアソシエーション関係は抽象化されたレベルで構築されるため、開発者は抽象化のための設計やプログラミングを行う必要があります。
ブリッジング・モデルは、システムの独立に変化する2つの次元を正しく識別する必要があるため、その使用はやや限定的であることに加え、ブリッジング・モデルの説明は以上です。