nikkie-ftnextの日記

イベントレポートや読書メモを発信

読書ログ | #ちょうぜつ本 第8章 Adapterパターン 〜身の回りにあるアダプタと同じ。2つのインターフェースが合わないときに変換する!〜

はじめに

変更しやすいコードが書けないのにソフトウェア開発とか舐めているのですか

天使様、ごめんなさい〜、nikkieです1

「かわいい」と技術書が夢の合体を果たした、ちょうぜつ本(『ちょうぜつソフトウェア設計入門』2)!🤗
昨年から読書会を共同主催しており、現在は第8章「デザインパターン」を読み進めています。
読んだ範囲から、Adapterを取り上げます。

目次

前回のちょうぜつ本!

前から順に読み進めて第8章に突入し、読書会では範囲を細かくしてじっくりと読み進めています。

Decoratorで(委譲した上で)新たなメソッドを追加し、使いやすくするのを見ました。

Adapterパターン

※辞書を引いたところ、adaptorという綴りでもよいそうです(ウィズダム英和辞典)

呼び出し元と呼び出し先のオブジェクトの間に割って入り、呼び出し先オブジェクトをラップ(包み)ます。
その目的は、インターフェースの変換

ProxyやDecoratorはインターフェースが一致している2者の間に入りますが、Adapterはインターフェースが一致しない2者の間に入ります

図形描画の例

Pythonで写経したコードはこちら

Decoratorと同様の図形描画です。
私たちが定義した、線分が引けるインターフェースDrawingInterfaceがあります。
メソッド:

  • start_at
  • line_to

図形描画に使いたいサードパーティライブラリのインターフェースはVendorGraphicsInterfaceです。
メソッド:

  • line

これらメソッドの引数も違います

  • DrawingInterfaceのstart_atメソッドやline_toメソッドは、私たちが定義したPointクラスのインスタンス1つを受け取ります
  • VendorGraphicsInterfaceのlineメソッドは、2点のxy座標(すなわち4つの整数値)を受け取ります

2つのインターフェースが合わない状況をAdapterで解決します。

drawing = VendorGraphicsDrawingAdapter(ExampleVendorGraphics())
drawing.start_at(Point(5, 40))
drawing.line_to(Point(20, 10))

AdapterでVendorGraphicsInterfaceをラップします。
そして、DrawingInterfaceを満たす2つのメソッドをAdapterに持たせるわけですね。
メソッドの実装ではVendorGraphicsInterfaceに委譲します

VendorGraphicsInterfaceサードパーティライブラリ)がDrawingInterface(私たちが表現している世界)を満たすように変換したわけです!

具体的な実装以外ではこんな話題が

結城浩にインタビュー Java言語で学ぶデザインパターン入門

ちょうぜつ本と同様の説明です。

インタフェース(API)があわないとき、それをうまく変換してやって適合するようにしてあげる存在がいればいいんです。 それを一般に「アダプター」と呼びます。ACアダプターと同じですね。

結城先生の本は、Mediatorパターンを理解する際に特にお世話になりました。

マンガでわかる Adapter

ちょうぜつ本の元になったアドベントカレンダー

機能は合ってるのに端子がかみ合わないものを形合わせしたいという「意図」に名前が付いているのであって、ぜんぶ新規でコードを書くなら Adapter パターン構造には意味がないよってことです。

たしかに全部新規で書くなら最初から端子が合うように書けばいいわけで、Adapterの出番はないですね

クリーンアーキテクチャのインフラストラクチャ層にあたる(ちょうぜつ本より)

1章(読書ログ)とのつながりがありました。

アダプターはアプリケーションアーキテクチャにもサードパーティライブラリにも依存します。(Kindle版 p.387)

インフラストラクチャ層の実現に噛むのがAdapterってことですね

そして、アダプターは変換だけを担うよう注意も促されます。

サードパーティのライブラリの使い方が本当に合っているかは、単体テストではわかりません。(Kindle版 p.388)

単体テストでアダプターはモックされますが、アダプターは実動作でテストしないと実際の動きが確認できません。
アダプターが変換だけを担うなら、実動作のテストが小さくなりますね。
単体テストのパターンの「コードに恥をかかせる」話が似ているなと思い出しました3

終わりに

ちょうぜつ本 8章よりAdapterパターンでした。
このパターンは、身の回りにあるアダプタと同じであると明確に理解できました。
2つのインターフェースが合わないときの変換

おまけ:AdapterとDecoratorを合わせた図形描画の例

AdapterによってVendorGraphicsInterfaceDrawingInterfaceを満たすので、それをDecorativeDrawingに渡せちゃいます!

drawing = DecorativeDrawing(
    VendorGraphicsDrawingAdapter(ExampleVendorGraphics())
)
drawing.rectangle(Point(10, 60), Point(80, 20))


  1. ちょうぜつ本読書ログシリーズではおなじみのこちらの書き出し。元は『お隣の天使様にいつの間にか駄目人間にされていた件』の「家事ができないのに一人暮らしとか舐めているのですか」です。なお、天使様は2024年の干支の可能性があります!
  2. 技術書界のきららとして知られます。アニメ化してほしいな〜
  3. #pyconapac2023 トーク「練習してテストを書けるようになるんだ」extra | テストを書くようになったあなたと語りたいトピック集 - nikkie-ftnextの日記にあります