Java.use(better);

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


Episode#07

NullObject パターンの事例 -- if と別れる50の方法


《関連記事》

■ 余録

参考までに、他言語の事例を以下に紹介します。

Scala:Singleton パターン

Episode#02 で紹介したように、Scala では、object を導入するだけで、冗長な Java のコードを削除できます。というのも、Singleton パターンのエッセンスはすでに、言語仕様に盛り込まれているからです。

case object NullObject
  extends Tile(Tile.dim-1, Tile.dim-1, 0) {
  override def backgroundColor = Color.lightGray
  override def drawValue(g: Graphics2D, x: Int, y: Int) {}
}

空白部分を埋める16番目のタイル NullObject は、object 宣言を伴う Singleton パターンを体現しています。

class Tile(var x: Int, var y: Int, value: Int) extends Piece {

その親クラス Tile では、属性 x,y,value を規定してあるので、その初期値を設定するだけです。また、

abstract class Piece extends Shape {
  def backgroundColor = Color.white
  def drawValue(g: Graphics2D, x: Int, y: Int)
}

抽象クラス Piece では、抽象メソッド backgroundColor,drawValue を規定してあるので、その本体を実現するだけです。

Java の隘路:イベント処理

Scala の事例を紹介する前に、Java の隘路を確認しておきます。

    addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) { update(e); }
    });

マウスクリックに対処するには、事前にリスナーを登録する必要があります。このとき、リスナーとして有効なのは、インターフェース MouseListener に準拠する任意のオブジェクトです。ただし、それを利用するには、次のメソッド群

    void mouseClicked(MouseEvent e)
    void mouseEntered(MouseEvent e)
    void mouseExited(MouseEvent e)
    void mousePressed(MouseEvent e)
    void mouseReleased(MouseEvent e)

をすべて実現する必要があり面倒です。そこで、規定の動作(なにもしない)を実現した、抽象クラス MouseAdapter を利用すると、コードを記述する手間が省けます。

また、発生するイベントとリスナーの組み合わせは、その一部だけを紹介しても

  • addActionListener - actionPerformed(ActionEvent)
  • addChangeListener - stateChanged(ChangeEvent)
  • addComponentListener - componentMoved(ComponentEvent)
  • addFocusListener - focusGained(FocusEvent)
  • addKeyListener - keyTyped(KeyEvent)
  • addListSelectionListener - valueChanged(ListSelectionEvent)
  • addMouseListener - mouseClicked(MouseEvent)
  • addMouseMotionListener - mouseMoved(MouseEvent)



という具合にさまざまです。そこで、これらを統一できる仕掛があると便利です。その有効な手段となるのが OOP の三本柱の1つである「ポリモフィズム」です。

Scala:イベント処理

リスナーを登録するときの Java のイディオム add...Listener は、

    new Publisher {
      reactions += {
        case MouseClicked(_,point,_,_,_) => update(point)
      }
    }.listenTo(mouse.clicks)

Scala ではすべて、listenTo に統一できます。このとき「情報隠蔽の原則」に沿って、addMouseListener/MouseEvent などは利用者(プログラマー)には知らされず、提供者(プログラマー)だけが知ることになります。そして、マウスをクリックしたときに発生するイベントに付随する情報はすべて、MouseClicked に集約されます。すると、パターンマッチングによって、クリックした位置の座標 point を簡単に参照できます。また、reactions に追加登録できるものの種別には依存しないので「ポリモフィズム」を体現しているのが分ります。

Jython にも、Scala と同様の利便が図られています(後述)。


 ↑ TOP

》作業中です《

update*13/02/28 20:36:46