Menu
Coddy logo textTech

アダプターパターン

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"}
}

XmlToJsonAdapterXmlService をラップし、JsonData インターフェースを実装します。クライアントコードは、データがもともと XML ソースから取得されたものであることを知らなくても、使い慣れた JsonData インターフェースを使用できます。アダプターがすべての変換を内部で処理します。

既存のクラスを使用したいものの、そのインターフェースが必要なものと一致しない場合、または互換性のないインターフェースを持つクラスと連携する再利用可能なクラスを作成する必要がある場合は、Adapter パターンを使用します。

challenge icon

チャレンジ

簡単

media player adapter system を構築しましょう!すべての media source が標準の interface を通じて audio を提供することを期待する最新の audio system がある一方で、まったく異なる方法で音を生成する旧式の vinyl record player を統合する必要がある状況を想像してください。

adapter pattern の実装を整理するために、2つのファイルを作成します。

  • media_adapter.dart: このファイルには interface と adapter クラスを含めます。最新の system が期待する abstract class AudioSource を Define します。このクラスには、audio output を string として返す method String playAudio() が必要です。次に、legacy equipment を表す VinylPlayer クラスを作成します。このクラスには trackName field と、*crackle* Playing vinyl: [trackName] *crackle* を返す method String spinRecord() があります。最後に、AudioSource を implements し、VinylPlayer をラップする VinylAdapter を作成します。adapter の playAudio() method は vinyl player の spinRecord() method を呼び出して result を返し、incompatible な interface の橋渡しを行います。
  • main.dart: media adapter file を import し、adapter によって、最新の AudioSource interface を期待する code で旧式の vinyl player を動作させる方法を示します。track name が Bohemian RhapsodyVinylPlayer を 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() を呼び出し、結果を出力する
  
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Dartオンラインコンパイラ