python编程(基于订阅模式的mvc实现)
2017-12-27 23:39
120 查看
【声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
基于mvc方式开发的客户端软件很多,但是用订阅方式实现mvc,我今天还是第一次看到。今天看到一篇英文文献,十分有意思,原有链接在这。
现在假设有两个页面,一个页面要存钱、取钱,另外一个要显示。当然,这中间少不了controller和model,看看链接中的code是怎么处理mvc关系的。
首先是model和controller代码,也是应用的入口代码,
然后是一个显示窗口的代码,
最后是存钱、取钱窗口的代码,
通过这一些类的操作,大家可以看一下整个消息流是怎么从money_changing变成money_changed流程的。
当然,这里没有给出publish-subscrib的代码,没关系,我们可以看另外一种简单的实现办法,或许对我们有所触动。
大家可以利用这个案例好好思考一下mvc是如何利用publish-subscribe的方式将他们串在一起的。目前在wxpython中可以直接调用这个类,比如
基于mvc方式开发的客户端软件很多,但是用订阅方式实现mvc,我今天还是第一次看到。今天看到一篇英文文献,十分有意思,原有链接在这。
现在假设有两个页面,一个页面要存钱、取钱,另外一个要显示。当然,这中间少不了controller和model,看看链接中的code是怎么处理mvc关系的。
首先是model和controller代码,也是应用的入口代码,
""" Adapted from wxPython website at http://wiki.wxpython.org/ModelViewController/. :copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. :license: BSD, see LICENSE.txt for details. """ import wx from pubsub import pub print('pubsub API version', pub.VERSION_API) # notification from pubsub.utils.notification import useNotifyByWriteFile import sys useNotifyByWriteFile(sys.stdout) # the following two modules don't know about each other yet will # exchange data via pubsub: from wx_win1 import View from wx_win2 import ChangerWidget class Model: def __init__(self): self.myMoney = 0 def addMoney(self, value): self.myMoney += value # now tell anyone who cares that the value has been changed pub.sendMessage("money_changed", money=self.myMoney) def removeMoney(self, value): self.myMoney -= value # now tell anyone who cares that the value has been changed pub.sendMessage("money_changed", money=self.myMoney) class Controller: def __init__(self): self.model = Model() # set up the first frame which displays the current Model value self.view1 = View() self.view1.setMoney(self.model.myMoney) # set up the second frame which allows the user to modify the Model's value self.view2 = ChangerWidget() self.view1.Show() self.view2.Show() pub.subscribe(self.changeMoney, 'money_changing') def changeMoney(self, amount): if amount >= 0: self.model.addMoney(amount) else: self.model.removeMoney(-amount) if __name__ == "__main__": app = wx.App() c = Controller() sys.stdout = sys.__stdout__ print('---- Starting main event loop ----') app.MainLoop() print('---- Exited main event loop ----')
然后是一个显示窗口的代码,
""" :copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. :license: BSD, see LICENSE.txt for details. """ import wx from pubsub import pub class View(wx.Frame): def __init__(self, parent=None): wx.Frame.__init__(self, parent, -1, "Main View") sizer = wx.BoxSizer(wx.VERTICAL) text = wx.StaticText(self, -1, "My Money") ctrl = wx.TextCtrl(self, -1, "") sizer.Add(text, 0, wx.EXPAND | wx.ALL) sizer.Add(ctrl, 0, wx.EXPAND | wx.ALL) self.moneyCtrl = ctrl ctrl.SetEditable(False) self.SetSizer(sizer) # subscribe to all "MONEY CHANGED" messages from the Model # to subscribe to ALL messages (topics), omit the second argument below pub.subscribe(self.setMoney, "money_changed") def setMoney(self, money): self.moneyCtrl.SetValue(str(money))
最后是存钱、取钱窗口的代码,
""" Widget from which money can be added or removed from account. :copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. :license: BSD, see LICENSE.txt for details. """ import wx from pubsub import pub class ChangerWidget(wx.Frame): CHANGE = 10 # by how much money changes every time click def __init__(self, parent=None): wx.Frame.__init__(self, parent, -1, "Changer View") sizer = wx.BoxSizer(wx.VERTICAL) self.add = wx.Button(self, -1, "Add Money") self.remove = wx.Button(self, -1, "Remove Money") sizer.Add(self.add, 0, wx.EXPAND | wx.ALL) sizer.Add(self.remove, 0, wx.EXPAND | wx.ALL) self.SetSizer(sizer) self.add.Bind(wx.EVT_BUTTON, self.onAdd) self.remove.Bind(wx.EVT_BUTTON, self.onRemove) def onAdd(self, evt): print('-----') pub.sendMessage("money_changing", amount=self.CHANGE) def onRemove(self, evt): print('-----') pub.sendMessage("money_changing", amount=- self.CHANGE)
通过这一些类的操作,大家可以看一下整个消息流是怎么从money_changing变成money_changed流程的。
当然,这里没有给出publish-subscrib的代码,没关系,我们可以看另外一种简单的实现办法,或许对我们有所触动。
class Observable: def __init__(self, initialValue=None): self.data = initialValue self.callbacks = {} def addCallback(self, func): self.callbacks[func] = 1 def delCallback(self, func): del self.callback[func] def _docallbacks(self): for func in self.callbacks: func(self.data) def set(self, data): self.data = data self._docallbacks() def get(self): return self.data def unset(self): self.data = None
大家可以利用这个案例好好思考一下mvc是如何利用publish-subscribe的方式将他们串在一起的。目前在wxpython中可以直接调用这个类,比如
from wx.lib.pubsub import Publisher
相关文章推荐
- 基于WebForm实现Front Controller MVC模式
- 2.1、Spring Web MVC是什么 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职
- 基于事件的监听,消息订阅设计模式的实现框架,ERP,OA,复杂,灵活多变的项目的福音
- Struts——基于J2EE 的 web 形式 MVC 模式实现
- 基于spring-redis发布订阅模式的实现
- 基于dojo实现mvc 模式下的ajax应用
- ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现
- 基于订阅/发布模式的简易聊天室实现(java+redis)
- 基于.Net的发布订阅模式API的实现与详解(一)
- 基于Json.NET自己实现MVC中的JsonValueProviderFactory
- 演练:实现支持基于事件的异步模式的组件
- 《设计模式:基于C#的工程化实现及扩展》学习笔记 02 准备篇 -- Namespace(命名空间)
- 构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)
- 基于MVC的简单学生信息管理功能实现
- 《设计模式 基于C#的工程化实现及扩展》 - 书摘精要
- 构建基于MVC+Observer模式的、艺术性的移动开发框架(KJAVA版)(二)
- 发布订阅 - 基于A2DFramework的事件机制实现
- asp.net mvc简单实现基于Razor的分页控件
- 基于MVC+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出
- 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现