単純なプログラムを書換えよう(Groovy編)−抽象クラス
Commandを抽象クラスにするをまねてGroovyで書いてみよう.
実は,Groovy 1.0-beta6ではコンストラクタをprivateにできない.したがって,CommandDispatcherをSingletonにはできていない.
//Command.groovy abstract class Command{ model Command(args){ this.model=args } void execute(){} } //end //IncCommand.groovy class IncCommand extends Command{ IncCommand(args){ super(args) } void execute(){ model++ } } //end //DecCommand.groovy class DecCommand extends Command{ DecCommand(args){ super(args) } void execute(){ model-- } } //end //CommandDispatcher.groovy import java.io.File class CommandDispatcher{ private static classloader={new GroovyClassLoader().parseClass(new File(it))} private static commands=["inc":classloader("IncCommand.groovy"), "dec":classloader("DecCommand.groovy")] model CommandDispatcher(args){ //コンストラクタをpriveteにはできない model=args.model } Command command(args){ Javaで書いて予めコンパイルしておかないとClass.forName(String)が使えない return commands[args.type] .getConstructor(new Class[]{java.lang.Object}) .newInstance(new Object[]{this.model}) } } //end //Controller.groovy import java.awt.event.ActionEvent import java.awt.event.ActionListener class Controller implements ActionListener{ model dispatcher Controller(args){ model=args.model dispatcher=new CommandDispatcher(model:model) //Singletonにできないのでインスタンスを作る } void actionPerformed(ActionEvent event){ dispatcher.command(type:event.getActionCommand()).execute() } } //end //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').addActionListener args.controller //こう書くとなぜかActionEvent/ActionListenerが使える button(text:'dec').addActionListener args.controller } } } view.show() } void update(model){ value.text=model.value.toString() } } //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