Lua中的封装
Lua
中没有private
,table
中的key/value
可以随意访问,利用metatable
虽然可以施加一些限制,但是实际上有各种方法可以绕过这些限制。
下面介绍一种方法,实现真正的封装。
local LuaClass = require "LuaClass"
local TestClass = LuaClass("TestClass")
local PrivateDataMap = LuaClass:PrivateDataMap{
"MemberA",
"MemberB",
}
function TestClass:GetMemberA()
return PrivateDataMap:Get(self, "MemberA")
end
function TestClass:SetMemberA(Value)
local ExistValue = PrivateDataMap:Get(self, "MemberA")
if ExistValue ~= Value then – 比较差异
PrivateDataMap:Set(self, "MemberA", Value)
DispatchXXX – 触发事件
end
end
function TestClass:GetMemberB()
return PrivateDataMap:Get(self, "MemberB")
end
上面这段代码中,每个object
对应两个成员MemberA
、MemberB
,因为PrivateDataMap
是局部变量,所以外部的代码无法直接访问,只能通过TestClass
提供的接口访问这些成员。
PrivateDataMap
的实现方法如下:
function LuaClass:PrivateDataMap(MemberNameList)
local DataMap = {}
function DataMap:Set(Owner, MemberName, Value)
local Owner2ValueMap = DataMap[MemberName]
if Owner2ValueMap then
Owner2ValueMap[Owner] = Value
end
end
<span class="k">function</span> <span class="nf">DataMap</span><span class="p">:</span><span class="n">Get</span><span class="p">(</span><span class="n">Owner</span><span class="p">,</span> <span class="n">MemberName</span><span class="p">)</span>
<span class="kd">local</span> <span class="n">Owner2ValueMap</span> <span class="o">=</span> <span class="n">DataMap</span><span class="p">[</span><span class="n">MemberName</span><span class="p">]</span>
<span class="k">return</span> <span class="n">Owner2ValueMap</span> <span class="ow">and</span> <span class="n">Owner2ValueMap</span><span class="p">[</span><span class="n">Owner</span><span class="p">]</span>
<span class="k">end</span>
<span class="kd">local</span> <span class="n">CommonFunction</span> <span class="o">=</span> <span class="nb">require</span> <span class="s2">"CommonFunction"</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">MemberName</span> <span class="k">in</span> <span class="nb">pairs</span><span class="p">(</span><span class="n">MemberNameList</span><span class="p">)</span> <span class="k">do</span>
<span class="n">DataMap</span><span class="p">[</span><span class="n">MemberName</span><span class="p">]</span> <span class="o">=</span> <span class="n">CommonFunction</span><span class="p">:</span><span class="n">CreateWeakTable</span><span class="p">()</span>
<span class="k">end</span>
<span class="k">return</span> <span class="n">DataMap</span>
end
其中,object
与member
的对应关系存储在weaktable
中,不会影响object
的释放。