MVC,MVP,MVVM(model-view-viewModel
一.What is MVC
- A model is an object representing data or even activity, e.g. a database table or even some plant-floor production-machine process.
- A view is some form of visualization of the state of the model.
- A controller offers facilities to change the state of the model. ( Control即输入)
Input --> Processing --> Output
Controller --> Model --> View
A model encapsulates more than just data and functions that operate on it. A model is meant to serve as a computational approximation or abstraction of some real world process or system. It captures not only the state of a process or system, but how the system works. This makes it very easy to use real-world modeling techniques in defining your models. For example, you could define a model that bridges your computational back-end with your GUI front-end. In this scenario, the model wraps and abstracts the functionality of a computation engine or hardware system and acts as a liaison requesting the real services of the system it models.
The [view or viewport] is responsible for mapping graphics onto a device. A viewport typically has a one to one correspondence with a display surface and knows how to render to it. A viewport attaches to a model and renders its contents to the display surface. In addition, when the model changes, the viewport automatically redraws the affected part of the image to reflect those changes. There can be multiple viewports onto the same model and each of these viewports can render the contents of the model to a different display surface.
A controller is the means by which the user interacts with the application. A controller accepts input from the user and instructs the model and viewport to perform actions based on that input. In effect, the controller is responsible for mapping end-user action to application response. For example, if the user clicks the mouse button or chooses a menu item, the controller is responsible for determining how the application should respond.
MVC特征:
1. 可以为一个Model提供不同的多个视图View表现形式,也可以为一个模型创建新的视图而不需重写模型。模型的改变能影响视图。
MVC要求当我们改变model,不需要改变view, view是自动更新的。
这个通常是个observe 模式,一个对象的改变能影响另一些对象,而这对象不需要知道这些被影响对象的细节。
2. 视图可以嵌套。例如一个对象查看器的用户界面可以由嵌套的视图来构成,而这些视图又可以复用于其它地方。
一般可以使用composite 模式的CompositeView,包含一个类层次结构,这个层次里的成员可以是一个原子对象:button,也可以是由原子对象组合成的compositeView.
3. 允许在不改变视图的外观下改变视图对用户输入的响应方式。
MVC 将响应方式封装在controller中,一个view的响应策略对应一个具体的controller子类,可以方便的对这个controller进行改变或者替换,view-controller的关系可以用strategy 模式来包装。
(MFC 可以理解为这样吗?
- Document = Model: Stores the domain data and logic
- View = View
- CFrameWnd = Controller: CFrameWnd dispatches window messages and you implement methods here to alter Model and View based on the message received such as a keyboard or mouse message. )
+------------+
| Model |
+------------+
/| . /|
/ . \
/ . \
/ . \
/ |/ \
+------------+ <------ +------------+
| View | | Controller |
+------------+ ......> +------------+
Model指向view的箭头是一个弱类型(weak-type)的引用,model通过它来通知view端改变,只需要view的一个基类,
而不需要具体类。View 需要model的具体类,一个强类型(strong-type)引用,允许view调用model的任何数据处理函数。
View有一个弱类型引用controller, view应该只能调用controller基类的函数,因为我们可能要换掉controller,必须保证最小依赖。
Controller有着强类型的model和view指针,因为controller定义三者的动作,它要将user input 转变成application response.
(Controller不改变view,而是通过改变model, model通过observable 模式改变view, Flow Synchronization and Observer Synchronization的区别。
http://martinfowler.com/eaaDev/uiArchs.html
Observable的缺点:很难通过读代码来知道在做什么,只有调试,一步一步来。
MVC.
- Make a strong separation between presentation (view & controller) and domain (model) - Separated Presentation.
- Divide GUI widgets(窗口) into a controller (for reacting to user stimulus) and view (for displaying the state of the model). Controller and view should (mostly) not communicate directly but through the model.
- Have views (and controllers) observe the model to allow multiple widgets to update without needed to communicate directly - Observer Synchronization.
Calculating the variance between actual and target is domain(Model?) behavior, it is nothing to do with the UI. As a result following Separated Presentation says we should place this in the domain layer of the system - which is exactly what the reading object represents. When we look at the reading object, the variance feature makes complete sense without any notion of the user interface.
困难:
There's two areas where I've skipped over some awkward points that get in the way of MVC theory. The first problem area is to deal with setting the color of the variance. This shouldn't really fit into a domain(Model?) object, as the color by which we display a value isn't part of the domain. The first step in dealing with this is to realize that part of the logic is domain logic. What we are doing here is making a qualitative statement about the variance, which we could term as good (over by more than 5%), bad (under by more than 10%), and normal (the rest). Making that assessment is certainly domain language, mapping that to colors and altering the variance field is view logic. The problem lies in where we put this view logic - it's not part of our standard text field.
This kind of problem was faced by early smalltalkers and they came up with some solutions. The solution I've shown above is the dirty one - compromise some of the purity of the domain in order to make things work
看来mvc的问题是有些view logic与view state不能放到model 中去?
VisualWorks Application Model(有点像下面的 MVV)
The main difference between using an application model and classic MVC is that we now have an intermediate class between the domain model class (Reader) and the widget - this is the application model class. The widgets don't access the domain objects directly - their model is the application model. Widgets are still broken down into views and controllers, but unless you're building new widgets that distinction isn't important.
A Property Object changes this by having the property return an object that wraps the actual value. So in VisualWorks when we ask for a name we get back a wrapping object. We then get the actual value by asking the wrapping object for its value. So accessing a person's name would use temp = aPerson name value
and aPerson name value: 'martin'
中间插入一个Application model在view与model之间,我觉得实质上就是view model.
So now the soundbites on Application Model
- Followed MVC in using Separated Presentation and Observer Synchronization.
- Introduced an intermediate application model as a home for presentation logic and state - a partial development of Presentation Model.
- Widgets do not observe domain objects directly, instead they observe the application model.
- Made extensive use of Property Objects to help connect the various layers and to support the fine grained synchronization using observers.
- It wasn't the default behavior for the application model to manipulate widgets, but it was commonly done for complicated cases.
二.MVC in WPF
(http://www.orbifold.net/default/?p=550)
Wpf实现MVC的问题:
1. Declarative programming,例如xaml, 节省了很多代码,如databinding,triggers和events.这些原来这些应该在controller做的。
2. MVC中view从model中获得数据展示,WPF有可能通过value converter,observalbelcollection 来更新presentation.
3. 使用 controls in WPF 允许定义能被override的默认样式,generic.xaml,这样也增加了model展示的灵活性。
4. 更多的更大范围的机制来响应用户动作,如ICommand, triggers, animations,event bubbling or tunning.
(一个Model/View/ViewModel architecture构架)
Model: 用来包装数据,让wpf容易访问。其所有的public API应该是只能在UI thread中调用,就是界面操作。对数据的应该尽量实现INotifyPropertyChanged或者INotifyCollectionChanged. 当获取数据代价高时,它将读取数据过程抽象出来,但是不能block UI线程。它有时候也包括组合多处数据的功能。
ViewModel: 其是一个view 对应的model。在这个构架中,用viewModel作为view的DataContext,这样可以方便的通过binding获得viewModel数据.这样也符合DataTemplate/Data 模式。理想状况下,view不需要code behind.只要xaml即可。
DataModel与ViewModel的界限可以比较模糊。DataModel主要在UI中以DataTemplate来实现,似乎与ViewModel区别不大。注意支持composition,ViewModel应该可以composite其他ViewModel或DataModel,DataModel应该可以composed of 其他dataModel.
ViewModel是View的Model, 我们需要用DataBind来把DataObject(model)的一个属性帮定到 ViewObject(view)的一个属性,但是有时候需要converting或者计算,这就是ViewModel的用处。Converter 和计算可以在viewModel中完成。。。
(注:controller怎么办?还是要定义事件处理,用户命令吧, view帮定viewModel的数据,而不是直接帮定model
Model: 用INotifyPropertyChanged能够bubble changes up the stack.其公有函数必须在UI 线程上,这是因为model可能会运行些代价很高的操作从而诸塞UI。(Dispather.beginInvoke()).
In MVC, it is a view's responsibility to display the data held by a model object. A controller can be
used to determine how low-level user gestures are translated into actions on the model.
Generally, a view and controller are directly linked together (usually by an instance variable pointing from one to the other) but a
view/controller pair is only indirectly linked to the model. By “indirect”, I mean that an Observer
relationship1 is set up so that the view/controller pair knows about the existence of the model but not
vice versa. The advantage of this comes because it is then possible to connect multiple
views/controller pairs to the same model so that several user interfaces can share the same data.
Unfortunately, it is the nature of this indirect link that causes the problems with MVC.
因为mvc的model无法成为纯model,它还是要有view中的一些数据结构(application logic),而它又没有对view的直接引用,是用observable 的通知机制,这样就考虑到了MVP结构。
In MVC, most of the application functionality must be built into a model class known as an
Application Model (see figure 1). It is the responsibility of the application model to be the mediator
between the true domain objects and the views and their controllers. The views, of course, are
responsible for displaying the domain data while the controllers handle the raw user gestures that will
eventually perform actions on this data. So the application model typically has methods to perform
menu command actions, push buttons actions and general validation on the data that it manages.
Nearly all of the application logic will reside in the application model classes. However, because the
application model’s role is that of a go-between, it is at times necessary for it to gain access to the user
interface directly but, because of the Observer relationship between it and the view/controller, this
sort of access is discouraged.
三.MVP
The Model
This is the data upon which the user interface will operate. It is typically a domain object and the
intention is that such objects should have no knowledge of the user interface. Here the M in MVP
differs from the M in MVC. As mentioned above, the latter is actually an Application Model, which
holds onto aspects of the domain data but also implements the user interface to manipulate it. In
MVP, the model is purely a domain object and there is no expectation of (or link to) the user interface
at all.
The View
The behaviour of a view in MVP is much the same as in MVC. It is the view's responsibility to display
the contents of a model. The model is expected to trigger appropriate change notifications whenever
its data is modified and these allow the view to "hang off" the model following the standard Observer
pattern. In the same way as MVC does, this allows multiple views to be connected to a single model.
One significant difference in MVP is the removal of the controller. Instead, the view is expected to
handle the raw user interface events generated by the operating system (in Windows these come in as
WM_xxxx messages) and this way of working fits more naturally into the style of most modern
operating systems. In some cases, such as a TextView, the user input is handled directly by the view
and used to make changes to the model data. However, in most cases the user input events are
actually routed via the presenter and it is this which becomes responsible for how the model gets
changed 5.
The Presenter(即管对model的更新,又放置一些application logic,相当于application model)
While it is the view’s responsibility to display model data it is the presenter that governs how the
model can be manipulated and changed by the user interface. This is where the heart of an
application's behaviour resides. In many ways, a MVP presenter is equivalent to the application model
in MVC; most of the code dealing with how a user interface works is built into a presenter class. The
main difference is that a presenter is directly linked to its associated view so that the two can closely
collaborate in their roles of supplying the user interface for a particular model.
Presenter应该是兼顾view model和business model, 传统的presenter 有对view的指针,但是WPF把这个也可以取消掉,而用binding来实现presenter 与view的通讯, 例如在presenter定义一个DP或者继承了INotifiyProperty的普通属性,这个属性与view中一个DP绑定,当presenter属性中变化后,view中DP的changed Call back能够进行相应的操作)
Benefits of MVP
So the effect of this "twist" is that the presenter, where the data manipulation part of a user interface
is handled, is also allowed direct access to the view, where the data display is implemented. This can
be very handy at times and is one of the most obvious benefits over MVC where the application
model only has an indirect link to its associated view. The Dolphin implementation of MVP also
manages to dispense with the idea of a controller, which seems to make the framework "fit" better
with the underlying Windows operating system.
Compared with our original widget framework, MVP offers a much greater separation between the
visual presentation of an interface and the code required to implement the interface functionality. The
latter resides in one or more presenter classes that are coded as normal using a standard class browser.
The window layouts for most applications are created using a tool known as the View Composer
which is used to create an instance of the view required6. These view instances are held in an internal
binary form by a Resource Manager. Normally, one or more view instances can be associated with any
Presenter class and a presenter can specify which particular view is required when it is launched.
Hence it is easy for an MVP application to have one or more "skins" that can be selected as required.
For example, the Dolphin development environment has three versions of the standard Class
Hierarchy Browser which are all driven by the same ClassBrowserShell presenter class. We have the
standard browser view, a simplified version for beginners (offering fewer options) and an alternative
version where the class hierarchy is represented as a diagram rather than a standard tree view. This
level of flexibility would not be possible with a framework based solely on widgets.
The first element of Potel is to treat the view as structure of widgets, widgets that correspond to the controls of the Forms and Controls model and remove any view/controller separation. The view of MVP is a structure of these widgets. It doesn't contain any behavior that describes how the widgets react to user interaction.
The active reaction to user acts lives in a separate presenter object. The fundamental handlers for user gestures still exist in the widgets, but these handlers merely pass control to the presenter.
The presenter then decides how to react to the event. Potel discusses this interaction primarily in terms of actions on the model, which it does by a system of commands and selections. A useful thing to highlight here is the approach of packaging all the edits to the model in a command - this provides a good foundation for providing undo/redo behavior.
As the Presenter updates the model, the view is updated through the same Observer Synchronization approach that MVC uses.
Here are the MVP soundbites:
- User gestures are handed off by the widgets to a Supervising Controller.
- The presenter coordinates changes in a domain model.
- Different variants of MVP handle view updates differently. These vary from using Observer Synchronization to having the presenter doing all the updates with a lot of ground in-between.(http://martinfowler.com/eaaDev/uiArchs.html)
(MVP的演变Potel):