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

原创 2012年03月24日 22:18:20

引言

上篇文章,我们分析了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交互就可以了,降低了耦合度。


图1. Façade模式

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

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

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

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

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

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

2 pureMVC中的facade


图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三个子模块
protected Facade()
	{
		initializeFacade();
	}

	/**
	 * Initialize the Multiton <code>Facade</code> instance.
	 * 
	 * <P>
	 * Called automatically by the constructor. Override in your
	 * subclass to do any subclass specific initializations. Be
	 * sure to call <code>super.initializeFacade()</code>, though.</P>
	 */
	protected void initializeFacade( )
	{
		initializeModel();
		initializeController();
		initializeView();
	}
protected void initializeController()
	{
		if( controller != null )
			return;

		controller = Controller.getInstance();
	}
protected void initializeModel()
	{
		if( model != null )
			return;

		model = Model.getInstance();
	}
	protected void initializeView()
	{
		if( view != null )
			return;

		view = View.getInstance();
	}

控制协作看,看下面两个代码片段:
	public void registerCommand( String noteName, ICommand command )
	{
		controller.registerCommand( noteName, command );
	}

	public void notifyObservers( INotification note )
	{
		if( view != null)
			view.notifyObservers( note );
	}

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

二、pureMVC中的singleton模式

1. singleton 模式介绍

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


图三、单例模式

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

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

2. pureMVC中的单例

pureMVC作为一个框架,是整个应用系统的核心部分,那么他的几个部件,controller,model和view在整个系统中自然应该只有一份。这个在语义上很好理解,model管理所有的数据,view管理所有的试图,controller则管理控制流。
从上面facade初始化的代码中,大家已经看到,gegecomponent,包括facade,是通过一个getInstance()来获取实例的,具有很明显的单例模式的特征。下面我们看看初始化的代码。
public class Model implements IModel
{

	/**
	 * Singleton instance
	 */ 
	protected static Model instance;
	protected Map<String, IProxy> proxyMap;
	protected Model()
	{
		instance = this;
		proxyMap = new HashMap<String, IProxy>();
		initializeModel();
	}
	protected void initializeModel( )
	{
	}
	public synchronized static Model getInstance()
	{
		if( instance == null)
			instance = new Model();

		return instance;
	}

......
}
其他几个模块的初始化代码与之类似,就不再赘述。

三、总结:

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

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



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

AsWing 入门

环境准备 说白了AsWing就是一套用AS3写成的类库,所以只要有编译AS3程序的环境,就能使用AsWing。 从编译环境来说基本就是2种,一个是Flash CS3,另一个就是 flex sdk。开发...

PureMvc个人笔记

学习资料:pureMv中文指南,C++

关于指针的使用

关于指针的使用2007年10月24日 星期三 10:58 用变量a给出下面的定义 ...

facade设计模式

Facade 外 观模式,是一种结构型模式,它主要解决的问题是:组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合 面临很多变化的挑战。在这里我想举一个...

PureMVC 游戏框架解析

http://blog.csdn.net/kenkao/article/details/50291991 作者:吴秦 出处:http://www.cnblogs.com/s...
  • anypkv
  • anypkv
  • 2016-07-11 10:48
  • 1445

pureMVC与设计模式之一. 结构与工作流

引言  设计模式是软件开发人员的九阳神功。设计模式有基本的23种,九阳神功有九层。学习设计模式容易看似会了生搬硬套,修炼九阳神功容易根基不稳走火入魔。但是,如果最后都深刻理解,融入贯通的话,无疑已是...
  • cpfeed
  • cpfeed
  • 2012-03-18 18:30
  • 2347

一步一步学习TypeScript(03.let与const)

letES6中有两个新特性:let和 const,为了理解let,让我们看看let与var声明变量的区别:if(true){ let a = 5; var b = 6; con...

PureMVC 游戏框架解析

作者:吴秦 出处:http://www.cnblogs.com/skynet/ 本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名吴秦(包含链接). ...
  • kenkao
  • kenkao
  • 2015-12-14 11:07
  • 2920
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)