- ActionScript 2
- ActionScript 3
- C ++
- C #
- ColdFusion
- Dart
- Haxe
- Java
- JavaScript
- Objective C
- Perl
- PHP
- Python
- Ruby
- Model和Proxy: Model保存Proxy的引用,Proxy負責操作Model中都數據,使Model複用性更高
- View和Mediator: View保存Mediator引用,Mediator操作視圖組件,處理UI事件
- Controller和Command: Controller中保存了Command的映射,Command主要控制業務邏輯
Model, View和Controller之間的通訊並沒有使用平臺相關的UI事件機制,而使用了觀察者模式。其中:
- Mediator可以發送和處理Notification
- Proxy只能發送Notification
- Notification也可以觸發Command
PureMVC提供了一個Facade類封裝了對Model,View和Controller了的訪問。Facade也負責Model,view和Contoller的初始化以及Proxy,Mediator和Command的註冊。
下面是一個PyQt4的demo,實現一個簡單的計算器:
Facade是個單例,在初始化方法中註冊兩個Command。StartUpCommand 註冊Proxy和Mediator,ButtonPressedCommand調用model的計算方法
main.py:
class AppFacade(Facade):
START_UP = 'facade.start_up'
INPUT = 'facade.input'
@staticmethod
def getInstance():
return AppFacade()
'''register command to controller'''
def initializeFacade(self):
super(AppFacade, self).initializeFacade()
self.registerCommand(AppFacade.START_UP, controller.StartUpCommand)
self.registerCommand(AppFacade.INPUT, controller.ButtonPressedCommand)
Controller.py
class ButtonPressedCommand(SimpleCommand):
def execute(self, note):
calcService = self.facade.retrieveProxy(model.CalcProxy.NAME)
calcService.calc(note.getBody())
class StartUpCommand(SimpleCommand):
def execute(self, note):
appDialog = note.getBody()
'''register mediator, connect app dialog with mediator'''
self.facade.registerMediator(view.CalcMediator(appDialog ))
'''register proxy'''
self.facade.registerProxy(model.CalcProxy())
View中處理UI事件和發出Notification, 觸發Controller中對應的Command
view.py
class CalcMediator(Mediator):
NAME = 'CalcMediator'
def __init__(self, widget):
super(CalcMediator, self).__init__(self.NAME,widget)
QtCore.QObject.connect(self.viewComponent, QtCore.SIGNAL('buttonPressed'), self.buttonPressed)
'''list of notification name, override'''
def listNotificationInterests(self):
return [
model.CalcProxy.UPDATE_SCREEN
]
'''handle notification'''
def handleNotification(self, note):
if (note.getName() == model.CalcProxy.UPDATE_SCREEN):
self.viewComponent.screenLable.setText(note.getBody())
'''slot'''
def buttonPressed(self, text):
screenValue = self.viewComponent.screenLable.text()
if ('=' == text):
self.sendNotification(main.AppFacade.INPUT, screenValue, None)
else:
if screenValue != '0':
screenValue += text
else:
screenValue = text
self.viewComponent.screenLable.setText(screenValue)
model中實現計算,完成後發出更新UI的通知:
model.py
class CalcProxy(Proxy):
NAME = 'CalcProxy'
UPDATE_SCREEN = 'model.update'
def __init__(self, data = None):
super(CalcProxy, self).__init__(self.NAME, data)
def calc(self, string):
string = str(string)
'''int to flot'''
if string.find('.') == -1 :
string += '.'
'''remove 0, in the end of result if it's integer, e.g: 15.0'''
result = eval(string)
if (result == int(result)):
result = int(result)
self.sendNotification(CalcProxy.UPDATE_SCREEN, str(result), None)
其它資料:
PureMVC:http://www.puremvc.org
實戰PureMVC:http://www.ibm.com/developerworks/cn/java/j-lo-puremvc/index.html
PyQt:http://www.riverbankcomputing.co.uk/software/pyqt/intro
Qt Calculator Example:
http://doc.qt.nokia.com/4.7-snapshot/widgets-calculator.html