FLYabroad 自助移民 - FLYabroad111.com

FLYabroad.NET

MDN:sunhongliang@hotmail.com, QQ:147836980, GTalk:evenifyouknowme@gmail.com
随笔 - 23, 文章 - 0, 评论 - 165, 引用 - 9
数据加载中……

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 模式简单结构图

MVP      

该结构图表示 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 。

StopLight-MVP

MVP 之 Presenter

我们首先来看 Presenter ,在创建 SCSF 解决方案时,Guidance Package 自动在 Infrastructure 项目的接口层中(本例是 namespace SmartClient系列.Infrastructure.Interface)创建了一个抽象的 Presenter 类:

Presenter.cs 

 1public abstract class Presenter<TView> : IDisposable
 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 接口:

public partial class StopLightView : UserControl, IStopLightView

在 StopLightView.GeneratedCode.cs 文件(StopLightView 的分部类)中代码如下:

 1namespace SmartClient系列.StopLight
 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 的具体实现是:

public partial class StopLightViewPresenter : Presenter<IStopLightView>

也就是说,在 StopLightViewPresenter 类中,TView 泛型类型代表的是 IStopLightView 接口 ,因此 Presenter 与 View 通过接口进行联系,是一种松散的耦合。这与上面介绍的 MVP 结构中说的 Presenter 通过接口与 View 交互完全一致。

MVP 之 Model

Model 是一个比较宽泛的概念,一般认为业务逻辑实体、服务组件等都可以看作 Model,StopLight 项目从 Unity 的 QuickStart StopLight 移植而来,没有利用 SCSF 的 WorkItem 概念,而是直接在 Presenter 类中通过依赖注入方式与 Model 建立联系,看下面例子中的 Stoplight 和 StoplightSchedule:

 1   public partial class StopLightViewPresenter : Presenter<IStopLightView>
 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 应用提供了良好的参考。

Tag标签: scsf

posted on 2008-06-19 10:21 FLYabroad 阅读(1742) 评论(11)  编辑 收藏 所属分类: 框架架构

评论

#1楼    回复  引用  查看    

学习中...
2008-06-19 10:49 | jvl      

#2楼    回复  引用  查看    

写的很好。 期待一篇关于workItemVisualizer以及如何规划设计一个use case 下的workitem 树的文章。
2008-06-19 11:38 | 杨同学      

#3楼 [楼主]   回复  引用  查看    

workitem 下周应该能介绍到,Visualizer 我还没用过,据说是用来动态查看 workItem 运行状态
2008-06-19 11:52 | FLYabroad      

#4楼    回复  引用    

学习了,谢谢
2008-06-19 14:48 | 手机魔卡 [未注册用户]

#5楼    回复  引用  查看    

说实话,个人比较讨厌mvp模式,认为绝对是过度设计!

就为了view 与 presenter的分离,
所以view 调用 presenter的时候还不能return

而要通过接口 注入回去

这种方式 让人感觉很不爽快。

不过话说回来,这样确实解藕了view 和presenter!!!
2008-06-19 16:17 | xiao_p      

#6楼 [楼主]   回复  引用  查看    

这就要看我们希望得到什么了
基于项目的快速开发,还是基于产品的良好的可维护性、良好的可测试性?

框架、设计模式和良好的面向对象设计往往使系统类的数量增加,类之间的关系动态化,初看起来不容易了解,甚至令人望而生畏。

理论和实践总会有代沟。。。。。。,是否使用框架和这些模式其实是有很多因素决定的,我认为最关键的因素是人(团队)。
2008-06-19 17:25 | FLYabroad      

#7楼    回复  引用  查看    

简单理解原理会吃苦头的哦。
2008-06-19 19:09 | 皇帝的新装      

#8楼    回复  引用  查看    

如何具体使用需要仔细规划。
2008-06-19 19:10 | 皇帝的新装      

#9楼    回复  引用  查看    

在UNITY的DEMO里,P和V的解藕是用事件来实现的,而在SCSF的RI中却是用方法调用来实现
2008-06-19 21:51 | 江南白衣      

#10楼    回复  引用    

我也有疑问,如果说真正意义上实现MVP,是不是当View调用presenter时,不能有返回值,给页面赋值,就封装在IView中,这样才能达到真正意义上的View和model解偶(View 不知道 Model).可是实际中,这样可行吗?这样造成开发很麻烦
2008-09-12 15:05 | 看看 [未注册用户]

#11楼    回复  引用    

从标准的模式来看是要分开的。
使用架构和设计模式往往使系统开发变得麻烦点,这也是小项目不必要使用这些框架的原因,对于大的项目,多人协作开发的项目,编码麻烦的代价是可以通过后期维护的简单和扩展、重用的方便来弥补的
2008-09-12 15:13 | FLYabroadVisa [未注册用户]

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-06-19 10:25 编辑过


相关链接:
 


FLYabroad 自助签证工作室 - FLYabroad Visa