SCSF 系列:Smart Client Software Factory 中的 MVP 模式概述
Smart Client Software Factory 是一个关注 Smart Client (智能客户端)构建的 UI 层框架,提供了对 MVP 模式的 First Class 支持,不了解 MVP 模式就不能完全领会 SCSF 的思想精华。
本篇及后面两篇将结合 Smart Client Software Factory 讲解 MVP 模式及面向对象设计原则,要点:
- SCSF 严格按照标准 MVP 架构模式构造 UI 层,代码和架构完全吻合,给我们设计 MVP 应用提供了良好的参考。
- View 和 Presenter设计要以用例(Use Case)为基础,以面向对象设计原则为准则。力求职责单一,有选择的面向抽象,构建易测试、易理解的。
- Presenter 是整个用例的大管家,控制协调中心,自己基本上不做具体事情,核心工作都是组织和协调。作为控制器,Presenter了解与该用例相关的所有事情,因此能够将合适的事情指派给合适的人去处理。
- IOC 使我们将对象创建销毁和对象之间关系的维护在容器中进行,这是封装变化和推迟决策原则的具体体现。
上一篇创建的 StopLight 项目演示了如何使用 SCSF构造基于 MVP 模式的应用。StopLight 功能很简单,实现这样的需求很多人只用一个窗体类就可以搞定,而且代码量不会太大,理解维护起来不会太困难;使用 SCSF 的 MVP 构建却涉及到了 10 个左右的类,并且初看起来里面的关系也变得扑朔迷离,难以捉摸。
这牵扯到一个普遍问题,框架、设计模式和良好的面向对象设计往往使系统类的数量增加,类之间的关系动态化,初看起来不容易了解,甚至令人望而生畏。因此很多人,尤其是用惯了 Windows 开发平台的开发人员,认为很多模式和框架(例如今天我们讨论的 MVP )虽然理论上看上去很美,但工程上似乎不太实用。Java 社区过多的研究模式,框架等理论,导致设计模式、框架的过度使用和滥用,确实拖累了很多项目。
今天,.NET 社区对框架、设计模式的追崇也慢慢的跟进 JAVA 社区,IOC,MVP,MVC,SOA,ESB等等一系列的架构理论都有了相应的框架实现。今天我们通过这个小题大做的 StopLight 来理解一下 MVP 究竟能够我们带来什么,我们又因此付出了什么代价,并初步讨论什么样的项目适合使用 SCSF。
MVP 模式(Model-View-Presenter)是由 MVC模式(Model-View-Controller)演变来的 UI 层框架模式,MVP 模式本身往往有多个设计模式组成。MVP 和 MVC 都采用了抽象的方式将界面部分划分为相对独立的多个模块,并通过面向抽象编程(面向接口编程)来降低模块间的耦合性,SCSF 利用依赖注入方式进一步使构建松散耦合的 MVP 应用变得方便。MVP 与 MVC 的比较将在后面的文章中介绍。
Model-View-Presenter 模式简单结构图
该结构图表示 View 直接和 Presenter 交互,Presenter 与 Model 交互,View 和 Model 直间没有直接联系。同时 Presenter 通过接口与 View 交互。
Smart Client Software Factory 与 Model-View-Presenter 模式
SCSF 中的 MVP 实现完全按照上图模型实现,当我们使用 Add View(With Presenter)Guidance Package 生成 View 时,SCSF 为我们生成了三个类,本例中是IStopLightView ,StopLightView ,StopLightViewPresenter 。
MVP 之 Presenter
我们首先来看 Presenter ,在创建 SCSF 解决方案时,Guidance Package 自动在 Infrastructure 项目的接口层中(本例是 namespace SmartClient系列.Infrastructure.Interface)创建了一个抽象的 Presenter 类:
2
里面的 View (TView 类型)代表的就是 MVP 中的 V ,WorkItem (WorkItem 类型,通过 [ServiceDependency] 注入)代表了 MVP 中的 M (也可以认为 WorkItem 中承载了 Model,通过 WorkItem 我们可以获取所谓的 Model)。因此 Presenter 与 View 和 Model 建立起了关系。
MVP 之 View
再来看 StopLight 项目中的 V 部分由类 StopLightView 和接口 IStopLightView 组成,StopLightView 继承自 UserControl 并实现了 IStopLightView 接口:
在 StopLightView.GeneratedCode.cs 文件(StopLightView 的分部类)中代码如下:
2{
3 [SmartPart]
4 public partial class StopLightView
5 {
6 /// <summary>
7 /// Sets the presenter. The dependency injection system will automatically
8 /// create a new presenter for you.
9 /// 设置完 TView 后调用具体的 OnViewSet() 方法
10 /// </summary>
11 [CreateNew]
12 public StopLightViewPresenter Presenter
13 {
14 set
15 {
16 _presenter = value;
17 _presenter.View = this; //注意了!
18 }
19 }
20 }
21}
22
我们通过 [SmartPart] Attribute 标志该类(StopLightView)是一个 SmartPart(SCSF 中的概念,代表一个视图部件)。我们在 ObjectBuilder 部分介绍过,构造 StopLightView 对象时,SCSF 看到 Presenter 属性前面的 [CreateNew] Attribute 会自动创建一个 StopLightViewPresenter 对象附给 _presenter 字段,而 _presenter.View = this 语句表明新创建的StopLightViewPresenter 实例的 View 属性设置为 StopLightView 实例。
这样 View 就与 Prensenter 建立起了双向关系,StopLightView 实例具有了 StopLightViewPresenter 实例的引用,一种强耦合的引用。
值得注意的是,StopLightViewPresenter 的实例的 View 属性是在抽象类 Presenter 中定义的 <TView> 泛型类型,StopLightViewPresenter 的具体实现是:
也就是说,在 StopLightViewPresenter 类中,TView 泛型类型代表的是 IStopLightView 接口 ,因此 Presenter 与 View 通过接口进行联系,是一种松散的耦合。这与上面介绍的 MVP 结构中说的 Presenter 通过接口与 View 交互完全一致。
MVP 之 Model
Model 是一个比较宽泛的概念,一般认为业务逻辑实体、服务组件等都可以看作 Model,StopLight 项目从 Unity 的 QuickStart StopLight 移植而来,没有利用 SCSF 的 WorkItem 概念,而是直接在 Presenter 类中通过依赖注入方式与 Model 建立联系,看下面例子中的 Stoplight 和 StoplightSchedule:
2 {
3 private Stoplight stoplight;
4 private StoplightSchedule schedule;
5 [Dependency]
6 public Stoplight Stoplight
7 {
8 get { return stoplight; }
9 set { stoplight = value; }
10 }
11 [Dependency]
12 public StoplightSchedule Schedule
13 {
14 get { return schedule; }
15 set { schedule = value; }
16 }
17 …………
18 }
这里, StopLightViewPresenter 与 Stoplight ,StoplightSchedule 两个业务逻辑实体类是一种强的耦合关系,代表了 MVP 结构中 Presenter 与 Model 的关系。 在 SCSF 中,推荐的设计方式是所有的 View 和 Model 都驻留在该用例对应的 WorkItem 中,关于 WorkItem 后面会专门介绍到。
下一部分会介绍设计 MVP 应用的具体实践、设计原则并简要分析优缺点。
【FLYabroad】 SCSF 严格按照标准 MVP 架构模式构造 UI 层,代码和架构完全吻合,给我们设计 MVP 应用提供了良好的参考。
posted on 2008-06-19 10:21 FLYabroad 阅读(6495) 评论(12) 编辑 收藏 举报