-
Think in (Pure)MVC
How do I start using PureMVC? Short answer: Just think in (Pure)MVC! As its named says, PureMVC based on the classic Model-View-Controller design meta-pattern. Using the Facade-pattern you don’t instantiate the core actors directly, but every member of PureMVC has its own and clear defined role:
- Proxies = Model- Mediator and its ViewComponents = View
- Commands = Controller
用(Pure)MVC的思想去思考
我应该如何开始使用(Pure)MVC呢?,一句话:用(Pure)MVC的思想去思考! 从它的名字中就可以看出, PureMVC 是基于一般的 Model-View-Controller 元设计模式的.使用Facade-pattern 这种模式你不需要直接instantiate the core actors, 但是PureMVC中的每个Class都有它自己的定义很清楚的角色:
- Proxies = Model
- Mediator and its ViewComponents = View
- Commands = Controller -
Create an API for View Components
A View Component might be a standard UI component (e.g.
DataGrid
) or a custom component (e.g. a world within a game) or whatever. Don’t use its public methods directly. In order to change its state or behavior create an API.One of the advantage of PureMVC is to be neutral to the technologies being used. An example: I’ve built a “pure” Flash application based on PureMVC without using the Flex Framework. The same app will be ported to an AIR application for using AIR’s great File system API. The View Components have to be changed using the Flex Framework, but not the Mediators or any other actors of PureMVC.
为View Components创建API
一个 View Component可能是一个标准的UI component (比如DataGrid) 或者自定义组件 (比如一个游戏世界) 或者其他的东西. 不要直接使用它的 public方法. 而是把改变它的状态或者行为(等允许被外部调用的各种方法属性)写成API. PureMVC 的一个有点就是可以与所使用的技术无关. 举个例子:我建了一个基于PureMVC的'Pure' Flash application ,没有用到Flex Framework. 而后,为了使用AIR里面的File System API这个Application被转成一个AIR application.这时只需将View Components转化为使用 Flex Framework即可, 其他的Mediators 或者任何PureMVC中的任何actors均不需改变 . -
Use one Mediator for multiple View Components
To coordinate more than one View Component closely, use one Mediator only. In other words: Not all Views need a Mediator. For example: Assume a
ApplicationControlBar
containing aTextInput
, and aButton
or something else. Then create just one Mediator for theApplicationControlBar
calledApplicationControlBarMediator
and refer to the missing components casted as a second, third, etc. View Component.
多个View Components共同使用一个Mediator
为了紧密协调多个View Components 仅使用一个Mediator. 换句话说: 不是所有的Views 都需要Mediator. 例如: 有一个ApplicationControlBar,其中包含一个TextInput ,一个Button 或者其他的组件. 然后为ApplicationControlBar 创建一个名为ApplicationControlBarMediator的 Mediator 并且把它指定给ApplicationControlBar中所包含的所有View Component. -
Let’s Events bubble up
What happens if you don’t want to use multiple View Components within a Mediator? In order to handle user interactions with multiple View Components let’s bubble Events from the nested children of a View Component up.
For example: Clicking any Button within a View Component will fired up a custom Event which the Mediator is listen to. So the Mediator don’t have to know about the existing Button or about any other child of its View Component, just about the custom Event bubbled up.
让Events bubble up起来
如果你不想在一个Mediator中用多个View Components 又会怎样呢?为了处理多个 View Components的用户交互事件, 我们必须把View Component里面嵌套的所有组件的事件bubble up起来.
例如: 当你点击View Component 里面的任意Button都会触发Mediator监听的一个自定义事件. 所以Mediator并不需要知道这个Button是否存在或者任何一个这个 View Component的其他Child,它只需要知道这个事件已经被触发了就可以. -
Communicate using Notifications as often as possible
Notifications are the “Events” of PureMVC. For communicating between the three tiers Model, View and Controller use Notifications for the following scenarios as often as possible:
(communication from -> to)
- Mediator -> Proxy (via mapped Commands)
- Proxy -> Mediator
- Proxy -> Command
- Commands -> MediatorEven if it’s possible to retrieve a Proxy from a Mediator, don’t change the Proxy from a Mediator directly rather than sending a Notification using a mapped Command. It’s a bad practice to change a Proxy (Model) from a Mediator (View) directly without using a Command (Controller).
尽可能地的用Notifications通信
Notifications是PureMVC 里面的“Events” . 当Model, View and Controller 三者之间的通信是下面几种情况时应该尽可能地的使用这个Notifications :
(通信 from -> to)
- Mediator -> Proxy (via mapped Commands)
- Proxy -> Mediator
- Proxy -> Command
- Commands -> Mediator
即使可以从Mediator获得Proxy,也不要直接用Mediator来改变Proxy.应该是用一个mapped Command来发送Notification. 不通过使用Command (Controller)而用Mediator (View)来直接改变 Proxy (Model) 是一种非常糟糕的方法. -
Use Commands / MacroCommands as often as possible
Commands are doing the job at the Controller side: Retrieving and interacting Proxies, communicating with Mediators or executing other Commands. Even if a Command used only once or it has only two lines of code, use it as often as possible. To execute a Command once again anywhere or anytime within your application, you have to send just a Notification. In the future it’s easy to enlarge the Command with more complex actions. And - that’s very important - you always know, who the actor for changing the Proxy (Model) is.
Question: Have you had to execute more than one Command in a particular order? Use MacroCommands to execute multiple SubCommands (which means “simple” Commands) sequentially.
尽可能多的使用 Commands / MacroCommands
Commands 在控制端做这些工作: Retrieving and interacting Proxies, 与Mediators通信或者执行其他Commands. 即使一个Command仅被用了一次或者只有两行代码也要尽可能多的使用它. 为了在你的Application中可以随时随地的再次执行一个Command ,仅需发送一个Notification.以后也可以很容易的用更复杂的actions来扩展这个 Command. 还有非常重要的一点就是你总是知道改变Proxy (Model)的actor是哪一个.
问题: 你也没有遇到过需要按照特定次序执行多个Command的情况呢? 使用MacroCommands可以顺序执行多个SubCommands (也就是 “简单” Commands) . -
Use Remote Proxy to send and receive server-side data
To send and receive data between the application tier use Proxies called
Remote Proxies
. That’s not a special kind of a PureMVCProxy
, just a location based on aProxy
to organize the server calls such asHTTPServices
,RemoteObjects
or whatever.For example: To call a server-side
RemoteObject
to login a user create Proxy calledLoginProxy
. TheLoginProxy
does all the job to communicate with the server-side, which means sending and receiving data. Whenever you’ll change the server-side implementation for the LoginProcess, you’ll have to change one location within your application only - theLoginProxy
.
使用Remote Proxy来接收和发送服务端数据
在Application 中的发送和接收数据的Proxies 叫做“Remote Proxies”. 它不是一种特殊的PureMVC Proxy, 只是一个基于Proxy的location,而这个Proxy是负责处理比如HTTPSerivice,RemoteObject或者其他服务端调用的 Proxy.
例如: 为了调用服务器端一个负责登录用户的RemoteObject 而创建了一个叫做LoginProxy的Proxy. LoginProxy负责所有与服务器端通信的工作, 也就是接收和发送数据. 当你为LoginProcess改变服务器端执行操作时,你值需要改变Application中的一个locationt即可,即 LoginProxy. -
Remove unused Mediators
In some cases you don’t use a Mediator and its View Components anymore. Then remove the Mediator using
facade.removeMediator(MyMediator.NAME);
in conjunction with a self createddestroy()
method to remove the ViewComponent including all listeners, timer, references, etc. for a successful garbage collection.
去掉没有用到的Mediators
在某些情况下你不再使用一个Mediator和它的View Components. 你应该用facade.removeMediator(MyMediator.NAME)去掉这个Mediator同时用 destroy()来去掉包含所有listeners,timer,references的ViewComponent.以便更好的进行 垃圾回收. -
The Power of VO’s (Value Objects)
The place to store data within the Model are the Proxies - that’s right. The View Components have no need to know the Facade and the rest of the PureMVC application - that’s right, too. This means that the View Component has no access to the Model data directly.
To avoid this issue store within the View Component a reference to the data using Value Objects (VO’s). The VO’s are not a core actor of PureMVC and in conjunction with the Data Binding feature of Flex are a powerful way to react changes in the Model data without breaking rules.
去掉没有用到的Mediators
在某些情况下你不再使用一个Mediator和它的View Components. 你应该用facade.removeMediator(MyMediator.NAME)去掉这个Mediator同时用 destroy()来去掉包含所有listeners,timer,references的ViewComponent.以便更好的进行 垃圾回收. -
Courseware available
Cliff Hall has done an awesome job: You’ll find not only excellent documentations about the “Framework Overview“, “Best Practices” and a “Conceptual Diagram“,
also a very, very, very helpful Courseware. Check it out!
可以找到的课件
Cliff Hall 做个一个值得敬畏的工作: 不仅有非常好的文档 “Framework Overview“, “Best Practices” and a “Conceptual Diagram“, 而且还有非常非常有用的 课件. 自己去看看吧!