デザインパターンシリーズの記事
デザイン パターン (2、3): 創造的なファクトリー メソッドと抽象的なファクトリー パターン
デザインパターン (5): Creational Builder パターン
1. デザインパターンの分類
- 創作パターン
- 「オブジェクトの作成方法」を説明するために使用され、その主な特徴は「オブジェクトの作成と使用の分離」です。
- シングルトン、プロトタイプ、ファクトリ メソッド、抽象ファクトリ、ビルダーを提供します
5 种创建型模式
- 構造パターン
- クラスまたはオブジェクトを特定のレイアウトでより大きな構造に編成する方法を説明するために使用されます。
- プロキシ、アダプター、ブリッジ、デコレーター、ファサード、フライウェイト、コンポジションが提供されます
7 种结构型模式
- 行動モデル
- 単一のオブジェクトだけでは実行できないタスクをクラスまたはオブジェクトが互いに連携して完了する方法と、責任を割り当てる方法を説明するために使用されます。
- テンプレートメソッド、ポリシー、コマンド、責任連鎖、状態、オブザーバー、メディエーター、イテレーター、ビジター、メメント、インタープリターを提供します
11 种行为型模式
2.アダプターモード
1。概要
- 携帯電話の充電器(220v を 5v の電圧に変換)、カードリーダーなど、世の中にはそのような例がたくさんあります。
意味:
- クラスのインターフェースをクライアントが必要とする別のインターフェースに変換します。
- 互換性のないインターフェイスのために連携できないクラスを有効にします
- アダプターのパターンは
类适配器模式
とに分かれます。对象适配器模式
- 前者のクラス間の結合度は後者のクラス間の結合度よりも高い
- また、プログラマーは既存のコンポーネント ライブラリ内の関連コンポーネントの内部構造を理解する必要があります。
- なので応募数は比較的少ないです
2. 構造
アダプター パターン (アダプター) には、次の主な役割が含まれます。
- ターゲット インターフェイス: 現在のシステム ビジネスによって予期されるインターフェイス。抽象クラスまたはインターフェイスにすることができます。
- Adapte クラス: アクセスして適応される既存のコンポーネント ライブラリ内のコンポーネント インターフェイスです。
- アダプター クラス:コンバータ、アダプター オブジェクトを継承または参照することによってアダプター インターフェイスをターゲット インターフェイスに変換し、クライアントがターゲット インターフェイスの形式でアダプターにアクセスできるようにします。
3. クラスアダプタモード
実装方法:現行システムのビジネスインタフェースを実装するアダプタクラスを定義し、同時に既存コンポーネントライブラリ内の既存コンポーネントを継承
カード読み取り装置
- 既存のコンピューターはSDカードのみを読み取ることができます
- TF カードのコンテンツを読み取るには、アダプター モードを使用する必要があります。
- TF カードの内容を読み取るためのカード リーダーを作成します。
クラス図は次のとおりです。
コードは以下のように表示されます。
//SD卡的接口
public interface SDCard {
//读取SD卡方法
String readSD();
//写入SD卡功能
void writeSD(String msg);
}
//SD卡实现类
public class SDCardImpl implements SDCard {
public String readSD() {
String msg = "sd card read a msg :hello word SD";
return msg;
}
public void writeSD(String msg) {
System.out.println("sd card write msg : " + msg);
}
}
//电脑类
public class Computer {
public String readSD(SDCard sdCard) {
return sdCard.readSD();
}
}
//TF卡接口
public interface TFCard {
//读取TF卡方法
String readTF();
//写入TF卡功能
void writeTF(String msg);
}
//TF卡实现类
public class TFCardImpl implements TFCard {
public String readTF() {
String msg ="tf card read msg : hello word tf card";
return msg;
}
public void writeTF(String msg) {
System.out.println("tf card write a msg : " + msg);
}
}
//定义适配器类(SD兼容TF)
public class SDAdapterTF extends TFCardImpl implements SDCard {
public String readSD() {
System.out.println("adapter read tf card ");
return super.readTF();
}
public void writeSD(String msg) {
System.out.println("adapter write tf card");
super.writeTF(msg);
}
}
//测试类
public class Client {
public static void main(String[] args) {
Computer computer = new Computer();
SDCard sdCard = new SDCardImpl();
System.out.println(computer.readSD(sdCard));
System.out.println("------------");
SDAdapterTF adapter = new SDAdapterTF();
System.out.println(computer.readSD(adapter));
}
}
- クラス アダプター パターンは構成再利用の原則に違反しています
- クラス アダプタは、クライアント クラスにインターフェイス仕様がある場合に使用できます。それ以外の場合は使用できません。
4. オブジェクトアダプターパターン
実装方法:オブジェクトアダプタモードを使用して、既存のコンポーネントライブラリに実装されているコンポーネントをアダプタクラスに導入することができ、同時に現在のシステムのビジネスインターフェイスを実現します
コードは以下のように表示されます。
//创建适配器对象(SD兼容TF)
public class SDAdapterTF implements SDCard {
private TFCard tfCard;
public SDAdapterTF(TFCard tfCard) {
this.tfCard = tfCard;
}
public String readSD() {
System.out.println("adapter read tf card ");
return tfCard.readTF();
}
public void writeSD(String msg) {
System.out.println("adapter write tf card");
tfCard.writeTF(msg);
}
}
//测试类
public class Client {
public static void main(String[] args) {
Computer computer = new Computer();
SDCard sdCard = new SDCardImpl();
System.out.println(computer.readSD(sdCard));
System.out.println("------------");
TFCard tfCard = new TFCardImpl();
SDAdapterTF adapter = new SDAdapterTF(tfCard);
System.out.println(computer.readSD(adapter));
}
}
- というアダプターパターンもあります。
接口适配器模式
- インターフェイスにすべてのメソッドを実装したくない場合
- 抽象クラス アダプターを作成してすべてのメソッドを実装できます。
- 現時点では、抽象クラスを継承するだけで済みます。
5. JDKのソースコード解析
InputStream(バイトストリーム)をReader(文字ストリーム)に変換するInputStreamReader変換ストリームはアダプタモードを使用します。
- InputStreamReader は java.io パッケージの Reader を継承します
- read のオーバーロードされたメソッドは、read(char cbuf[], int off, int len) メソッドを直接または間接的に呼び出します。
- InputStreamReader は、次のように、実装されていない抽象メソッドの実装を提供します。
public class InputStreamReader extends Reader {
private final StreamDecoder sd;
public int read() throws IOException {
return sd.read();
}
public int read(char cbuf[], int offset, int length) throws IOException {
return sd.read(cbuf, offset, length);
}
...
}
- 上記のコードの sd (StreamDecoder クラス オブジェクト) は Sun の JDK で実装されています。
- 実際のメソッド実装は、sun.nio.cs.StreamDecoder クラスと同じ名前のメソッドの呼び出しのカプセル化です。
- クラス構造図は次のとおりです。
- InputStreamReader と StreamDecoder は両方とも Reader を継承します
- StreamDecoder は抽象メソッド read を実装します。
- 次に、InputStreamReader は、実際に StreamDecoder の実装を呼び出す抽象メソッド read も実装します。
- StreamDecoderは遷移クラスに相当します
- StreamDecoder クラスはInputStreamを集約し、readメソッドは実際にInputStreamのreadメソッドを呼び出します。
結論は:
- 表面的な観点から見ると、InputStreamReader は、InputStream バイト ストリーム クラスを Reader 文字ストリームに変換します。
- 上記の Sun JDK の実装クラス関係構造からわかるように、StreamDecoder の設計と実装では実際にはアダプター モードが使用されます。