书接上回。在展示了App最顶层的代码后,我们去看看各模块怎样编程。
为了能看懂各模块的代码,首先须要铺垫一下Softchip架构的基本概念和设计规范。
1、随意模块不持有其它模块的实例。自然不再显式使用句柄调用不论什么方法。
这意味着模块之间不存在编码期和编译期的耦合。
2、每一个模块在形式上仅仅与Machine之间存在接口。该接口以API和Event两种形态存在。
API将直接映射到函数入口地址,使用者可直接调用,执行期性能高。主要用于Utility性质的方法和须要高性能的场合。
Event也是同步调用,但执行期性低于API。它的关键作用是在逻辑上分割冗长的调用链。在传统套路中。一个模块在完毕自己的处理后。往往还要辛苦地触发其它模块的相关兴许动作,这在逻辑上相当于惦记着“别人的事儿”。Event的引入相当于将原来长长的调用链在时间上切分为一个一个的阶段状态。
每一个模块仅仅须要告诉Machine“X的事情Y完了”,Machine会自己主动查找谁须要在“X的事情Y完了”之后继续。Machine寻找兴许操作的根据就是目标模块在自己的接口中所做的事件监听声明。
3、模块接口由自行声明,包含:3-1) outAPI : 自己须要调用的API名称列表。
3-2) inAPI : 自己能够提供其它模块调用的API名称列表(附带相应的函数入口地址)。
3-3) inEvent : 自己要监听的事件名称列表(附带相应的事件处理函数入口地址)。
3-4) outEvent: 自己是否要发送事件。
基于各模块声明。Machine自己主动将各模块“插入”。完毕执行期API的绑定和event的分发。
4、概括来说,各模块基本仅仅须要关心“自己的事情”:4-1) 我提供什么API?
4-2) 我须要调用什么API?
4-3) 我监听并处理什么事件?
4-4) 我产生什么事件?
反过来讲,模块不须要关心“别人的事情”:
4-5) 谁使用我的API?
4-6) 谁提供API给我用?
4-7) 我监听的事件是谁产生的?(我干活之前是谁在干?)
4-8) 我产生的事件谁处理?(我干完了谁来继续?)举个简单的样例,在TextChat的设计中,LoginWindow登录成功后,不须要显式通知ChatWindow,由于那是ChatWindow的事情。LoginWindow仅仅须要告诉Machine“LoginWindow登录成功了”。
Machine会自己主动找到ChatWindow出来干活,由于ChatWindow之前已经告诉过Machine,假设“LiginWindow登录成功了”。请通知我。
OK,有了上面的铺垫,以下的代码就比較easy看懂了。基本套路是:
1、每一个模块都继承Chip类。
2、实现_DefineInterface()方法以完毕接口声明。
3、实现_PowerOn()方法以接收Machine发出的"上电"通知。
除此以外,每一个模块就全然自由了。爱怎么玩就怎么玩吧。
新版的模块关系參照下图。
from Softchip import Chip
class Controller(Chip): def __init__(self, chipID): Chip.__init__(self, chipID) def _DefineInterface(self): outAPIList = [ u'connect_server', u'disconnect_server', ] inAPIList = [ (u'api_start_work', self.__apiStartWork), ] inEventList = [ (u'evt_logout_done', self.__evtOnLogoutDone), ] self.__interface = { Chip.TYPE_INT_API : inAPIList, Chip.TYPE_OUT_API : outAPIList, Chip.TYPE_OUT_EVENT: None, } return self.__interface def _PowerOn(self): self._eHandler = self.__interface[CHIP.TYPE_OUT_EVENT] apiMap = self._DefineInterface[CHIP.TYPE_OUT_API] self.__apiConnect = apiMap[u'connect_server'] self.__apiDisconnect = apiMap[u'disconnect_server'] def __apiStartWork(self, serverHost, serverPort): succeeded = self.__apiConnect(serverHost, serverPort) if not succeeded: self._eHandler(u'evt_connect_failed') return self._eHandler(u'evt_connect_succeeded') def __evtOnLogoutDone(self): self.__apiDisconnect() class CommunicationManager(Chip): def __init__(self, chipID): Chip.__init__(self, chipID) def _DefineInterface(self): inAPIList = [ (u'connect_server', self.__Connect ), (u'disconnect_server', self.__DisConnect ), (u'log_in', self.__Login ), (u'log_out', self.__Logout ), (u'invite_friend', self.__InviteFriend), (u'send_message', self.__SendMessage ), ] self.__interface = { Chip.TYPE_IN_API : inAPIList, Chip.TYPE_OUT_EVENT: None, } return self.__interface def _PowerOn(self): self._eHandler = self.__interface[Chip.TYPE_OUT_EVENT] def __Connect(serverHost, serverPort): pass def __DisConnect(serverHost, serverPort): pass def __Login(username, password): pass def __Logout(): pass def __InviteFriend(friendName): ... self.__MessageReceiveThread() ... def __SendMessage(message): pass def __MessageReceiveThread(): while(True): ... message = xxx self._eHandler(u'evt_message_arrived', message) ... class LoginWindow(Chip): def __init__(self, chipID): Chip.__init__(self, chipID) def _DefineInterface(self): outAPIList = [ u'log_in', u'log_out', ] inEventList = [ (u'evt_connect_succeeded', self.__evtOnConnectSucceeded), (u'evt_chat_closed', self.__evtOnChatClosed ), ] self.__interface = { Chip.TYPE_OUT_API : outAPIList, Chip.TYPE_INT_EVENT: inEventList, Chip.TYPE_OUT_EVENT: None, } return self.__interface def _PowerOn(self): self._eHandler = self.__interface[CHIP.TYPE_OUT_EVENT] apiMap = self._DefineInterface[CHIP.TYPE_OUT_API] self.__apiLogin = apiMap[u'log_in'] self.__apiLogout = apiMap[u'log_out'] def __evtOnConnectSucceeded(self): self.Show() def __evtOnChatClosed(self): self.__apiLogout() self._eHandler(u'evt_logout_done') def __OnLoginButtonPressed(self): username = xxx.GetValue() password = xxx.GetValue() succeeded = self.__apiLogin(username, password) if not succeeded: self._eHandler(u'evt_login_failed') return self._eHandler(u'evt_login_succeeded') self.Hide() class ChatWindow(Chip): def __init__(self, chipID): Chip.__init__(self, chipID) def _DefineInterface(self): outAPIList = [ u'invite_friend', u'send_message', u'log_out', u'disconnect_server', ] inEventList = [ (u'evt_login_succeeded', self.__evtOnLoginSucceeded ), (u'evt_message_arrived', self.__evtOnMessageReceived), ] self.__interface = { Chip.TYPE_OUT_API : outAPIList, Chip.TYPE_IN_API : inEventList, Chip.TYPE_OUT_EVENT: None, } return self.__interface def _PowerOn(self): self._eHandler = self.__interface[CHIP.TYPE_OUT_EVENT] apiMap = self._DefineInterface[CHIP.TYPE_OUT_API] self.__apiInvite = apiMap[u'invite_friend'] self.__apiSendMsg = apiMap[u'send_message'] self.__apiLogout = apiMap[u'log_out'] self.__apiDisconnect = apiMap[u'disconnect_server'] def __evtOnLoginSucceeded(self): self.Show() def __evtOnMessageReceived(self, message): xxx.ShowText(message) def __OnInviteButtonPressed(self): friendName = xxx.GetValue() succeeded = self.__apiInvite(friendName, self.__OnMessageReceived) if not succeeded: self._eHandler(u'evt_invite_failed') return self._eHandler(u'evt_invite_succeeded') def __OnSendButtonPressed(self): message = xxx.GetValue() self.__apiSendMsg(message) def __OnWindowClosing(self): self._eHandle(u'evt_chat_closed')
在本系列的下一篇。我们将简要分析一下Softchip框架的意义。