Template Pattern


An implementation of Template Method Pattern (http://en.wikipedia.org/wiki/Template_method_pattern). Uses module as class. One file for each class. Based on Petite Abeille's module usage style. Using C++ example from http://login2win.blogspot.com/2008/06/c-template-pattern.html.

Abstract Base Class: Account

local require = require
local setmetatable = setmetatable
local getmetatable = getmetatable
local error = error
local assert = assert
local print = print
-- module declaration
module(...)
_VERSION = "1.0"
local class = setmetatable( _M, {} )
local meta = getmetatable( class )
function meta:__tostring()
 return ( "%s/%s" ):format( self._NAME, self._VERSION )
end
function class:__tostring()
 return "Account"
end
-- Abstract Methods
function Start(self)
 error("abstract method: should be implemented by derived")
end
function Allow(self)
 error("abstract method: should be implemented by derived")
end
function End(self)
 error("abstract method: should be implemented by derived")
end
function MaxLimit(self)
 error("abstract method: should be implemented by derived")
end
-- Template Method
function Withdraw(self, amount)
 self:Start()
 
 local limit = self:MaxLimit()
 if amount < limit then
 self:Allow()
 else
 print("Not allowed")
 end
 
 self:End()
end
-- constructor
function meta:__call()
 error("private ctor!")
end

Derived Class: AccountNormal?

local require = require
local getmetatable = getmetatable
local setmetatable = setmetatable
local error = error
local assert = assert
local print = print
local tostring = tostring
-- module declaration
module(...)
_VERSION = "1.0"
local Account = require("account")
local class = setmetatable( _M, {__index = Account} )
local meta = getmetatable( class )
function meta:__tostring()
 return ( "%s/%s" ):format( self._NAME, self._VERSION )
end
function class:__tostring()
 return "AccountNormal"
end
local ometa = { __index = class, __tostring = function() return "AccountNormal" end }
local function InitInstance(self, name)
 self.name = name or "noname"
 --...
end
-- Implement Abstract Methods
function Start(self)
 print("[" .. self.name .. "] Start ...")
end
function Allow(self)
 print("[" .. self.name .. "] Allow ...")
end
function End(self)
 print("[" .. self.name .. "] End ...")
end
function MaxLimit(self)
 return 1000
end
-- constructor
function meta:__call( name )
 
 local c = setmetatable( {}, ometa )
 InitInstance(c, name)
 
 return c
end

Derived Class: AccountPower?

local require = require
local getmetatable = getmetatable
local setmetatable = setmetatable
local error = error
local assert = assert
local print = print
local tostring = tostring
-- module declaration
module(...)
_VERSION = "1.0"
local Account = require("account")
local class = setmetatable( _M, {__index = Account} )
local meta = getmetatable( class )
function meta:__tostring()
 return ( "%s/%s" ):format( self._NAME, self._VERSION )
end
function class:__tostring()
 return "AccountPower"
end
local ometa = { __index = class, __tostring = function() return "AccountPower" end }
local function InitInstance(self, name)
 self.name = name or "noname"
 --...
end
-- Implement Abstract Methods
function Start(self)
 print("[" .. self.name .. "] Start ...")
end
function Allow(self)
 print("[" .. self.name .. "] Allow ...")
end
function End(self)
 print("[" .. self.name .. "] End ...")
end
function MaxLimit(self)
 return 5000
end
-- constructor
function meta:__call( name )
 
 local c = setmetatable( {}, ometa )
 InitInstance(c, name)
 
 return c
end

Test:

local require = require
local print = print
local Account = require("account")
local AccountNormal = require("accountnormal")
local AccountPower = require("accountpower")
-- local ab = Account() -- error! can't create instance of base class
local an0 = AccountNormal("an0")
an0:Withdraw(1500)
local an1 = AccountNormal("an1")
an1:Withdraw(1500)
local ap0 = AccountPower("ap0")
ap0:Withdraw(1500)
local ap1 = AccountPower("ap1")
ap1:Withdraw(1500)

Output:

>lua main.lua
[an0] Start ...
Not allowed
[an0] End ...
[an1] Start ...
Not allowed
[an1] End ...
[ap0] Start ...
[ap0] Allow ...
[ap0] End ...
[ap1] Start ...
[ap1] Allow ...
[ap1] End ...
>Exit code: 0

Download(5.1): Files:wiki_insecure/template-design-pattern.zip Download(5.2): Files:wiki_insecure/template-design-pattern-5.2.zip

-- HakkiDogusan


RecentChanges · preferences
edit · history
Last edited December 23, 2011 11:24 am GMT (diff)

AltStyle によって変換されたページ (->オリジナル) /