设计模式在GIS中的应用
一、设计模式概述
随着面向对象技术的广泛应用,软件复用在越来越多的开发工程中被采用。在研究软件复用的过程中,设计模式的概念被提了出来。所谓设计模式就是一些设计面向对象的软件的经验总结,它的出现可以说是面向对象理论发展的一个重要的里程碑。地理信息系统(GIS)是一种特定而又十分重要的空间信息系统,它是以采集、贮存、管理、处理分析和描述整个或部分地球表面(包括大气层在内)与空间和地理分布有关的数据的空间信息系统。它不仅要处理一般的、规则的属性数据,还要处理海量的、复杂的空间数据,通常是一个复杂而又庞大的系统,开发起来比较耗费时间和财力。因此GIS的重新实现或者重新修改都是一项耗费巨大的工程。在地理信息系统的软件开发中导入设计模式的思想会在提高地理信息系统质量的同时,提高系统的可复用性、可扩充性和可移植性,从而实现降低成本、分享开发经验等目的。在《设计模式—可复用面向对象软件的基础》书中一共提出了23种设计模式。
二、GIS中应用设计模式的必要性
在地理信息系统开发中,为了开发的基础组件可以重用,我们通常是用面向对象的方法封装成类库,然后客户端程序调用。然而,随着当前GIS软件开发日益的复杂化和大型化,如何做到代码重用、类重用以及组件重用是一个严峻的考验。而设计模式可以解决GIS中常见的问题域。
三、常见设计模式在GIS中应用
1、工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法(Factory Method)使一个类的实例化延迟到其子类。也叫虚构造器(Virtual Constructor)。
在GIS底层几何对象模型中,通常需要一个几何抽象基类Geometry,从而可以派生出许多具体的实体类,如Point,PolyLine等。当要创建一个Geometry对象时,我们可以用基类的指针实际指向子类,然而,随着类的增多,管理起来就不方便。这时,我们可以通过抽象工厂方法,将创建对象的过程封装在工厂方法中。
2、组合模式
组合模式常用于构成树形的“整体-部分”之间的关系。在GIS中,地理事物常被抽象为点、线和面三种基本类型。线由点构成,面由首尾相连的线串构成。如下图所示:
3、桥接模式
桥接模式主要是将抽象部分和实现部分分离,对两者进行修改可以独立进行互不依赖。在继承体系中也可以实现这样的操作,那就是模板方法,但是当需求变化时,也会造成类层次的庞大,不利于管理。
在GIS中一个最主要的功能当然是地图的显示了。地图显示过程中通常要用到坐标转换,例如地理坐标和设备坐标之间的转换,这里的设备可以包括计算机屏幕、打印机或者绘图仪等。显示过程中必要要进行放大、缩小、平移等操作。如果将这些操作都写到地图类MAP中,这将会造成地图类的庞大臃肿。如果将这些操作封装在另外一个类DisplayManager中,地图类MAP中保存一个指向DisplayManager类的指针,具体的操作过程交由DisplayManager去完成。下图是具体的类图。
4、模板模式
模板模式最主要的特征是虚基类定义一系列的接口,具体实现的部分交给实体类重写这个方法去完成。例如,在GIS系统中,几何对象模型中就可以用模板方法。虚基类Geometry可以定义一些接口如求面积、长度、绘制等函数。然而,这些函数针对不同的具体类就会有不同的实现,其思想非常简单。
5、命令模式
命令的意图:为一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤消的操作。
在GIS系统中,经常会遇到地理要素的编辑,需要redo/undo。这时就可以向系统发出这些操作的命令,可以先实现一个基类Command,实现逻辑操作接口,然后根据不同的操作去实现真正的操作。它的类图如下。
命令模式还可以和备忘录模式结合完成undo的操作,也就是取消操作。
6、策略模式
策略模式和模板模式解决的问题是相似或者说是相同的。在GIS中,数据类型多种多样,可能会根据应用的需求增加新的数据源。各个数据的数据格式是不一致的,以及他们的原生编程接口也是不一致的。例如shapefile的原生编程接口是shapelib,大名鼎鼎的GDAL/OGR类库就是用这个接口读写shapefile的数据;oracle spatial的C/C++读写接口就是OCI/OCCI。还有各种其他数据,可以说,你就是专做数据格式转换都能将你累垮。如果GIS系统没有考虑到多种格式的需求,那么将来需要应用其他数据格式的时候需要大量改动现有代码的设计,那将是一场灾难,我们并不希望这样。为了能够支持多种数据格式,并对外提供统一的接口支持读写,我们可以采取策略模式。例如对于文件型的数据可以先读取索引文件,然后根据索引文件读写相应位置的几何数据。这样,对外暴漏的接口只要按照接口去存取数据就可以了,而不需要关心数据的底层是如何读写的。当有新的数据类型需要加进来的时候,只需要加入一个对应的新的策略类就可以了。具体的类图如下:
7、单例模式
单例模式可以说是最简单的设计模式,它主要是通过一个类维护一个静态成员变量来记录唯一的对象。在GIS中,由于空间数据类型众多,许多系统针对每一种数据格式都会有一个Driver来读写数据,然而这么多的驱动可以由一个DriverManager来进行方便的管理。在一个系统中,如果驱动管理器很多,这个驱动管理器里面有一个shapefile的驱动,那个驱动管理器里面也有一个shapefile的驱动,这就会造成管理的混乱。所以说,我们要限制驱动的个数为一个就能防止这类问题的发生。
四、后记
当然,本文不可能面面俱到,把23种设计模式如何应用到GIS开发中全部进行讲解不太可能,某些设计模式目前也弄得不是特别明白。欢迎大家一起讨论GIS软件设计中的设计模式,高手就别喷了。