Lua私有性(面向对象程序设计)

私有性(privacy)

很多人认为私有性是面向对象语言的应有的一部分。每个对象的状态应该是这个对象自己的事情。在一些面向对象的语言中,比如 C++和 Java 你可以控制对象成员变量或者成员方法是否私有。其他一些语言比如 Smalltalk 中,所有的成员变量都是私有,所有的成员方法都是公有的。第一个面向对象语言 Simula 不提供任何保护成员机制。

如前面我们所看到的 Lua 中的主要对象设计不提供私有性访问机制。部分原因因为这是我们使用通用数据结构 tables 来表示对象的结果。但是这也反映了后来的 Lua 的设计思想。Lua 没有打算被用来进行大型的程序设计,相反,Lua 目标定于小型到中型的程序设计,通常是作为大型系统的一部分。典型的,被一个或者很少几个程序员开发,甚至被非程序员使用。所以,Lua 避免太冗余和太多的人为限制。如果你不想访问一个对象内的一些东西就不要访问(If you do not want to access something inside an object, just do not do it.)。

然而,Lua 的另一个目标是灵活性,提供程序员元机制(meta-mechanisms),通过他你可以实现很多不同的机制。虽然 Lua 中基本的面向对象设计并不提供私有性访问的机制,我们可以用不同的方式来实现他。虽然这种实现并不常用,但知道他也是有益的,不仅因为它展示了 Lua 的一些有趣的角落,也因为它可能是某些问题的很好地解决方案。

设计的基本思想是,每个对象用两个表来表示:一个描述状态;另一个描述操作(或者叫接口)。对象本身通过第二个表来访问,也就是说,通过接口来访问对象。为了避免未授权的访问,表示状态的表中不涉及到操作;表示操作的表也不涉及到状态,取而代之的是,状态被保存在方法的闭包内。例如,用这种设计表述我们的银行账号,我们使用下面的函数工厂创建新的对象:

function newAccount (initialBalance) 
local self = {balance = initialBalance} 
local withdraw = function (v) 
 self.balance = self.balance - v 
end 
local deposit = function (v) 
 self.balance = self.balance + v 
end 
local getBalance = function () return self.balance end
return { 
 withdraw = withdraw, 
 deposit = deposit, 
 getBalance = getBalance 
 } 
end 

首先,函数创建一个表用来描述对象的内部状态,并保存在局部变量 self 内。然后,函数为对象的每一个方法创建闭包(也就是说,嵌套的函数实例)。最后,函数创建并返回外部对象,外部对象中将局部方法名指向最终要实现的方法。这儿的关键点在于:这些方法没有使用额外的参数 self,代替的是直接访问 self。因为没有这个额外的参数,我们不能使用冒号语法来访问这些对象。函数只能像其他函数一样调用:

acc1 = newAccount(100.00) 
acc1.withdraw(40.00) 
print(acc1.getBalance()) --> 60 

这种设计实现了任何存储在 self 表中的部分都是私有的,newAccount 返回之后,没有什么方法可以直接访问对象,我们只能通过 newAccount 中定义的函数来访问他。虽然我们的例子中仅仅将一个变量放到私有表中,但是我们可以将对象的任何的部分放到私有表中。我们也可以定义私有方法,他们看起来象公有的,但我们并不将其放到接口中。例如,我们的账号可以给某些用户取款享有额外的 10%的存款上限,但是我们不想用户直接访问这种计算的详细信息,我们实现如下:

function newAccount (initialBalance) 
local self = { 
 balance = initialBalance, 
 LIM = 10000.00, 
 } 
local extra = function () 
 if self.balance > self.LIM then
 return self.balance*0.10 
 else 
 return 0 
 end 
end 
local getBalance = function () 
 return self.balance + self.extra() 
end 
 ... 

这样,对于用户而言就没有办法直接访问 extra 函数了。

发布了290 篇原创文章 · 获赞 153 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_39885372/article/details/104404839