アダプターパターン
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 95/110。
Adapter パターンにより、incompatible interface を連携させることができます。これは、そうでなければ協調できない2つのクラスの間の橋渡しとして機能し、existing クラスを clients が期待する新しい interface でラップします。これは、サードパーティ製ライブラリや legacy コードをアプリケーションに統合する場合に特に役立ちます。
JSON データを扱うシステムがある一方で、XML のみを出力するコンポーネントを統合する必要があると想像してください。どちらの class も変更する代わりに、両者の間を変換する adapter を作成します。
// システムが期待する既存のインターフェース
abstract class JsonData {
String getJson();
}
// 互換性のないインターフェースを持つレガシークラス
class XmlService {
String getXml() {
return '<data><name>John</name></data>';
}
}
// アダプターにより XmlService を JsonData と互換にする
class XmlToJsonAdapter implements JsonData {
final XmlService _xmlService;
XmlToJsonAdapter(this._xmlService);
@override
String getJson() {
String xml = _xmlService.getXml();
// XML を JSON に変換する(簡略化)
return '{"name": "John"}';
}
}
void main() {
var xmlService = XmlService();
var adapter = XmlToJsonAdapter(xmlService);
print(adapter.getJson()); // {"name": "John"}
}XmlToJsonAdapter は XmlService をラップし、JsonData インターフェースを実装します。クライアントコードは、データがもともと XML ソースから取得されたものであることを知らなくても、使い慣れた JsonData インターフェースを使用できます。アダプターがすべての変換を内部で処理します。
既存のクラスを使用したいものの、そのインターフェースが必要なものと一致しない場合、または互換性のないインターフェースを持つクラスと連携する再利用可能なクラスを作成する必要がある場合は、Adapter パターンを使用します。
チャレンジ
簡単media player adapter system を構築しましょう!すべての media source が標準の interface を通じて audio を提供することを期待する最新の audio system がある一方で、まったく異なる方法で音を生成する旧式の vinyl record player を統合する必要がある状況を想像してください。
adapter pattern の実装を整理するために、2つのファイルを作成します。
media_adapter.dart: このファイルには interface と adapter クラスを含めます。最新の system が期待する abstract classAudioSourceを Define します。このクラスには、audio output を string として返す methodString playAudio()が必要です。次に、legacy equipment を表すVinylPlayerクラスを作成します。このクラスにはtrackNamefield と、*crackle* Playing vinyl: [trackName] *crackle*を返す methodString spinRecord()があります。最後に、AudioSourceを implements し、VinylPlayerをラップするVinylAdapterを作成します。adapter のplayAudio()method は vinyl player のspinRecord()method を呼び出して result を返し、incompatible な interface の橋渡しを行います。main.dart: media adapter file を import し、adapter によって、最新のAudioSourceinterface を期待する code で旧式の vinyl player を動作させる方法を示します。track name がBohemian RhapsodyのVinylPlayerを Create します。次に、この vinyl player をラップするVinylAdapterを作成します。adapter をAudioSource型の variable に格納し、期待される interface に準拠していることを確認します。audio source に対してplayAudio()を呼び出し、result を print します。
この pattern の魅力は、main code が標準の AudioSource interface を使って動作し、裏側で実際の処理を旧式の vinyl player が行っていることを知る必要がない点です。
期待される output:
*crackle* Playing vinyl: Bohemian Rhapsody *crackle*自分で試してみよう
import 'media_adapter.dart';
void main() {
// TODO: トラック名 "Bohemian Rhapsody" の VinylPlayer を作成する
// TODO: ビニールプレイヤーをラップする VinylAdapter を作成する
// TODO: アダプターを AudioSource 型の変数に格納する
// TODO: オーディオソースで playAudio() を呼び出し、結果を出力する
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ自分で練習してみよう: Dartオンラインコンパイラ