単純なプログラムを書換えよう(Groovy編)−Observer

Observerパターンを使ったModel-View-Controllerを作ってみた.java.util.Observerではなく,interface Observerを独自に定義している.

//Model.groovy
class Model{
  value=0
  observers=[]

  Model next(){
    setValue value+1
    return this
  }
  Model previous(){
    setValue value-1
    return this
  }
  void setValue(value){
    this.value=value
    notifyObservers()
  }

  void add(observer){
    observers.add observer
  }
  void remove(observer){
    observers.remove observer
  }
  void notifyObservers(){
    observers.each{
      it.update(this)
    }
  }
}
//end

//View.groovy
import groovy.swing.SwingBuilder
import java.awt.BorderLayout

class View implements Observer{
  private value

  View(args){
    builder=new SwingBuilder()
    view=builder.frame(defaultCloseOperation:javax.swing.WindowConstants.EXIT_ON_CLOSE,
                       size:[200,100]){
      panel(layout:new BorderLayout()){
        value=label(text:args.init.toString(),constraints:BorderLayout.CENTER)
        panel(constraints:BorderLayout.SOUTH) {
          button(text:'inc',actionPerformed:{args.controller.actionPerformed it})
          button(text:'dec',actionPerformed:{args.controller.actionPerformed it})
        }
      }
    }
    view.show()
  }
  
  void update(model){
    value.text=model.value.toString()
  }
}
//end

//Controller.groovy
class Controller{
  model

  void actionPerformed(event){
    actions=['inc':{model++},
             'dec':{model--}]
    actions[event.actionCommand]()
  }
}
//end

//Main.groovy
class Main{
  static void main(args){
    model=new Model(value:0)
    controller=new Controller(model:model)
    view=new View(controller:controller,init:0)
    model.add view
  }
}
//end
  

Viewがimplementsしているinterface Observerについて注意である.以下のようなコードを書くと問題ないような印象があるが,これはエラーになる.groovy 1.0-beta7ではまだinterfaceを実装できていていためである.

//Observer.groovy
interface Observer{
  void update(subject);
}
//end

$ groovy Observer.groovy
Exception in thread "main" NOT YET IMPLEMENTED: interfaces
        at org.codehaus.groovy.syntax.parser.ASTBuilder.interfaceDeclaration(AST
Builder.java:581)
        at org.codehaus.groovy.syntax.parser.ASTBuilder.topLevelStatement(ASTBui
lder.java:319)
<<省略>>
  

ということで,interfaceはJavaで記述し,コンパイルしておく必要がある.

//Observer.java
public interface Observer{
  void update(Object subject);
}
//end