书接上回。在展示了App最顶层的代码后,我们去看看各模块怎样编程。

为了能看懂各模块的代码,首先须要铺垫一下Softchip架构的基本概念和设计规范。

1、随意模块不持有其它模块的实例。自然不再显式使用句柄调用不论什么方法。

这意味着模块之间不存在编码期和编译期的耦合。

2、每一个模块在形式上仅仅与Machine之间存在接口。该接口以APIEvent两种形态存在。

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框架的意义。

Python演绎的精彩故事(二)的更多相关文章

  1. 进击的Python【第五章】:Python的高级应用(二)常用模块

    Python的高级应用(二)常用模块学习 本章学习要点: Python模块的定义 time &datetime模块 random模块 os模块 sys模块 shutil模块 ConfigPar ...

  2. Python开发【第二十二篇】:Web框架之Django【进阶】

    Python开发[第二十二篇]:Web框架之Django[进阶]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...

  3. Python编程核心内容之二——切片、迭代和列表生成式

    Python版本:3.6.2  操作系统:Windows  作者:SmallWZQ 最近太忙啦.很多事情需要自己处理,感觉时间不够用啊~~~~今后,博客更新时间可能会慢下来,哈哈,正所谓"人 ...

  4. 使用Python的库qrcode生成二维码

    现在有很多二维码的生成工具,在线的,或者安装的软件,都可以进行生成二维码.今天我用Python的qrcode库生成二维码.需要预先安装  Image 库 安装 用pip安装 # pip install ...

  5. redis学习 (key)键,Python操作redis 键 (二)

    # -*- coding: utf-8 -*- import redis #这个redis 连接不能用,请根据自己的需要修改 r =redis.Redis(host=") 1. delete ...

  6. Python 简单入门指北(二)

    Python 简单入门指北(二) 2 函数 2.1 函数是一等公民 一等公民指的是 Python 的函数能够动态创建,能赋值给别的变量,能作为参传给函数,也能作为函数的返回值.总而言之,函数和普通变量 ...

  7. Python 多线程、多进程 (二)之 多线程、同步、通信

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...

  8. python创建与遍历List二维列表

    python创建与遍历List二维列表 觉得有用的话,欢迎一起讨论相互学习~Follow Me python 创建List二维列表 lists = [[] for i in range(3)] # 创 ...

  9. python中的类(二)

    python中的类(二) 六.类的成员 字段:普通字段,静态字段 eg: class Province(): country=’中国’ #静态字段,保存在类中,执行时可以通过类或对象访问 def __ ...

随机推荐

  1. .NET重构(七):VS报表的制作

    导读:机房做到最后阶段,就是报表的制作了.想到第一次,是借助外部控件进行实现的,这次采用VS进行编写,在这个软件中,有自带的报表编辑工具,更加的方便和简洁,现在就对这一块的学习,进行总结. 一.报表制 ...

  2. BZOJ 3230 相似子串 ——后缀数组

    题目的Source好有趣. 我们求出SA,然后求出每一个后缀中与前面本质不同的字符串的个数. 然后二分求出当前的字符串. 然后就是正反两次后缀数组求LCP的裸题了. 要注意,这时两个串的起点可能会相同 ...

  3. UVA 11297 Census ——二维线段树

    [题目分析] 二维线段树模板题目. 简直就是无比的暴力.时间复杂度为两个log. 标记的更新方式比较奇特,空间复杂度为N^2. 模板题目. [代码] #include <cstdio> # ...

  4. P2016 战略游戏 (树形DP)

    题目描述 Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题. 他要建立一个古城堡,城堡中的路形成一棵树.他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能 ...

  5. 【2018.10.1】「JOI 2014 Final」年轮蛋糕

    题面 一看到求“最小值的最大值”这种问题,就能想到二分了. 二分答案,然后我们要把一圈分成三块,使这三块的大小都$\geq mid$.做法是把环展开成2倍长度的链,先钦定一个起点,然后根据前缀和再二分 ...

  6. eclipse导入svn检出的maven项目问题

    1.修改项目jdk环境和编译环境.消除红叉. 2.windows-preferences-java-installed jres,修改工作空间的jdk,在Default vm arguments栏中添 ...

  7. farm

    farm 时间限制:C/C++ 4秒,其他语言8秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 White Rabbit has ...

  8. Dreamweaver8中文版视频教程 [爱闪教程]Dreamweaver8中文版

    原文发布时间为:2008-07-30 -- 来源于本人的百度文章 [由搬家工具导入] http://www.176net.com/shipin/UploadFiles_1476/teach1/%5B% ...

  9. mongodb的入门CURD

    mongodb的入门CURD #查看所有数据库show dbs;show databases; #有些版本可能不行 #使用数据库use 数据库名 #查看集合(集合即mysql的表)show table ...

  10. Java 并发编程中的 CountDownLatch 锁用于多个线程同时开始运行或主线程等待子线程结束

    Java 5 开始引入的 Concurrent 并发软件包里面的 CountDownLatch 其实可以把它看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器,也就是 ...