MVC vs. MVP vs. MVVM

An important FAQ. The answer actually depends on where the person is coming from. MVC is a fundamental pattern which has been tweaked quite a bit to fit into various platforms. For instance if you had asked anybody how to implement an MVC in ASP.NET (prior to release of ASP.NET MVC framework) you would get very different answers. So let’s start with basic. The common motivation behind all 3 is separation of concerns, cutting flab from UI (good for UI designers), swapping UIs (for instance windows to web), make UI easy for Unit Testing, etc. Have a look at the below diagram, I have taken it from CAB documentation.

MVCMVP

MVC: Three components – View (your UI), Model (your business entities / data – that view is displaying) & Controller (contains the logic that alters the model depending on the action triggered by UI, typically implementing a Use Case). It’s widely known that MVC is a compound pattern (View and Controller have Strategy implementation, View itself can be a Composite implementation & View and Model are synched through Observer). In this case Controller doesn’t know anything about View, and the idea is that a View can switch Controllers (for instance depending upon who has logged to the system) & a single controller can be used by multiple Views. View subscribes to the changes done to the model & hence both are sync from the data perspective. One of the disadvantages of MVC is that it’s difficult to unit test. Controller manipulates the data but how about asserting those changes from a view perspective. For instance on click of a button you raise an event to controller, and controller modifies the value in model. This value modification changes the font size / color in View. Unit testing this scenario is slightly difficult in MVC.

MVP: Again three components. But dependencies change (look at arrows in the diagram). Over here we replace Controller with Presenter (one which presents the changes done in model back to view). The main difference between both is that Presenter refers back to the view while Controller doesn’t. Normal pattern found here is to create an abstraction of the View (in terms of properties / events) & Presenter refers to it. This makes the mocking of View much easier & hence the Unit Testing aspect. Presenter here hence takes the responsibility of not only manipulating model but also updating the view. Of course the implementations of MVP differ in real world in terms of how much thin the view is, some prefer keeping basic logic still inside view & taking complex logic in presenter, while others prefer keeping the entire logic in Presenter. Martin fowler describes 2 variations on MVP on these lines namely – Supervising Controller & Passive View described below

(A Passive View handles this by reducing the behavior of the UI components to the absolute minimum by using a controller that not just handles responses to user events, but also does all the updating of the view. This allows testing to be focused on the controller with little risk of problems in the view.

Supervising Controller uses a controller both to handle input response but also to manipulate the view to handle more complex view logic. It leaves simple view behavior to the declarative system, intervening only when effects are needed that are beyond what can be achieved declaratively.)

MVVM: Model–View-ViewModel talks of creating a new model (in addition to your domain model). This model normally adds additonal properties from the prespective of View (as we understand that View has controls in addition to data which it’s displaying). For instance if View had a property IsChecked and Presenter was setting in classic MVP, in MVVM Presenter will have that IsChecked Property which View will sync up with (doesn’t it look like Strategy pattern has been replaced with Observer?). So now a Presenter becomes more like a combo of – View Properties & Model properties which would be synchronized with View. So why not rename Presenter to ViewModel? Do that and you get MVVM. MVVM is attractive for platforms which support bi-directional binding with less effort. Also a minor tradeoff is ViewModel unlike Presenter can stand on its own (Presenter normally requires a View’s interface). Martin fowler describes similar pattern called Presentation Model & Josh Smith captures MVVM implementation for WPF / Silverlight in this article.

MVVM

ASP.NET MVC: So what has MVC got to do with ASP.NET MVC? First, Web works on a different model. Here, user interacts with HTML in browser and send a request back to the server for processing (for client side Ajax you might go just for data). As the interaction is normally stateless, when the request comes back to the server we need to recreate our View, load the model back & manipulate both of them as required. There are 2 variations on how handle this recreation – Page Controller & Front Controller. Make Page the decision maker – in this widely implemented pattern HTTP request is specific to physical page on server (.aspx for instance) & page in turn creates itself (builds the view from postback data) decides what model it needs and triggers the manipulation (events in codebehind file) it requires. As you see here the distinction between View & Controller becomes blur & is little difficult to separate. This where ASP.NET MVC comes in which behaves like a Front Controller – where Controller is the decision maker. Here all HTTP requests are mapped to methods on the Controller Class. Controller class recreates the model & view as required and does the manipulations. This makes unit testing easier as we can directly instantiate the front controller class & invoke methods on it to perform the assertions.

I can add code snippets to above explanations if you feel they would help you understand things better. I will look forward to your comments :) .

 

MVC和MVP的一些思考

碧落

前言

这篇文章是我近期对MVC和MVP的一些思考,在使用MVC/MVP模式的过程中曾经走过一些弯路。呵呵,现在虽然改正了某些弯路,但不保证改正了所有的弯路(例如对渲染的理解),所以请阅读这篇文章的朋友不吝发挥你们的质疑。

写这篇文章也是想知道自己还有什么地方是错的,我的最终方案是否可行?

有交流才会有进步。你有一个苹果,我有一个苹果,我们交换后仍各有一个苹果,你有一个思想,我有一个思想,我们交换后......会有N个思想 :p

1. MVC的理解误区

以下是我以前对MVC模式的理解误区:

1. 认为Model是指失血模型的实体类(Entity),是作为ViewController之间的传输数据。

2. 把业务逻辑全部放在Controller端,认为Controller是用来写UI的业务逻辑的。

这两个误区本质上都是对Model的作用不明导致的。

Model在MVC架构中起的作用非常重要,它才是UI业务逻辑真正的实现层。所以Model的实际上是Business Model(业务模型)。

而Controller仅仅起一个“桥梁”作用,它负责把View的请求转发给Model,再负责把Model处理结束的消息通知View。Controller就是一个消息分发器。Controller是用来解耦View和Model的,具体一点说,就是为了让UI与逻辑分离(界面与代码分离)。

2. MVC与VCP的区别

MVC的View直接与Model打交道,Controller只转发请求(View的请求)和通知(Model处理完之后的通知),不传递数据(业务结果),而是由View直接向Model拿数据。

MVP的View不与Model直接联系,所有的请求、结果通知、数据传递都是通过Controller转发,View和Model彼此不知道对方的存在。

3. MVC与MVP的相同点

无论是MVC还是MVP,View和Controller都是紧密联系的,在WinForm模式下更显得突出,View和Controller直接绑定在一起了(在一个类里面)。

MVC/MVP都是通过“通知”机制(观察者模式,在C#中使用事件解决ViewController的交互。

4. MVP框架的设计

在MVP框架里,用Presenter代替MVC的Controller,而且View不再与Model交互。

4.1. Presenter

Presenter的作用比Controller大得多,Controller只是一个纯粹的消息分发器,而Presenter还负责传递Model的处理结果给View,并指导View的渲染。

注意,渲染我理解为UI的展现方式。

4.2. Presenter与Model

Presenter与Model使用接口隔离,Presenter直接调用Model的接口方法(比如IUserModel的FetchUserList()SaveUser())。

4.3. Presenter与View

View与Presenter的交互使用观察者模式,有两种方式实现:

1. View主动使用Presenter。

View主动构造Presenter,并在内部调用Presenter的方法。即先有View再有Presenter。这种情况下,View明确知道自己要使用哪些Presenter。

2. Presenter主动使用View。

Presneter主动创建View,View里面定义有一堆的事件,Presenter注册这些事件。这种情况下,View不知道自己会被哪些Presenter使用。

第二种方式比第一种方式耦合性低,但View里要写一堆的事件,Presenter类里要捕获一堆的事件,感觉写起来很烦琐,代码不雅观。

5. Controller/Presenter的意义

以下Controller/Presenter简称为C/P。

C/P存在的意义是为了解耦View和Model。如果C/P不存在的话,View就直接访问Model,而View的变化是频繁的,不同的系统,View的展现方式不一样,让Model去控制View的渲染,会降低Model的重用性。如果Model不管View的渲染,由View自己渲染,那么就是WinForm的解决方式,即View和C/P经绑定(合并为一个类)。

6. 为什么要用MVC/MVP模式?

老实说,到目前为止,我依然看不出WinForm把Model分离之后,与标准的MVC/MVP有什麽差距。在WinForm分离Model之后,两者的交互可以用接口隔离,也可以用观察者模式让Form与Model一对多。再用IoC替代View直接构造Model的实例,那WinForm代表的View+C/P(Form)已经与Model完全解耦了,View+C/P层连Model层都不需要引用(但要引用IModel层)。

这里关键是使用IoC技术,否则WinForm确实会导致View与Model直接耦合,更换Model,或者改变Model的接口会导致View要修改。注意,我们分离出来的Model,并不完全是为了使UI与代码分离,我们更注重Model的重用性,力求一个Model被多个View享用,甚至是不同系统的View享用。这就要求我们改动View的渲染时不用改动Model,同样地,我们改动Model的内部逻辑时,也不影响View的渲染。

嗯,或许还有一点:View通过Controller/ Presenter交互,使得统可以有一个共同的“入口”,系统可以在入口处做拦截,利于日志和权限的处理。但我们可以用AOP技术替代C/P的入口。

7. 新方案

由此看来,IoC+AOP可以完全替代C/P,而且框架上更“干净”,开发人员写起来更自由。

一些零碎的想法,有什么错误的地方请大家多多指教,谢谢。

 

 

在我们深入理解这两者差异前让我们研究设计模式如何工作和更好使用两种( MVC设计与MVP )之一。 ( MVC设计与MVP )模式已使用了好几年,解决的一个关键问题即面向对象主要关注点,分离的用户界面和业务层。

还有一些框架,是目前使用的是基于这些模式包括: JAVA Struts, ROR, Microsoft Smart Client Software Factory (CAB), Microsoft Web Client Software Factory,

以及最近宣布ASP.Net MVC framework. 框架。

模型视图控制器( MVC设计)模式

 

在MVC模式是一个用户界面演示模式,重点是从业务层(Model)分离的用户界面(View) 。该模式在职责分开三部分组成:view 负责渲染UI元素  , 控制器controller 负责响应用户界面的行动,

该模型(Model)是负责业务的行为和状态管理。在大多数执行所有三个组成部分可以直接相互交流,在一些实施的控制器负责确定其中view显示(Front Controller Pattern) ,

模型认为主持人( MVP )模式

 

( MVP )模式 是一个在MVC模式基础上的概念MVC模式。模式职责分开四个部分组成:view 负责渲染UI元素,界面接口被用于解牛控制它的 (presenter)主持人, presenter 主

界面接口和服务层通常用来简化presenter和model模式的单元测试。

主要优点

在使用任何模式一开发商需要考虑的优点和缺点的后再使用它。有一些关键的优点 可决定使用MVP或MVC模式(见下面的列表) 。

但是,也有少数人提请审议支持。最大的缺点是额外的复杂性和学习曲线。虽然模式可能并不适合简单的解决方案;不过解决方案可以极大地受益于使用模式。

我体验是我用到了几个模式解决方案,模式消除了大量的复杂,但我正在重新考虑更好的使用模式。

 

松散耦合- presenter/controller在用户界面代码和模型 之间的扮演了中间人角色。这使得界面和模型 ,形成各自独立。

明确分开的问题/责任

1,view用户界面(表单或页面) -负责渲染U I元素

2,Presenter/controller主持人 -负责处理U I元素 事件和用户界面与模型 交互

3,model模型-负责业务行为和状态管理

测试驱动-通过孤立每一个主要component (用户界面,演示/控制器和模型)是比较容易写单元测试。尤其是当使用了MVP模式,这是为什么,Presenter只通过接口与view界面互交.

concerns/responsible

代码重用-通过使用关心或负责任的设计方法会增加代码的重用。尤其是当使用一个域模型和维持所有商业/状态管理逻辑在其混在一起时。

隐藏数据存取-使用这些模式逼着你把数据访问代码封装在一个数据访问层。还有其他一些典型的模式,与MVP/ MVC模式的数据存取。Two of the most common ones are repository and unit of work. (See Martin Fowler – Patterns of Enterprise Application Architecture for more details)

灵活性/适应性-通过隔震大部分的代码到主持人/控制器和模型组成的代码基础上更加适应变化。例如考虑多少UI和数据存取技术多年来改变了和有我们今天有可利用选择的数量。 一个适当的设计解决方案或使用的MVC MVP能够支持多个用户界面和一个数据同步。

主要区别

那么,真正的分歧MVP和MVC模式。其实不是很多的分歧。这两种模式的重点放在分离的责任跨越多组件和促进松散的耦合的用户界面(视图)从业务层(模型) 。主要分歧是如何实施的模式和一些先进的情景你既需要主持人和控制器。

 

这里是关键的分歧模式:

 

1 View 与model 更松散耦合的模式。主讲人是负责binding该model模型与view的。

The presenter is responsible for binding the model to the view.

2 容易单元测试,因为与view相互作用的是通过一个接口

3 通常presenters与view 一一对应。复杂的view可能会多presenters。

 

MVC模式

1 Controller 是基于行为的,可共享的 views

2  Can be responsible for determining which view to display (Front Controller Pattern)

 

希望你对这个文章感兴趣,它有助于澄清之间的分歧和MVP的MVC模式。如果不是这样,就算的模式是功能强大的工具,可很难使用有时。

有一件事需要记住的是,一种模式是一个蓝本,而不是一个彻头彻尾的方块的解决办法。开发人员应该根据自己的问题域使用它们作为指导和修改执行。

 

As promised in MVP design pattern - Part 2, today post would cover something which generated a lot (very well deserved) noise last days - Microsoft MVC.NET framework. After some playing with the MVC.NET framework CTP bits and after reading some MVC.NET blog posts, I found myself  thinking about next questions:

  • "What is the difference between MVP and MVC? "
  • "Having MVC .NET in place, do we need MVP?"
  • "What is easier to use for TDD?"

This blog post would try to give answers on those questions

The role of view

If we would compare the diagrams of MVP and MVC patterns

image

we could see that MVP design pattern implementation has a view totally unaware of model. Presenter is the one exclusively communicating with the model and sending DTO (in case of Supervising controller) to model or performing direct manipulation with the view UI elements.

On the other hand, in MVC we have next two "read data" cases:

  • a view reading data directly from model and perform "declarative data binding" of its controls or
  • controller retrieving data from model, pass that context data to view while loading the appropriate view and view then binds to that sent context data

In most of the "update data" use cases we have a view sending updated context data to controller, where controller  performs some validation and/or business logic and updates the model with that data.

Navigation aspects

In general, MVP pattern is based on standard ASP NET page controller pattern implementation, where Page A performs Response.Redirect("PageB") and that results with page B loading with complete page life cycle events fired etc. MVP adds to that sequence just  one additional step: injecting the view to presenter (where view for presenter is just an UI technology abstracted view interface) image

Beside that "default" ASP NET page controller based implementation, there are various ways how the MVP implementation can be enhanced.

One of them is the utilization of application controller  and Page Flow Application Block (which I presented last week on my Web Client Software Factory session) where application controller centralizes flow and navigation concerns and behaves as shared context  container for multiple views covering the same use case.

Page flow application block is a block using the NET 3.0 workflow engine enhanced with additional UI designer used in defining navigation flows. The end result is that you have a separate project with workflow definition describing navigation flow use cases. In a way, that is something very similar to the purpose front controller has.
Having in mind type of enhancement application controller and navigation flow AB bring to standard ASP NET, I am calling the WCSF sometimes "ASP NET web forms on steroids"

MVP summarized: Navigation is handled on a per page basis using page controller pattern approach.

MVC.NET framework is different - more "web suitable" approach to the same concern of efficient handling navigation. It is based on front controller design pattern driven routing engine, which in general represents intercepting of  every http request on a http handler level and checking if there are mapped controller types responsible for handling intercepted Url.

As we can see on first diagram, the flow in MVC starts with controller class and not with web page - view (which is use case in MVP). When controller is been invocated, it usually:

  • retrieves some data from model,
  • performs business logic and
  • picking the appropriate view to which he pass the processed model data
  • loads  the view - which then renders without the need of complete page life cycle being executed

In a way, that is something similar to what we have in Supervising controller MVP pattern, with a difference that in supervising controller the view (page) is still been loaded first and then the presenter class is been created)

MVC summarized: The navigation is handled in one centralized configurable place for all the pages  based on front controller pattern.

I found one thing important enough to be emphasized here: Front controller (routing engine) is a part of Microsoft MVC.NET framework, but that is its separate part and pattern different then MVC pattern.

To illustrate how routing engine is important for MVC framework, I'll just mentioned briefly that I've been working on a POC which was supposed to handle on efficient way the need for having various page UI flavors of the same page - based on multiple business conditions.

I choose to built POC platform based on MVP pattern where multiple views (representing versions of the page) are sharing the same presenter (to remove redundancy) enhanced with custom (Maverick .NET based) routing front controller engine. The end result of this solution based on a front controller + MVP is something which looks (to me at least) very much like what I've seen in MVC.NET framework but just with standard web forms used.

Advantages of the MVP

One advantage I am particular excited about MVP is something David Hayden blogged about and Ron Jacobs talked about with Atomic Object guys. It is the fact that in MVP all you need to develop the presenter is an interface of the view. That interface of the view in passive view version of MVP represents page UI elements, so in a sense it can be considered as page abstraction or even as page contract between the UX (designers) and DEV (developers).  

Although passive view is very cumbersome to be implemented and sometimes lead to complex presenters, the advantages of its usage are much higher in standard waterfall development process, because it enables tech leads  to translate the FRD (Functional Requirement Document) requirements right at the beginning of development phase and produce sets of view interfaces (abstracted pages).

Therefore, communication on relation tech lead->developer is concentrated to the beginning of development phase with very precise set of artifacts defining requirements. Once the interface of the views would be defined and verified as the one matching the FRD requirements, developers are able to start developing their presenters including the unit tests to verify that FRD functional requirements are fulfilled well.

The end result of that activity would be a list of unit tests representing FRD requirements. Percentage of successfully "green" test of that list can be used then to track realistic project progress. 5 green tests of 100 FRD tests=> 5% progress report.

image

What we get as the end result is:

  • totally decoupled and effective working streams of tech lead, developer and designer
  • set of artifacts useful in tracking the real project implementation progress  and as a guidance to developers what requirements they have to met.

IMHO, Second advantage MVP has is that while MVC pattern feels more natural in some web development scenarios,  MVP pattern based development offers "crossing the boundaries" out of the box by utilizing the fact that presenter is not aware of the view UI used technology. Both view interface and presenter  are living even in separate class library project which allows their re-usage in win form applications too.

I know, most of us thinks about that as "cool but YAGNI", "we are doing only web development", but once you would see how easy it is to get the smart client application from already built web application, you would start thinking about that too.

Think about another idea: win form UI development is much faster to be implemented and modified so imagine doing prototypes of your web sites in win form just to speed up process of verifying if business needs would be met with application. Once that would be verified, you would still use the same presenter you used for win form and build a web form UI layer on top of it but this time with already confirmed business expectations.

MVP and MVC in Test Driven Development

As stated already in this post, MVP biggest advantage is enabling writing presenter tests with only view interface available.
On the other hand, MVC.NET approach to TDD offer much more power with providing ability of mocking the flow itself (you can mock context, request, response) + providing the controller based testing on a way similar to testing the supervising controller (setting the context DTO to desired values to trigger certain test flows).

Although that looks maybe to someone on first sight as an overkill, according to the Jeremy D. Miler (and he knows what he's talking :) ) the simple nature of MVC route -> controller -> view makes writing complex web form tests much easier

I spent decent amount of time of this 2007 doing MVP tests in web forms and although there were a lot of hurdles during that time I face, I can not say that I felt too much pain mainly because I was mostly using  either front controller or application controller as MVP supplemental patterns

Right now, to me too MVC looks a little bit more complex to be TDD-ed and I don't know if the advantages of the MVP can be achieved easily in MVC too, but I realize that I don't have too much experience with real world TDD-ing MVC usage but I know that I can relay on Jeremy's opinion.

The promise of having easier TDD experience with MVC in upcoming period is making me very happy and really eager to dive deeper in MVC, so be prepared for some blog posts on that subject (if anything left to be blogged after all this MVC .NET posts appearing last days like mushrooms after the rain :)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值