[ColdFusion] コンポーネント(3/4)

  • このエントリーをはてなブックマークに追加
  • 人気ブログランキング

例題

三角形、長方形、円があります。
1.それぞれの面積を求める関数を作りなさい
2.それぞれの周辺の長さを求める関数を作りなさい
3.それぞれの面積を合計した関数を作りなさい
4.それぞれの周辺の長さを合計した関数を作りなさい

 

今回はオブジェクト指向で考えて作って見ます。

 

オブジェクトとしては、
三角形、長方形、円、ですね。

 

動きとしては、
面積の計算、
長さの計算
が、共通しています。

 

よく使う関数の場合は、引数が必要になりますが、
オブジェクト指向の場合は、
事前にデータを渡しておき、
そのデータをもとに計算することができます。

 

そうすると、三角形、長方形、円は
引数なしの関数で、

calcMenseki
calcNagasa

と、することができます。

 

オブジェクト指向の特徴としては、
ポリモーフィズム(多態性)というものがあります。

「多態性(Polymorphism)」とは、オブジェクト指向における
「実行される処理の実体が、コールされたメッセージではなく、
メッセージを受けたオブジェクトによって決定される性質」のことです。

http://codezine.jp/article/detail/3709

 

例えば、三角形というオブジェクトに対して

calcMenseki

というメッセージを受けると
その三角形の面積の計算を行う、
ということです。

 

 

それでは以下はオブジェクト指向を使った例です。

 

●基本オブジェクト

●obj.cfc

<cfcomponent>

     <!---=========================================
     init
     ==========================================--->
     <cffunction name="init" returnType="obj" output="no">

          <cfreturn this>
     </cffunction>
</cfcomponent>

 

●三角形オブジェクト

●sankaku.cfc

<cfcomponent extends="obj">
     <cfset variables.teihen     = 0>
     <cfset variables.takasa     = 0>
     <cfset variables.hen1     = 0>
     <cfset variables.hen2     = 0>
     <cfset variables.hen3     = 0>

     <cffunction name="calcMenseki" returnType="numeric" output="no">
          <cfreturn (variables.teihen * variables.takasa / 2) >
     </cffunction>
     <cffunction name="calcNagasa" returnType="numeric" output="no">
          <cfreturn (variables.hen1 + variables.hen2 + variables.hen3) >
     </cffunction>

     <!--- setter --->
     <cffunction name="setTeihen" returnType="void" output="no">
          <cfargument name="teihen" type="numeric" required ="yes">

          <cfset variables.teihen = arguments.teihen>
     </cffunction>
     <cffunction name="setTakasa" returnType="void" output="no">
          <cfargument name="takasa" type="numeric" required ="yes">

          <cfset variables.takasa = arguments.takasa>
     </cffunction>
     <cffunction name="setHen1" returnType="void" output="no">
          <cfargument name="hen1" type="numeric" required ="yes">

          <cfset variables.hen1 = arguments.hen1>
     </cffunction>
     <cffunction name="setHen2" returnType="void" output="no">
          <cfargument name="hen2" type="numeric" required ="yes">

          <cfset variables.hen2 = arguments.hen2>
     </cffunction>
     <cffunction name="setHen3" returnType="void" output="no">
          <cfargument name="hen3" type="numeric" required ="yes">

          <cfset variables.hen3 = arguments.hen3>
     </cffunction>
</cfcomponent>

 

●長方形オブジェクト

●shikaku.cfc

<cfcomponent extends="obj">
     <cfset variables.tate = 0>
     <cfset variables.yoko = 0>

     <cffunction name="calcMenseki" returnType="numeric" output="no">
          <cfreturn (variables.tate * variables.yoko) >
     </cffunction>
     <cffunction name="calcNagasa" returnType="numeric" output="no">
          <cfreturn ((variables.tate * 2) + (variables.yoko * 2)) >
     </cffunction>

     <!--- setter --->
     <cffunction name="setTate" returnType="void" output="no">
          <cfargument name="tate" type="numeric" required ="yes">

          <cfset variables.tate = arguments.tate>
     </cffunction>
     <cffunction name="setYoko" returnType="void" output="no">
          <cfargument name="yoko" type="numeric" required ="yes">

          <cfset variables.yoko = arguments.yoko>
     </cffunction>
</cfcomponent>

 

●円オブジェクト

●en.cfc

<cfcomponent extends="obj">
     <cfset variables.hankei = 0>

     <cffunction name="calcMenseki" returnType="numeric" output="no">
          <cfreturn (variables.hankei * variables.hankei * 3.14) >
     </cffunction>
     <cffunction name="calcNagasa" returnType="numeric" output="no">
          <cfreturn (2 * variables.hankei * 3.14) >
     </cffunction>

     <!--- setter --->
     <cffunction name="setHankei" returnType="void" output="no">
          <cfargument name="hankei" type="numeric" required ="yes">

          <cfset variables.hankei = arguments.hankei>
     </cffunction>
</cfcomponent>

 

●オブジェクトをいれる箱オブジェクト

●objbox.cfc

<cfcomponent>
     <cfset variables.aryObj = arrayNew(1)>

     <cffunction name="init" returnType="objbox" output="no">
          <cfreturn this>
     </cffunction>
     <cffunction name="setObj" returnType="void" output="no">
          <cfargument name="obj" type="obj" required ="yes">

          <cfset ArrayAppend(variables.aryObj, arguments.obj)>
     </cffunction>
     <cffunction name="calcMenseki" returnType="numeric" output="no">
          <cfset var local = structNew()>

          <cfset local.gokei = 0>
          <cfloop index="local.idx" array="#variables.aryObj#">
               <cfset local.gokei = local.gokei + local.idx.calcMenseki()>
          </cfloop>

          <cfreturn local.gokei>
     </cffunction>
     <cffunction name="calcNagasa" returnType="numeric" output="no">
          <cfset var local = structNew()>

          <cfset local.gokei = 0>
          <cfloop index="local.idx" array="#variables.aryObj#">
               <cfset local.gokei = local.gokei + local.idx.calcNagasa()>
          </cfloop>

          <cfreturn local.gokei>
     </cffunction>
</cfcomponent>

 

●実際の処理

●index.cfm

<cfparam name="url.p" default="">

<!--- objbox作成 --->
<cfset objbox = CreateObject("component", "objbox").init()>

<!--- 三角形を2つobjboxにセット --->
<cfloop index="idx" from="1" to="2">
     <cfset objSan = CreateObject("component", "sankaku").init()>
     <cfset objSan.setTeihen(3)>
     <cfset objSan.setTakasa(4)>
     <cfset objSan.setHen1(3)>
     <cfset objSan.setHen2(4)>
     <cfset objSan.setHen3(5)>
     <cfset objbox.setObj(objSan)>
</cfloop>

<!--- 長方形を3つobjboxにセット --->
<cfloop index="idx" from="1" to="3">
     <cfset objShi = CreateObject("component", "shikaku").init()>
     <cfset objShi.setTate(5)>
     <cfset objShi.setYoko(6)>
     <cfset objbox.setObj(objShi)>
</cfloop>

<!--- 円を4つobjboxにセット --->
<cfloop index="idx" from="1" to="4">
     <cfset objEn = CreateObject("component", "en").init()>
     <cfset objEn.setHankei(7)>
     <cfset objbox.setObj(objEn)>
</cfloop>

<cfoutput>
<cfif url.p eq "menseki">
menseki gokei = #objbox.calcMenseki()#
</cfif>
<cfif url.p eq "nagasa">
nagasa gokei = #objbox.calcNagasa()#
</cfif>
</cfoutput>

 

index.cfmの動きとしては、

 

1.三角形などのオブジェクトを作って、箱オブジェクトにいれる。
2.指定した処理で、箱オブジェクトの処理

 

面積の合計など行っています。

 

箱オブジェクトが「多態性」をうまく利用しています。
また「継承」も利用しています。

 

関数をあらためて見てみます。

 

●setObj関数

<cffunction name="setObj" returnType="void" output="no">
     <cfargument name="obj" type="obj" required ="yes">

     <cfset ArrayAppend(variables.aryObj, arguments.obj)>
</cffunction>

 

あらかじめ用意したvariables.aryObj配列変数に
オブジェクトをセットしています。

 

引数のtypeがobjとなっていますが、
これはobj.cfcを意味しています。

 

obj.cfcを継承している三角形、長方形、円オブジェクトを
セットすることができます。

 

●calcMenseki関数

<cffunction name="calcMenseki" returnType="numeric" output="no">
     <cfset var local = structNew()>

     <cfset local.gokei = 0>
     <cfloop index="local.idx" array="#variables.aryObj#">
          <cfset local.gokei = local.gokei + local.idx.calcMenseki()>
     </cfloop>

     <cfreturn local.gokei>
</cffunction>

 

local.gokei変数にセットしている行がキモですね。
local.idx.calcMenseki()

 

この部分は、それぞれのオブジェクトに対する関数を使っています。

 

三角形なら三角形用のcalcMenseki関数、
長方形なら長方形用のcalcMenseki関数、
円なら円用のcalcMenseki関数、

 

を、使っています。

 

考え方によっては、シンプルに作ることができますね。

  • このエントリーをはてなブックマークに追加
  • 人気ブログランキング

この記事に関連する記事一覧

最近の投稿
カテゴリー
タグ
アーカイブ
プロフィール