Template Pattern |
|
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