lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi all!

Lately when I do OO I usually use the following pattern:

-------------------------------------------------------
-- mymodule - here the object ctor is defined
M = {}

local MyObject_MT = { __metatable = "private" }
MyObject_MT.__index = MyObject_MT
MyObject_MT.__newindex = function()
error( "cannot modify a MyObject object directly - use its methods instead", 2 )
end
MyObject_MT.__tostring = function( proxy )
   return "MyObject object (" .. tostring( proxy[ MyObject_MT ] ) .. ")"
end

-- object constructor
local function M_MyObject( someoption )
   local proxy, object = {}, {}
   proxy[ MyObject_MT ] = object
   -- perform object initialization
   object.someoption = someoption
   return setmetatable( proxy, MyObject_MT )
end
M.MyObject = M_MyObject


local function MyObject_DoSomething( proxy )
 local object = proxy[ MyObject_MT ]
 print( "this is object named: " .. object.someoption )
end
MyObject_MT.DoSomething = MyObject_DoSomething

return M

-- client code - here objects of type "MyObject" are used

local mymodule = require 'mymodule'

local obj = mymodule.MyObject( "foobar" )
obj:DoSomething()

-------------------------------------------------------


That is I make use of the follwing:
- a shared metatable for all objects of the same kind
- proxy tables
- the actual object is stored in the proxy table using a "private" index (the metatable itself) to achieve encapsulation and prevent the client from tampering with the object directly.

Note: I don't need inheritance support, since almost always use this pattern to represent objects of "concrete classes".

I'm still a bit puzzled at the plethora of possible approaches, and I'm still exploring, so I will greatly appreciate some comments.

In particular, is this kind of approach acceptable, i.e, is it sound enough or am I missing something? Are there some obvious drawbacks of such a design pattern?

Thanks in advance for any help.

P.S.: I've browsed the WIKI and this approach doesn't seem to be there.
It is in part based of a suggestion given in PiL (section 13.4.4 - Tracking Table Accesses). I've also searched the list archive for "proxy tables", but the results where overwhelming and I didn't find anything close to what I'm using - thus my doubts.


-- Lorenzo