lua 使用消息订阅实现业务模块的解耦

lua使用消息订阅实现业务模块的解耦

lua中经常需要在对象变更时触发其他业务模块的操作,代码往往放置在lua的变更对象中,当业务需求有变更时,需要在变更对象的模块进行代码的修改,可维护性较差。
在lua中将触发其他业务模块的操作代码放置在变更的对象中,使得代码耦合性增强。
通过在lua中引入事件消息的发布与订阅机制可以使得触发事件的模块与监听事件的模块解耦,提高代码可维护性。示例代码示例如下:
-- 文件eventmgr.lua:

module("EventMgr", package.seeall )

local eventMgr = nil

function EventMgr:Instance()
	if nil == eventMgr then
		eventMgr = self
		eventMgr.listenerList = {}
	end
	return eventMgr
end

function EventMgr:AddEventListener(eventType,key,callBack,selfObj)
	assert(eventType ~= nil)
	assert(key ~= nil)
	assert(callBack ~= nil)

	if self.listenerList[eventType] == nil then
		self.listenerList[eventType] = {}
	end

	if self.listenerList[eventType][key] == nil then
		self.listenerList[eventType][key] = {}
	end

	local listenerData = {}
	listenerData.key = key
	listenerData.callBack = callBack
	listenerData.selfObj = selfObj
	self.listenerList[eventType][key] = listenerData
end

function EventMgr:RemoveEventListener(eventType,key)
	assert(eventType ~= nil)
	assert(key ~= nil)
	local list = self.listenerList[eventType]

	if list then
		list[key] = nil
		if LuaTable.IsEmpty(list) then
			self.listenerList[eventType] = nil
		end
	end
end

function EventMgr:removeAllEventListeners(key)
	assert(key ~= nil)
	
	for eventType,list in pairs(self.listenerList) do
		list[key] = nil
		if LuaTable.IsEmpty(list) then
			self.listenerList[eventType] = nil
		end
	end
end

function EventMgr:DispatchEvent(eventType,data)
	assert(eventType ~= nil)
	local list = self.listenerList[eventType]

	if list then
		for k,listenerData in pairs(list) do
			if listenerData.selfObj then
				listenerData.callBack(listenerData.selfObj,eventType,data)
			else
				listenerData.callBack(eventType, data)
			end
		end
	end
end
-- 文件eventtype.lua(示例):

local nextEventID = 0

local DefineEvent = function ()
	nextEventID = nextEventID + 1
	return nextEventID
end

--hero
EVENT_HERO_MOVESPEED_CHG                           = DefineEvent()        --主角移动速度改变
EVENT_HERO_POS_CHG                                 = DefineEvent()        --主角位置改变
EVENT_HERO_ENTER_BATTLE                            = DefineEvent()        --主角进入战斗状态
EVENT_HERO_LEAVE_BATTLE                            = DefineEvent()        --主角离开战斗状态

测试示例

-- 文件testEventtype.lua(测试示例)require("eventtype")
require("eventmgr")


print("EVENT_HERO_ENTER_BATTLE:"..EVENT_HERO_ENTER_BATTLE)
local eventmgr_inst = EventMgr.EventMgr:Instance()
local eventmgr_inst2 = EventMgr.EventMgr:Instance()

if(eventmgr_inst == eventmgr_inst2) then
	print("singleton !")
end

TestEvent = {}

function TestEvent:Instance()
	eventmgr_inst:AddEventListener(EVENT_HERO_ENTER_BATTLE,self,TestEvent.OnEvent,self)
end

function TestEvent:OnEvent(eventType,data)
	print("receive event:"..eventType.." data:"..data)
end

TestEvent:Instance()
aa = {}
aa[TestEvent] = 5

for k,v in pairs(aa) do
	print(k,"====",v)
end

print(aa)

eventmgr_inst:DispatchEvent(EVENT_HERO_ENTER_BATTLE, 100)

你可能感兴趣的:(Lua)