【MVVM的定义】

 
 

MVVM的目的是什么?

简单总结起来一句话:分离UI逻辑和业务逻辑。这一点和被大家熟知的MVP和MVC是一致的。

 
 

下面详细来说明下这个问题,下面一段英文来自Msdn:

 
 

The Model-View-ViewModel (MVVM) pattern helps you to cleanly separate the business and presentation logic of your application from its user interface (UI). Maintaining a clean separation between application logic and UI helps to address numerous development and design issues and can make your application much easier to test, maintain, and evolve. It can also greatly improve code re-use opportunities and allows developers and UI designers to more easily collaborate when developing their respective parts of the application.

Using the MVVM pattern, the UI of the application and the underlying presentation and business logic is separated into three separate classes: the view, which encapsulates the UI and UI logic; the view model, which encapsulates presentation logic and state; and the model, which encapsulates the application's business logic and data.

Prism includes samples and reference implementations that show how to implement the MVVM pattern in a Silverlight or Windows Presentation Foundation (WPF) application. The Prism Library also provides features that can help you implement the pattern in your own applications. These features embody the most common practices for implementing the MVVM pattern and are designed to support testability and to work well with Expression Blend and Visual Studio.

 
 

总结起来MVVM的好处有:

 
 

1、分离业务逻辑(buiness logic)和表现层逻辑(presentation logic)

2、Support testability 易于测试,正如martin flower 在xunit partten中提到的,对于程序unit test的建设要在设计之初便有所考虑。(对于这点是容易被很多人忽略的,因为多数coder甚至都不清楚什么叫Unit Test)而这一点事实上也是MVVM带来的很重要的好处。

3、从笔者的经历来看,mvvm的另一个意义在于,提高团队协作的效率。

 
 

为什么这么说呢?类比《设计模式》一书,设计模式这本书的重要作用在于,给程序员之间一个很好的名字契约,因此沟通时,只需要说我用了XX模式,那么对方很直观便明白了具体的实现。一个标准的架构的意义也在于此,比如团队使用MVVM来架构,那么只需要团队中的成员对MVVM有所了解,对各层的职责明确清楚,那么接下来继续要开展的工作就容易很多。这和招聘iOS研发要需要理解MVC是一个道理,大家都了解的统一的程序架构,是协作的很重要的前提。

 
 

看过了MVVM 的作用,我们接下来要做的便是明确各层的职责。单纯的把类名起名叫ViewModel却不做VM该做的事情,那还是建议压根就不要起名为VM来混淆试听了。(不能说拿来一个橙子告诉别人我这是橘子,而别人质疑的时候,辩解到这是改良的橘子)(虽然MVVM和MVX系列很相似,但他也是单独命名出来的,而不是叫做变种的MVP)

(因此建议不要再同其他人交流的过程中说,我用了MVVM架构,但说出来却完全不是那么回事儿,干脆说叫MVVMNB算了也免得产生误会)

 
 

【MVVM各层的职责界定】

 
 

为了权威仍然引用msdn中对于mvvm的各层的职责界定:

 
 

 
 

 
 

此图很清晰的明确了各层的职责以及交互方式,结合说明我们做进一步分析:

 
 

The View Class

 
 

The view's responsibility is to define the structure and appearance of what the user sees on the screen. Ideally, the code-behind of a view contains only a constructor that calls the InitializeComponent method. In some cases, the code-behind may contain UI logic code that implements visual behavior that is difficult or inefficient to express in Extensible Application Markup Language (XAML), such as complex animations, or when the code needs to directly manipulate visual elements that are part of the view. You should not put any logic code in the view that you need to unit test. Typically, logic code in the view's code-behind will be tested via a UI automation testing approach.

 
 

In Silverlight and WPF, data binding expressions in the view are evaluated against its data context. In MVVM, the view's data context is set to the view model. The view model implements properties and commands to which the view can bind and notifies the view of any changes in state through change notification events. There is typically a one-to-one relationship between a view and its view model.

 
 

To summarize, the view has the following key characteristics:

  • The view is a visual element, such as a window, page, user control, or data template. The view defines the controls contained in the view and their visual layout and styling.
  • The view references the view model through its DataContext property. The controls in the view are data bound to the properties and commands exposed by the view model.
  • The view may customize the data binding behavior between the view and the view model. For example, the view may use value converters to format the data to be displayed in the UI, or it may use validation rules to provide additional input data validation to the user.
  • The view defines and handles UI visual behavior, such as animations or transitions that may be triggered from a state change in the view model or via the user's interaction with the UI.
  • The view's code-behind may define UI logic to implement visual behavior that is difficult to express in XAML or that requires direct references to the specific UI controls defined in the view.

     
     

 
 

很清楚的可以看出View的职责:

定义用户在屏幕中所看到的各个UI元素。

需要说明的是:

1、一般情况下在view的code behind里面应只包含构造函数,构造函数中执行InitilizeComponent方法。例外的场景是,在xaml中不容易实现的复杂的ui逻辑等。

2、不应将任何需要进行单元测试的逻辑放到view层中

3、在MVVM中View的DataContext是在ViewModel中。通常情况下View和ViewModel是一对一的关系

 
 

对于View层的理解比较简单

 
 

The View Model Class

The view model in the MVVM pattern encapsulates the presentation logic and data for the view. It has no direct reference to the view or any knowledge about the view's specific implementation or type. The view model implements properties and commands to which the view can data bind and notifies the view of any state changes through change notification events. The properties and commands that the view model provides define the functionality to be offered by the UI, but the view determines how that functionality is to be rendered.

The view model is responsible for coordinating the view's interaction with any model classes that are required. Typically, there is a one-to many-relationship between the view model and the model classes. The view model may choose to expose model classes directly to the view so that controls in the view can data bind directly to them. In this case, the model classes will need to be designed to support data binding and the relevant change notification events. For more information about this scenario, see the section, Data Binding, later in this topic.

The view model may convert or manipulate model data so that it can be easily consumed by the view. The view model may define additional properties to specifically support the view; these properties would not normally be part of (or cannot be added to) the model. For example, the view model may combine the value of two fields to make it easier for the view to present, or it may calculate the number of characters remaining for input for fields with a maximum length. The view model may also implement data validation logic to ensure data consistency.

The view model may also define logical states the view can use to provide visual changes in the UI. The view may define layout or styling changes that reflect the state of the view model. For example, the view model may define a state that indicates that data is being submitted asynchronously to a web service. The view can display an animation during this state to provide visual feedback to the user.

Typically, the view model will define commands or actions that can be represented in the UI and that the user can invoke. A common example is when the view model provides a Submit command that allows the user submit data to a web service or to a data repository. The view may choose to represent that command with a button so that the user can click the button to submit the data. Typically, when the command becomes unavailable, its associated UI representation becomes disabled. Commands provide a way to encapsulate user actions and to cleanly separate them from their visual representation in the UI.

 
 

To summarize, the view model has the following key characteristics:

  • The view model is a non-visual class and does not derive from any WPF or Silverlight base class. It encapsulates the presentation logic required to support a use case or user task in the application. The view model is testable independently of the view and the model.
  • The view model typically does not directly reference the view. It implements properties and commands to which the view can data bind. It notifies the view of any state changes via change notification events via the INotifyPropertyChanged and INotifyCollectionChanged interfaces.
  • The view model coordinates the view's interaction with the model. It may convert or manipulate data so that it can be easily consumed by the view and may implement additional properties that may not be present on the model. It may also implement data validation via the IDataErrorInfo or INotifyDataErrorInfo interfaces.
  • The view model may define logical states that the view can represent visually to the user.

 
 

 

需要注意的:

1、对于VM的职责,有一点非常容易理解错误,就是VM和Business logic的关系。

View Model 从名字来看就可以看出它是View的Model,因此它需要为View提供数据,以及操作接口,View Model中不应该包含Business Logic

2、VIewModel与View的关系如上面的图中所描述,ViewModel是不该知道View的,即ViewModel不该持有View的实例(It has no direct reference to the view or any knowledge about the view's specific implementation or type.)

3、ViewModel是可以脱离View和Model进行Unit Test的(the view model is testable independently of the view and the model.)

 
 

4、View通过Binding的方式将ViewModel中定义的数据以及行为(command)关联到一起

 
 

The Model Class

 
 

The model in the MVVM pattern encapsulates business logic and data. Business logic is defined as any application logic that is concerned with the retrieval and management of application data and for making sure that any business rules that ensure data consistency and validity are imposed. To maximize re-use opportunities, models should not contain any use case–specific or user task–specific behavior or application logic.

Typically, the model represents the client-side domain model for the application. It can define data structures based on the application's data model and any supporting business and validation logic. The model may also include the code to support data access and caching, though typically a separate data repository or service is employed for this. Often, the model and data access layer are generated as part of a data access or service strategy, such as the ADO.NET Entity Framework, WCF Data Services, or WCF RIA Services.

Typically, the model implements the facilities that make it easy to bind to the view. This usually means it supports property and collection changed notification through the INotifyPropertyChanged and INotifyCollectionChanged interfaces. Models classes that represent collections of objects typically derive from the ObservableCollection<T> class, which provides an implementation of the INotifyCollectionChanged interface.

The model may also support data validation and error reporting through the IDataErrorInfo (or INotifyDataErrorInfo) interfaces. These interfaces allow WPF and Silverlight data binding to be notified when values change so that the UI can be updated. They also enable support for data validation and error reporting in the UI layer.

 
 

 
 

The model has the following key characteristics:

  • Model classes are non-visual classes that encapsulate the application's data and business logic. They are responsible for managing the application's data and for ensuring its consistency and validity by encapsulating the required business rules and data validation logic.
  • The model classes do not directly reference the view or view model classes and have no dependency on how they are implemented.
  • The model classes typically provide property and collection change notification events through the INotifyPropertyChanged and INotifyCollectionChanged interfaces. This allows them to be easily data bound in the view. Model classes that represent collections of objects typically derive from the ObservableCollection<T> class.
  • The model classes typically provide data validation and error reporting through either the IDataErrorInfo or INotifyDataErrorInfo interfaces.
  • The model classes are typically used in conjunction with a service or repository that encapsulates data access and caching.

 
 

 
 

需要说明的有:

1、Model层定义Business logic 和Data。

2、Model层不依赖于View和ViewModel层

 

 
 

总结

对于MVVM的职责划分正如上面所阐述的,很清晰,如此划分,我们可以很好的根据职责来组织代码的结构,增加程序的可维护性

 
 

综上,笔者的结论是,MVVM是配合WPF系列技术中Binding等强大特性而出现的一种程序的架构方式,清晰而简单,值得推荐使用。

 
 

参考:

http://en.wikipedia.org/wiki/MVVM

http://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

http://stackoverflow.com/questions/1644453/why-mvvm-and-what-are-its-core-benefits

 
 

更多关于MVVM的讨论欢迎加入qq群:182659848

 
 

 
 

 
 

 
 

 
 

WP架构设计(一)MVVM回顾的更多相关文章

  1. Unity应用架构设计(1)—— MVVM 模式的设计和实施(Part 2)

    MVVM回顾 经过上一篇文章的介绍,相信你对MVVM的设计思想有所了解.MVVM的核心思想就是解耦,View与ViewModel应该感受不到彼此的存在. View只关心怎样渲染,而ViewModel只 ...

  2. Unity应用架构设计(1)—— MVVM 模式的设计和实施(Part 1)

    初识 MVVM 谈起 MVVM 设计模式,可能第一映像你会想到 WPF/Sliverlight,他们提供了的数据绑定(Data Binding),命令(Command)等功能,这让 MVVM 模式得到 ...

  3. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  4. Android App的架构设计:从VM、MVC、MVP到MVVM

    随着Android应用开发规模的扩大,客户端业务逻辑也越来越复杂,已然不是简单的数据展示了.如同后端开发遇到瓶颈时采用的组件拆分思想,客户端也需要进行架构设计,拆分视图和数据,解除模块之间的耦合,提高 ...

  5. 浅谈iOS中MVVM的架构设计与团队协作

    说到架构设计和团队协作,这个对App的开发还是比较重要的.即使作为一个专业的搬砖者,前提是你这砖搬完放在哪?不只是Code有框架,其他的东西都是有框架的,比如桥梁等等神马的~在这儿就不往外扯了.一个好 ...

  6. iOS中MVVM的架构设计与团队协作

    对MVVM的理解主要是借鉴于之前的用过的MVC的Web框架,之前用过ThinkPHP框架,和SSH框架,都是MVC的架构模式,今天MVVM与传统的MVC可谓是极为相似,也可以说是兄弟关系,也就是一家人 ...

  7. MVVM的架构设计与团队协作 with StoryBoard

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  8. IOS中 浅谈iOS中MVVM的架构设计与团队协作

    今天写这篇文章是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇文章的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  9. 浅谈iOS中MVVM的架构设计与团队协作【转载】

    今天写这篇文章是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇文章的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

随机推荐

  1. 根据WSDL文件生成代理类

    D:\Program Files\Microsoft Visual Studio 10.0\VC>wsdl  /l:c#  /n:cmsserver  /out:E:\ospsoft\Trave ...

  2. C++ 踩内存

    1.从上往下,栈在堆上面(记忆方法:站在堆上面),二者向里压缩,也就是说,栈地址减少,堆地址增加.栈顶是小地址. 2.模拟踩内存,让程序崩溃.代码如下: int main(int argc, char ...

  3. 一个完整的C++程序SpreadSheet - 1) 类的声明和定义

    1. SpreadsheetCell.h #pragma once #include <string> class SpreadsheetCell { public: void setVa ...

  4. 使用Bundle进行VIM插件的管理

    http://www.oschina.net/p/vundle git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle ...

  5. Google开源单元測试框架Google Test:VS2012 配置

    由题目可知,Google Test(简称gtest)是Google公布的一个开源C/C++測试框架,被应用于多个开源项目及Google内部项目中,包括Chrome浏览器.LLVM编译器架构.Proto ...

  6. dojo 五 配置dojoconfig

    官方教程:Configuring Dojo with dojoConfig例子: <-- set Dojo configuration, load Dojo --> <script& ...

  7. java线程-java多线程之可见性

    可见性:一个线程对共享变量值的修改,能够及时呗其他线程看到. 共享变量:如果一个变量在多个线程的内存中都存在副本,那么这个变量就是这几个线程的共享变量. java内存模型(JMM) 描述了java程序 ...

  8. 几种通讯协议的比较RMI > Httpinvoker >= Hessian >> Burlap >> web service (转)

    一.综述 本文比较了RMI,Hessian,Burlap,Httpinvoker,web service等5种通讯协议的在不同的数据结构和不同数据量时的传输性能.RMI是java语言本身提供的通讯协议 ...

  9. 【mysql】主键、普通索引、唯一索引和全文索引的比较

    YSQL索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录 开始扫描整个表的所有记录,直至找到符合要求的记录.表里面的记 ...

  10. js判断浏览器是否关闭

    http://www.blogjava.net/wyz191/archive/2008/12/08/245089.html JS   window.onunload=function(){      ...