CFMLでデザインパターン実装(2.Builder)
新しい言語は。。。やっぱPythonか?と言いつつ溜まっていたネタを。
今回はBuilderの実装をしてみました。実は今回はcfinterfaceの使い道を考えるというテーマがあったので、前回よりじっくりやってみました。が。。。はてさて、やはり微妙でした。
ともあれ、例によってまずはJava実装から。
まず、基本となる機能をJavaで実装したもの。
Java-1:呼び元(TestCaseをそのままmain扱い)
package creational_patterns.builder; import junit.framework.TestCase; public class _MainTestCase extends TestCase { public void test() { try { Builder builder = null; String word = null; builder = new HelloWorldBuilder(); word = this.getSaid(builder); System.out.println(word); builder = new GoodByWorldBuilder(); word = this.getSaid(builder); System.out.println(word); } catch (Exception e) { e.printStackTrace(); fail(); } } private String getSaid(Builder builderInstance) { Director director = new Director(builderInstance); director.constract(); return builderInstance.getWord(); } }
Java-2:Interface Builder
package creational_patterns.builder; public interface Builder { public void setWord(String word); public String getWord(); }
Java-3:Director
package creational_patterns.builder; public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } public void constract() { this.builder.setWord("Hello, Builder pattern."); } }
Java-4:Concrete builder(HelloWorldBuilder)
package creational_patterns.builder; import common.HelloWorld; public class HelloWorldBuilder implements Builder { private HelloWorld helloWorld; public HelloWorldBuilder() { this.helloWorld = new HelloWorld(); } @Override public String getWord() { return this.helloWorld.say(); } @Override public void setWord(String word) { this.helloWorld.setWord(word); } }
以上がJavaのソースコードです。(実はもう1つ、GoodByWorldBuilderが存在していますが、Directorでパラメータをべた書きしている為、ここに掲載する意味もない実装する意味もないので省略です)これを実行すると、
Hello, Builder pattern.
が出てきます。
これに続いて、
このJavaコードをまんまCFMLに展開。
cf-1:呼び元(ブラウザで見るしかないのでCFMで実装)
<html> <head> <title>Gof design pattern@CFML</title> </head> <body> <cfoutput> <cftry> <h5>Builder</h5> <cfobject name="Variables.builder" component="cftest.gof.builder.HelloWorldBuilder"/> <cfinvoke component="#Variables.builder#" method="HelloWorldBuilder"/> <cfinvoke component="cftest.gof.builder.Director" method="Director"> <cfinvokeargument name="builder" value="#Variables.builder#"/> </cfinvoke> <cfset Variables.s=Variables.builder.getWord()/> HelloWorldBuilder:[#Variables.s#]<br/> <hr/> <cfobject name="Variables.builder" component="cftest.gof.builder.GoodByWorldBuilder"/> <cfinvoke component="#Variables.builder#" method="GoodByWorldBuilder"/> <cfinvoke component="cftest.gof.builder.Director" method="Director"> <cfinvokeargument name="builder" value="#Variables.builder#"/> </cfinvoke> <cfset Variables.s=Variables.builder.getWord()/> HelloWorldBuilder:[#Variables.s#]<br/> <cfcatch> <cfdump var="#cfcatch#"/> </cfcatch> </cftry> </cfoutput> </body> </html>
cf-2:Builder
<cfinterface> <cffunction name="setWord" access="public" returntype="void"> <cfargument name="word" type="string" required="true"/> </cffunction> <cffunction name="getWord" access="public" returntype="string"/> </cfinterface>
cf-3:Director
<cfcomponent output="false"> <cffunction name="Director" access="public" returntype="void"> <cfargument name="builder" type="cftest.gof.builder.Builder" required="true"/> <cfset This.builder=Arguments.builder/> </cffunction> <cffunction name="constract" access="public" returntype="void"> <cfinvoke component="#This.builder#" method="setWord"> <cfinvokeargument name="word" value="Hello, Builder pattern."/> </cfinvoke> </cffunction> </cfcomponent>
cf-4:Concrete builder(HelloWorldBuilder)
<cfcomponent implements="cftest.gof.builder.Builder" output="false"> <!---// コンストラクタ風 //---> <cffunction name="HelloWorldBuilder" access="public" returntype="cftest.gof.common.HelloWorld"> <cfobject name="This.helloWorld" component="cftest.gof.common.HelloWorld"/> <cfinvoke component="#This.helloWorld#" method="HelloWorld"/> <cfreturn This.helloWorld/> </cffunction> <cffunction name="setWord" access="public" returntype="void"> <cfargument name="word" type="string" required="true"/> <cfinvoke component="#This.helloWorld#" method="setWord"> <cfinvokeargument name="word" value="#Arguments.word#"/> </cfinvoke> </cffunction> <cffunction name="getWord" access="public" returntype="string"> <cfset var retVal=""/> <cfinvoke component="#This.helloWorld#" method="getWord" returnvariable="retVal"> <cfreturn retVal/> </cffunction> </cfcomponent>
で、実行すると、
HelloWorldBuilder:[Hello, World.]
こんな感じ。