3.6 《硬啃设计模式》 第15章 超级文档编辑器 - 代理模式(Proxy Pattern)

你要做一个能和Word比美的文档编辑器,其中一个重大功能是:文档中能插入很多图片。
但如果文档的图片太多,文档加载的速度将会变得很慢,于是你想到的方法是不必所有图片都直接显示出来,可以先显示一个带叉叉的虚拟图片,当用户停留在当前图片时,才加载真正的图片。
不过除了图片,如 视频 、flash等其它可能需要耗大量资源的东西可能也需要这样处理。
你打算如何设计呢?

最开始你的设计是这样的:

3.6 《硬啃设计模式》 第15章 超级文档编辑器 - 代理模式(Proxy Pattern)_第1张图片  

这个设计的要点如下:
1.文档中的图片、Flash、多媒体等元素,都实现了Element接口。
2.DocumentEditor可以不区别是Graphic、Flash还是Media,只需要调用Draw()方法,就可以在屏幕上画出相应的东西来。
3.如果以后需要增加新的元素,只需要实现Element接口就可以了,DocumentEditor不需要修改代码。
说明:DocumentEditor不一定是具体的一个类,是泛指除了Element、Graphic、Flash、Media以外的程序。

这个设计其实挺漂亮的,不过还有这样的问题未解决:
1.对于Graphic,如何先显示一个带叉叉的虚拟图片呢?而Flash、Media应该先显示什么虚拟的东西呢?
2.显示虚拟东西的代码写到哪里呢?在DocumentEditor写吗?还是在Graphic、Flash、Media中各自处理?
   1)如果在DocumentEditor写这些代码,则需要在DocumentEditor中写一堆 if else 或者是 switch case ,以后每增加一种元素就要修改这些代码,麻烦!
   2)如果在Graphic、Flash、Media中各自搞定,那么需要在各自的Draw()方法中各自判断当前是需要画虚拟东西还是画具体的内容。这样做好像还可以,不过好像将这些判断逻辑写进各类中似乎增加了各类的责任,总觉得不太合适,如果能分离出来就好了。

应用了代理模式的设计如下:

3.6 《硬啃设计模式》 第15章 超级文档编辑器 - 代理模式(Proxy Pattern)_第2张图片  

说明:
1.本设计在原来设计的基础上,为Graphic、Flash、Media各自增了两对应的Proxy。
2.这些Proxy都实现了Element接口,并且含有对应被代理的类的引用。
3.每个Proxy要判断当前需要画虚拟的东西还是画具体的内容,如果需要画虚拟的东西,则由自己来处理,如果需要画具体的内容,则调用被代理类的Draw()方法。
4.对于DocumentEditor来说,它实际得到的是一个一个Proxy,但因为Proxy同样也是实现了Element接口,所以DocumentEditor的代码不需要做任何修改。
5.如果需要增加一个新元素,则需要增加一个类以及它的Proxy,都实现Element接口便可。
代理模式精妙之点在于代理和被代理者实现了相同的接口,包揽了被代理者不适合干的事情,对于外界来说,只要访问代理就可以了,反正它会包办一切。

以下情况可考虑应用代理模式:
1.不希望某些类被直接访问。
2.访问之前希望先进行一些预处理。

3.希望对被访问的对象进行内存、权限等方面的控制。





请看下一文……
 
 
 

作者:张传波

创新工场创业课堂(敏捷课程)讲师

软件研发管理资深顾问

CMMI首席专家

《火球——UML大战需求分析》作者

《硬啃设计模式》作者

www.umlonline.org创办人



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