ひらめの日常

日常のメモをつらつらと

『Java言語で学ぶデザインパターン入門』を読んだ

ずっと前から教養としてデザインパターンを勉強せなばと思っていてこの本を読みましたので、感想を残しておきます。

Javaは自分が最初に学んだ言語というのもあったし、基本的なインターフェースや抽象クラスあたりの知識があればよかったので、読み進めることができました。

4年前は「Bridgeパターン?何それ?」と思ってissueにメモったりしてたのですが、結局何も理解していませんでした...

4年越しに読んでみると、「機能クラスの階層」と「実装クラスの階層」を分けることのありがたみを理解することができました。やはりコードを書いていくうちに、拡張性などが課題となった経験を重ねて、実際に使う時のイメージが湧きやすくなったからだと思います。

GoFデザインパターンはもちろん、自分の知らなかった新しい単語についても学ぶことができました。

ダブルディスパッチとVisitorパターン

ダブルディスパッチとは、メソッドの引数に渡されたオブジェクトに対して、自分自身を引数として別のメソッドを実行する方法。Scalaだとこんな感じ

class A {
  def foo(b: B): Unit = {
    b.bar(this)
  }
}

Visitorパターンはこのダブルディスパッチの応用。Visitorパターンは、実際のデータ構造と、それに対する処理を分離するのが目的。この本では、ファイルとディレクトリの走査を例としていた。「実際のデータ構造」=「ファイルやディレクトリ」、「それに対する処理」=「走査」でありそれを行うのがVisitor。

まず、Visitorはデータ構造を訪問する visit メソッドを、それぞれのオブジェクトに対して実装する。

trait Visitor {
  def visit(file: File): Unit
  def visit(directory: Directory): Unit
}

そして、訪問者を受け入れるElementはインターフェースとして accept メソッドを持つ。この accept の中でVisitorの visit メソッドを呼び出す。

trait Element {
  def accept(v: Visitor): Unit
}

こうすることによってVisitor側では、(1)visitする対象によって具体的な処理を変更することができる (2) Visitorの具体的な実装によって、それぞれ処理を変更することができる。

そしてElement側では、Elementの具体的なオブジェクトに応じて、Visitorを受け入れた時にそのVisitorをどのように伝播させていくかを変更することができる。

Scalaで実装した詳細はこちらの Github を参照してください

github.com

参考:ダブル・ディスパッチ~ 典型的なオブジェクト指向プログラミング・イディオム ~

intrinsic/extrinsic

  • intrinsicな情報:共有させる情報。主に場所や状況に 依存しないもの
  • extrinsicな情報:共有させない情報。主に場所や状況に依存するもの

今まで暗黙知的に実装していたパターンに名前がつくと、引き出しから取り出しやすくなるし、他の人とのコミュニケーションもスムーズにいきそうですね。

Scalaでのデザインパターンは、関数型プログラミングの影響も受けているので、以下の本を読んだりして別途勉強したいです。

追記:会社の勉強会で読むことになりました!