[Composite UI][设计模式]MVP or MVC?

********************************************************************
*                                                 版权声明
*
* 本文以Creative Commons的知识共享署名-非商业性使用-相同方式共享发布,请严格遵循该授权协议。
* 本文首发于博客园, 此声明为本文章中不可或缺的一部分。
* 作者网名:    浪子
* 作者EMAILdayichen (at)163.com
* 作者BLOG:  Http://Www.Cnblogs.Com/Walkingboy
*
********************************************************************

 

 

[Composite UI][设计模式]MVP or MVC?

-Written by 浪子@cnblogs.com  (06-12-20)

摘要:

MVP or MVC?一直以来都认为CAB是MVP的典型应用,最近再考虑自己Web MVP框架中的MdiForm实现,记得CAB.WinForms 中有类似的实现MdiWorksapce,昨天看了下CAB的所有Hands On Labs的示例,发现它的例子都不采用MVP模式,感觉有点“误用”,也顺便想了下,利用CAB做到真正的MVP的思路,暂且记录一下。

一、老调重弹:MVP与MVC

MVP不同于MVC的地方,关键在于,View不再显示的依赖于business logic controller,而是依赖于一个业务逻辑抽象接口,关注于View的解藕。

所以区分MVP与MVC的关键在于View是否依赖于某一具体的业务对象。

二、CAB Labs之MVC

暂以CAB的Labs的代码为例,各层次之间的定义和关联如下:

CustomerWorkItem:驱动一个完整的Customer UseCase

CustomerDetailView:显示客户明细的UI

CustomerDetailController:包装CustomerWorkItem的关于Detail的功能,暴露服务接口给CustomerDetailView使用

关于CustomerDetailView中如何使用CustomerWorkItem

    // We use our controller so we can show the comments page
        [CreateNew]
        public CustomerDetailController Controller
        {
            set { controller = value; }
        }

可以看到View只是依赖于OB的注入功能,采取对象注入的方式来获取Controller,但是其注入的类型却是具体的CustomerDetailController,而不是抽象对象(如IControlller),这样子虽然采用了IoC功能,但是依赖还是照样存在。

当然例子中有很多关于为View解藕的方法,比如EventBorker的Publisher和Subscriber,还有CommandHanlder,好像可以解决View的具体依赖问题,因为他们都依赖于抽象的WorkItem,但是当Controller也夹杂进来的时候,一下子就破坏了View的独立性。

三、CAB Labs之MVC重构

其实Labs中的依赖关键在于对具体Controller的依赖,如果我们可以将这部分进行重构,使之如同依赖于WorkItem一样依赖于一个IController就可以完全把View独立出来。

而如何抽象IController是关键点所在。

可能各种业务的Controller是不一样的,有的甚至背道而驰,如何抽象出他们的共同点是个难题所在。

我之前的框架是对其进行通用化,比如根据View的通过特性,定义一些跟View相关的约束:

         

public  interface IController
{
void ViewLoad;
object LoadData;
bool UpdateData;
void ViewClose;
//....
}

 

Controller以配置文件为依据,注入View中,这样子解决View的职责(收集数据,展现数据)。
但是实际编码过程中发现,这种方式摒避了业务的特性,使得编码的时候,总觉得用起来大不顺手,有点隔靴搔痒的感觉。
那如何解决业务对象千变万化的问题呢?其实CAB中已经给出了绝佳的解决方法。
首先,弱化IController的接口约束功能,接口如下:
 
 
public interface IController
{
}
没有看错,是个空接口。那业务功能怎么办?
别忘了WorkItem的实现方式,嘿嘿......
这个时候你会发现EventBroker&CommandHandler是如此的好用。通过配置将IView和IController进行结合,然后自动注册他们之间的关联Event和Command,
你会发现编码又恢复到之前面向过程的方式,但是所有的组件之间又是松耦合的。
四、CAB Labs之MVP
上节中所说的还都是MVC,只不过利用CAB将Controller的具体依赖拨除而已,此时对于重构到MVP已经是水到渠成了。
只要将控制的主动权转交到Presenter(由Controller重构而得)上就可以了。最简单的转化方式是,直接去除Labs示例中的Controller对象,
直接将WorkItem作为Presenter对象,此时所有的依赖都消失,这也是我对Labs中为何加入一个Controller的对象疑惑之处,还没有发现它的优点所在。
以上思路纯属主观幻想,框架代码重构ing......
posted @ 2006-12-20 14:22  浪子  阅读(4058)  评论(5编辑  收藏  举报