ID #33217

C#版MVC框架PureMVC的深入分析和改良方案

  在PureMVC中,通知(Notification)贯穿整个框架,把观察者模式发挥得淋漓尽致。MVC的三层通信都是通过Notification来通信。Notification由两部分组成:Name和Body。如果把Notification当作是邮件,那么Name就是收件人,不过在PureMVC中可以有多个观察者(Observer)接收相同的邮件,Body自然就是Notification的内容了。Notification和Observer的关系是1:N,这点可以从View层的代码中看出来。

observerMap = new Dictionary<String, IList<IObserver>>();

  Observer有两个属性:

private String notify;
private Object context;

  notify是方法名,context是方法的载体。当Observer接收到Notification时,将调用下面的方法

public void notifyObserver(INotification notification)
{
      Type t = this.getNotifyContext().GetType();
      BindingFlags f = BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase;
      MethodInfo mi = t.GetMethod(this.getNotifyMethod(), f);
      mi.Invoke(this.getNotifyContext(), new Object[] { notification });
}

  来执行notify这个方法。

  PureMVC中,注册Observer和通知Observer都是在View层进行的。

public interface IView
{
void reGISterObserver (String notificationName, IObserver observer);
void removeObserver(String notificationName, Object notifyContext);
void notifyObservers(INotification note);

  我觉得这点设计得不太好,使得View层和Observer产生了耦合,这些事情本不应该由View层来做的。而且,Observer接收的Notification不仅仅来自于View,还会来自于Controller和Model,那么,根据AOP的原则,应该把这部分的操作应该从MVC层的纵向分离出来,改为横向模式。可以创建一个观察者公司Obsertor(暂且这样叫它吧)来统一管理观察者,这样就可以减轻View层的工作了。结构图如下:

C#版MVC框架PureMVC的深入分析和改良方案

  在PureMVC中有一个类叫Notifyer,根据字面的意思,它应该是Notification的传递都,也就是邮差才对。然而这个类却不做自己的本职工作---给Observer发送通知,而是把所有通知都推给了Facade,再由Facade通过View来把Notification发送给Observer。发个通知也一波三折,我觉得这样设计不够合理。前面我已经创建了观察都的公司Obsertor了,那么Notifyer只要直接把Notification发送到Obsertor就可以了,Obsertor会把Notification发给具体的Observer。现实中的公司都是这样子的吧,经常都是前台告诉我,我的包裹到了。因此,应该让Notifyer做回它的本职工作。

C#版MVC框架PureMVC的深入分析和改良方案

  PureMVC的C#版本在Mediator的注册上存在着点BUG,注册Mediator的部分代码:

Code
public void registerMediator(IMediator mediator)
{
if (mediatorMap.ContainsKey(mediator.getMediatorName())) return;

  它的本意是避免Mediator的重复注册,然后当页面重新加载时,mediatorMap里的Mediator的视图已经过时了,这样就导致了无法更新页面。我的解决方法是

Code
public void registerMediator(IMediator mediator)
{
      if (mediatorMap.ContainsKey(mediator.getMediatorName()))
      {
        mediatorMap[mediator.getMediatorName()].setViewComponent(mediator.getViewComponent());
        return;
      }

  局部更新一下ViewComponent,这样就运行正常了。

  本来是想分析一下PureMVC的实现机制的,但发现自己的表达能力实在有限,心有余而力足,但哪天有思路了,再为大家献上。同时,我再根据自己的方案改良一下PureMVC,让它更适用于C#,到时再将源码一起发布。由于工作比较忙,可能要让大家等上一阵子。


2008-11-29 00:00
阅读:
I'm VC , Just U know Y
本站部分文章来源于互联网,版权归原作者所有。

延伸阅读:

C#2.0终于有了?:便捷判断的单分支版

在c#中实现3层架构

C#设计的一个向导程序(Wizard)框架

如何获取当前操作系统的软件版本

IP数据包的校验和算法C#版