2010年7月9日金曜日

C++プログラマがLuaを勉強してみる第10回

◆Luaでテンプレートメソッドパターン
今回はLua初心者のくせにテンプレートメソッドパターンに挑戦してしまいました。
テンプレートメソッドパターンについてはここ参照
無理矢理感が否めないので、ぜんぜんちっげーよ!ってコメント待ってます!

まずは、簡単にクラス図の説明を書きます。
なんかどっかでみたよーな命名ですが気にしない気にしない
   CaffeineBeverageクラス(Superクラス)
               △
                |
   ----------------
   |                        |
Coffeeクラス      Teaクラス


以下ソースコード
CaffeineBeverage.lua
----------------------------------------
--CaffeineBeverageクラス
----------------------------------------
CaffeineBeverage = {}

-- new
function CaffeineBeverage:new(_caffeineBeverage)
 local obj = {}
 -- field
 if _caffeineBeverage then
  obj.name = _caffeineBeverage.name
 else
  obj.name = ""
 end

 self.__index = self
 setmetatable(obj, self)
 return obj
end

-- property
function CaffeineBeverage:set(_name)
 self.name = _name
end


-- __tostring over ride
function CaffeineBeverage:__tostring()
 return "name:"..self.name
end

-- clone
function CaffeineBeverage:clone()
 return CaffeineBeverage:new(self)
end

-- prepareRecipe
function CaffeineBeverage:prepareRecipe()
 CaffeineBeverage:boilWater()
 CaffeineBeverage:brew()
 CaffeineBeverage:pourInCup()
 CaffeineBeverage:addCondiments()
end

-- boilWater
function CaffeineBeverage:boilWater()
 print("お湯を沸かす。。。")
end

-- brew()
function CaffeineBeverage:brew()
 error("have to override")
end

-- pourInCup
function CaffeineBeverage:pourInCup()
 print("カップに注ぐ。。。")
end

-- addCondiments
function CaffeineBeverage:addCondiments()
 error("have to override")
end


Coffee.lua
dofile("CaffeineBeverage.lua") -- C/C++で言うところの#include

----------------------------------------
--Coffeeクラス
----------------------------------------
Coffee = {}

-- new
function Coffee:new(_coffee)
  obj = {}
 -- field
 if _coffee then
  obj = CaffeineBeverage:new(_coffee)
 else
  obj = CaffeineBeverage:new()
 end

 -- clone (override)
 obj.__index.brew = function()
  return Coffee:new(self)
 end

 -- brew (overrice)
 obj.__index.brew = function()
  print("コーヒーをドリップする")
 end

 -- addCondiments (override)
 obj.__index.addCondiments = function()
  print("砂糖とクリープを加える")
 end

 return obj
end


Tea.lua
dofile("CaffeineBeverage.lua")
----------------------------------------
--Teaクラス
----------------------------------------
Tea = {}

-- new
function Tea:new(_tea)
  obj = {}
 -- field
 if _tea then
  obj = CaffeineBeverage:new(_tea)
 else
  obj = CaffeineBeverage:new()
 end

 -- clone
 obj.__index.brew = function()
  return Tea:new(self)
 end

 -- brew
 obj.__index.brew = function()
  print("ティーバッグをお湯に浸す")
 end

 -- addCondiments
 obj.__index.addCondiments = function()
  print("砂糖とレモン")
 end

 return obj
end

main.lua
dofile("Coffee.lua")
dofile("Tea.lua")

----------------------------------------
-- main
----------------------------------------
function main()
 print("--コーヒーの生成")
 a = Coffee:new()
 a:set("コーヒー")
 print(a)
 a:prepareRecipe()

 print("\n")

 print("--紅茶の生成")
 b = Tea:new()
 b:set("紅茶")
 print(b)

 b:prepareRecipe()

 print("\n")

 print("--コピーコンストラクタの使用")
 c = Tea:new(b)
 print(c)
 c:set("レモンティ")
 print(c)
 print(b)

 print("\n")

 print("クローン")
 d = c:clone()
 print(d)
 d:set("レモンの紅茶")
 print(d)
 print(c)
end

-- call main
-- try catchみたいなの使ってます。
-- error()ってメソッドがthrowに相当します。
local status, err = pcall(main)
if status then
 -- do nothing
else
 print(err)
end

0 件のコメント:

コメントを投稿