Java.use(better); Episode#21 ファインダーを作成する

前の記事記事一覧次の記事
Java.use(better, Scala);


Episode#21

ファインダーを作成する:開け胡麻



「ノー」という言葉を発することは
自治という道への第一歩を踏み出すことになる
Michael J. Fox - Wikipedia

《関連記事》

┃余録:match 式とポリモフィズム


□ パターンマッチングと case class

switch 文は、構造化プログラミングにおける制御構造「選択」を支援しますが、match 式は、オブジェクト指向プログラミングにおける「ポリモフィズム」を支援するとともに、パターンマッチングの恩恵に浴する case を利用できます。

  9: object Example {
 13:   def doIt() {
 14:     val c = new NamedColor("Aquamarine", 0x70, 0xDB, 0x93)
 15:     c match {
 16:       case NamedColor(n,r,g,b) =>
 17:         println("%s(%d,%d,%d)" format (n,r,g,b))
 18:     }
 19:   }
 20: }

[14]クラス NamedColor は、名前付きの色情報を扱いますが、パターンマッチングを利用すると、コードが簡潔で見通しも良くなります。[16]case に続くコンストラクターパターン NamedColor(n,r,g,b) を利用すると、名前や色情報の取扱いが容易になります。さもなければ、次のようにコードが冗長になるので、バグの温床にもなりかねません。

   :     println("%s(%d,%d,%d)" format (c.name, c.red, c.green, c.blue))

パターンマッチングと密接な関係にあるのが case class です。

 23: case class NamedColor(
 24:   name: String, red: Int, green: Int, blue: Int)

[23-24]case class を利用すると、getter/setter メソッドを用意する手間が省けるので、複雑になりがちなコードを簡潔に表現できます。

□ def unapply

スライサーを使えば、キャベツの千切りも楽ですが、プロの料理人を目指すなら、それに頼らない包丁さばきも身につけたいものです。同様に「プロ」グラマーの嗜みとして、case class に頼らないコードも記述できるようになりたいものです。これと同等のものは、object/class の組み合わせで実現できます。

 27: object NamedColor {
 28:   def unapply(x: NamedColor): Option[(String,Int,Int,Int)] =
 29:     Some((x.name, x.red, x.green, x.blue))
 30: }
 31: 
 32: class NamedColor(
 33:   name0: String, red0: Int, green0: Int, blue0: Int) {
 34:   def name = name0
 35:   def red = red0
 36:   def green = green0
 37:   def blue = blue0
 38: }

[28-29]メソッド unapply では、コンストラクターパターンの動作を規定します。リターン値に指定したタプルの各要素が、コンストラクターパターンの各引数に対応します。これに伴って[32-38]クラス NamedColor では、インスタンス属性を参照するためのメソッド群を用意します。

すると、コンストラクターパターンを介して、名前や色情報を個別に参照できるので、コードが簡潔で見通しが良くなります。確かに、case class は便利ですが、痒い所に手が届かないときには、object/class が必要になります。


》作業中です《

 ↑ TOP

Created: 2010/05/23|Last updated: 2013/06/04 7:01:18