単純なプログラムを書換えよう(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