pureMVC与设计模式之二. Facade模式与Singleton模式

引言

上篇文章,我们分析了pureMVC的结构以及工作流。从本文开始,将逐个解剖其中设计到的设计模式。我们先看facade模式和singleton模式。


一、pureMVC中的Facade模式

1. facade模式介绍

Façade模式的理论基础是迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP),就是说一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。英文简写为: LoD. Façade模式体现了这一点。GoF中对facade模式的定义是,为子系统定义一个高层接口,使得对子系统的使用更加容易。引入façade模式的基础,是OO设计中经常会把一个功能比较大的系统分成若干个子系统以降低复杂性。但随之而来的问题是,很多子系统是的客户在调用的时候需要知道很多的细节,使用不便。于是很自然的,想到用一个辅助类(facade),来提供更高层的基于语义/功能的接口。这种模式façade模式。如图1所示,客户1,2,3原来要分别同几个系统同时交互,而引入facad模式后,客户只要同façade交互就可以了,降低了耦合度。

pureMVC与设计模式之二. Facade模式与Singleton模式_第1张图片

图1. Façade模式

Façade模式在需要降低客户程序对多个子系统及其实现的高度耦合中非常有用。

  a. 当要为复杂的子系统提供简单统一的结构时使用,不必担心子系统由于各种原因演变而越来越复杂。而那些需要更多功能的客户则可以无视façade,直接去访问各个子系统,实现更高级的功能。

  b. 接触客户和抽象类具体实现的依赖关系。通过façade接口,客户无需知道是那个具体的实现类在为其服务,是的系统的维护性和一致性增强。这一点在pureMVC中体现的比较明显。

Façade的协作过程很简单,两步走:

第一步,客户对facade发起请求。

第二步,facade将请求转发给合适的子系统。

2 pureMVC中的facade

pureMVC与设计模式之二. Facade模式与Singleton模式_第2张图片

图2. Façade接口

pureMVC中有一个名为façade的package,明确指出使用的是façade模式。图2是façade接口中的所有函数。从成员函数很容易看出,façade类包括了对MVC中所有部件的操作,比如Model使用的proxy在这里进行注册和删除(registerProxy/removeProxy等),Controller使用的command在这里提供操作函数(registerCommand/removeCommand等),以及View需要的mediator也在这里操作(registerMediator/removemediator等)。除此之外,façade还提供对事件的控制接口,notifyObserver接口可以将该之间(INotification)发送出去。通过时间循环,对该事件感兴趣的observer都会收到通知。其中的细节我们会在observer模式中仔细分析。

再进一步,看看代码是如何实现的。

首先facade是作为一个单例的实现的,单例的好处,稍后会介绍。
先来看facade的初始化,其中我们可以看到在facade的初始化时候,分别初始化了mode,view和controller三个子模块
[java]  view plain copy print ?
  1. protected Facade()  
  2.     {  
  3.         initializeFacade();  
  4.     }  
  5.   
  6.     /** 
  7.      * Initialize the Multiton <code>Facade</code> instance. 
  8.      *  
  9.      * <P> 
  10.      * Called automatically by the constructor. Override in your 
  11.      * subclass to do any subclass specific initializations. Be 
  12.      * sure to call <code>super.initializeFacade()</code>, though.</P> 
  13.      */  
  14.     protected void initializeFacade( )  
  15.     {  
  16.         initializeModel();  
  17.         initializeController();  
  18.         initializeView();  
  19.     }  
  20. protected void initializeController()  
  21.     {  
  22.         if( controller != null )  
  23.             return;  
  24.   
  25.         controller = Controller.getInstance();  
  26.     }  
  27. protected void initializeModel()  
  28.     {  
  29.         if( model != null )  
  30.             return;  
  31.   
  32.         model = Model.getInstance();  
  33.     }  
  34.     protected void initializeView()  
  35.     {  
  36.         if( view != null )  
  37.             return;  
  38.   
  39.         view = View.getInstance();  
  40.     }  

控制协作看,看下面两个代码片段:
[java]  view plain copy print ?
  1. public void registerCommand( String noteName, ICommand command )  
  2. {  
  3.     controller.registerCommand( noteName, command );  
  4. }  

[java]  view plain copy print ?
  1. public void notifyObservers( INotification note )  
  2. {  
  3.     if( view != null)  
  4.         view.notifyObservers( note );  
  5. }  

可以说,pureMVC这里的facade模式实现的干净漂亮,是一个很好的范例。以后的系统设计中,可以借鉴。

二、pureMVC中的singleton模式

1. singleton 模式介绍

single模式非常简单,说的是系统中,一个类只有以后一个实例。如图三所示。在某些场合是非常需要的,比如,系统中只能有一个文件系统,一个会计系统只能专用于一个公司等。这个和具体的语义有关,这里不深入讨论。singleton可以作为改进的全局变量来使用。singleton类也可以有子类,通过子类来扩展和配置原有的应用,可以很容易的增强功能。

pureMVC与设计模式之二. Facade模式与Singleton模式_第3张图片
图三、单例模式

singleton类更大的挑战在他的实现,即如何才能让一个类只有一个实例。
a. 私有化构造函数 private/protected, 并定义一个静态的实例。
   使用唯一一个static类来获取实例。
b. 对每一个singleton的实例定义那么,然后将这个<name, object>对注册到一个统一的注册表,需要的时候从其中查找。

需要着重考虑的问题:
1. 是多线程安全问题,如何保证多线程能够正确安全的初始化并且获取到同一个实例。常见的解决办法,是静态初始化和double-check( http://blog.csdn.net/jiafu1115/article/details/6757629)。
2. 序列化。一般来说,单例的对象最好不要序列话。因为很容易从序列化后的数据中重新构建一个新的实例,进而破坏了单例的原则。

2. pureMVC中的单例

pureMVC作为一个框架,是整个应用系统的核心部分,那么他的几个部件,controller,model和view在整个系统中自然应该只有一份。这个在语义上很好理解,model管理所有的数据,view管理所有的视图,controller则管理控制流。
从上面facade初始化的代码中,大家已经看到,所有component,包括facade,是通过一个getInstance()来获取实例的,具有很明显的单例模式的特征。下面我们看看初始化的代码。
[java]  view plain copy print ?
  1. public class Model implements IModel  
  2. {  
  3.   
  4.     /** 
  5.      * Singleton instance 
  6.      */   
  7.     protected static Model instance;  
  8.     protected Map<String, IProxy> proxyMap;  
  9.     protected Model()  
  10.     {  
  11.         instance = this;  
  12.         proxyMap = new HashMap<String, IProxy>();  
  13.         initializeModel();  
  14.     }  
  15.     protected void initializeModel( )  
  16.     {  
  17.     }  
  18.     public synchronized static Model getInstance()  
  19.     {  
  20.         if( instance == null)  
  21.             instance = new Model();  
  22.   
  23.         return instance;  
  24.     }  
  25.   
  26. ......  
  27. }  
其他几个模块的初始化代码与之类似,就不再赘述。

三、总结:

singleton模式和facade是在framework中非常常见,这是由framework的特性决定的。framework是一个可以多次服用的代码集合,用framework来构建应用程序时候,只要在适当的地方填上具体的业务逻辑即可。但是业务逻辑不可避免的需要和framework中的多个component打交道,facade模式则把这些交互都集中到了一起,大大减少了复杂性。从这里可以初步看到facade为什么会在这出现。

另一方面,framework中的组件都是经过良好设计的,他们之间都是的交互也是良好定义的。他们在系统中一般应该也只应该出现一次,这是singleton的经常在framework中出现的语义基础。比如MFC框架中的theApp,便是一个整个app框架的singleton。


转自:http://blog.csdn.net/cpfeed/article/details/7391048

你可能感兴趣的:(设计模式,mvc)