ArcGIS Engine中的设计模式——工厂模式

在使用AE打开或者加载数据的第一步就是 通过工作空间工厂(IWorkspaceFactory)获取工作空间(IWorkspace),然后从工作空间中获取数据集(DataSet)、要素类(FeatureClass)、表(Table)等数据。

对于不同类型的空间数据库,对应着不同的工作空间类,这些类都继承了接口IWorkspaceFactory,然后通过IWorkspaceFactory接口的不同的方法如Create、Open、OpenFromFile产生不用类型的工作空间(IWorkspace)。

这种模式就是面向对象设计模式中的工厂模式,当我们想要扩展新的数据类型时,只需要创建对应的工作空间类,这个类继承自IWorkspaceFactory,然后创建相应的工作空间类,这个类继承自IWorkspace接口。 这样满足了依赖倒转的原则,实现了易维护,易重用,易扩展,灵活性好的设计。

我们来看一下类和接口之间的关系:

如果我们有新的数据类型,只需要创建如图所示的类,继承自IWorkspaceFactory接口即可。

其中Workspace类中包含了我们的大部分类型(file、geodata、sde)的对工作空间中数据的管理方法,我们也可以进行扩展,创建如图所示的类,继承自IWorkspace接口即可。

例子:

打开ShapeFile文件:

IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactoryClass();
IWorkspace pworkspace = workspaceFactory.OpenFromFile(string_ShapefileDirectory, 0);

打开个人空间数据库:

  IWorkspaceFactory pAccessWorkspaceFactory = new AccessWorkspaceFactory();

   IWorkspace pWorkspace = pAccessWorkspaceFactory.OpenFromFile(pFullPath, 0);

打开SDE空间数据库:

  IWorkspaceFactory pAccessWorkspaceFactory = new SdeWorkspaceFactory();

  IWorkspace pWorkspace = arcSDEWorkspaceOpen("192.168.70.110", "esri_sde", "sde", "sde", "", "SDE.DEFAULT");

接下来对pWorkspace 中的数据进行操作。

假如我们现在要扩展空间数据类型,我们构造了一种“文本空间数据(txt)”,我们就要对现有的类和接口进行扩展。

首先我们创建工厂类TxtWorkspaceFactory,继承自IWorkspaceFactory,然后创建接口ITxtWorkspace接口,该接口中有对TxtWorkspace中数据的操作方法,然后创建TxtIWorkspace类,继承自IWorkspace接口和ITxtWorkspace接口,在TxtWorkspaceFactory类编码对数据的操作。

则实现代码如下:

  IWorkspaceFactory ptxtWorkspaceFactory = new TxtWorkspaceFactory();

   IWorkspace pWorkspace = ptxtWorkspaceFactory .OpenFromFile(pTxtPath, 0);

  ITxtWorkspace txtWorkspace = pWorkspace  as ITxtWorkspace ;

  txtWorkspace 中的方法完成数据操作。

我猜想大概在ArcGIS Engine中也是这样架构的,达到易扩展,易维护、易重用和灵活性的效果。

在实际的开发中,我们可以借用配置文件中的信息来自动实例化某种数据,实现依赖注入。

<LocalFile IsEnable="true" MxdPath="C:\Users\ZHU\Desktop\To师姐\201301001_详查\201301001_详查.mxd"/>
<SDEServer IsEnable="false">
<ServerItem IsEnable="true" DBType="Oracle" IP="192.168.1.1" DBName="" Service="5151" SDEUser="SDE" SDEPassword="SDE" Version="SDE.DEFAULT" ConnectionType="ServiceConnect"/>
</SDEServer>

根据配置文件判断是那种数据类型,然后读取相应的参数,获得工作空间IWorkspace。

在GIS开发中,我们的框架通常使用单例模式进行创建,框架中包含 项目的信息、项目的坐标系信息、项目的MapControl、PageLayoutControl等。

/// <summary>
/// 宿主程序
/// </summary>
public partial class SBApplication : ISBApplication,ISBStatusControl, ISBMapStatuesControl,ISBDockManager
{
private const string LOGNAME = "SBApplication";
private static ISBApplication m_AppContext;
private static bool m_IsInitAppContext = false;

private Form m_platForm;//主窗体
private RibbonControl m_ctrlRibbon;//Ribbon控件
private DockManager m_platDock;//DockManager
private RibbonStatusBar m_platStatusBar;//状态栏
private AxMapControl m_platMapControl;//MapControl
private AxTOCControl m_platTOCControl;//TOCControl
private TabbedView m_platTabbedView;//多文档窗体
private ImageList m_imageList;//图标集合
private ISBTool m_currentTool;//当前操作工具
private List<PopupMenu> m_lstPopupMenus;//地图右键弹出菜单

private XtraTabControl m_tabControl;//TabControl
private string m_version;//版本

private EnumLoadSpatialDataType m_loadSpatialDataType;//空间数据加载类型
private SystemMenu m_systemMenu;//系统菜单配置

//返回静态宿主程序类AppContext
public static ISBApplication AppContext
{
get { return m_AppContext; }
}

/// <summary>
/// 构造函数,为地图控件和Button控件,TOC控件绑定事件。
/// </summary>
/// <param name="platForm"></param>
/// <param name="platDock"></param>
/// <param name="platTabbedView"></param>
/// <param name="platMapControl"></param>
/// <param name="platTOCCOntrol"></param>
/// <param name="imageList"></param>
private SBApplication(RibbonForm platForm, DockManager platDock, TabbedView platTabbedView, AxMapControl platMapControl,AxTOCControl platTOCCOntrol, ImageList imageList)
{
m_platForm = platForm;
m_ctrlRibbon = platForm.Ribbon;
m_platDock = platDock;
m_platTabbedView = platTabbedView;
m_platStatusBar = platForm.StatusBar;
m_platMapControl = platMapControl;
m_platTOCControl = platTOCCOntrol;
m_imageList = imageList;

m_loadSpatialDataType = EnumLoadSpatialDataType.LoadSDELayer;

m_ctrlRibbon.ItemClick +=new DevExpress.XtraBars.ItemClickEventHandler(m_ctrlRibbon_ItemClick);

m_platMapControl.OnMouseDown +=new IMapControlEvents2_Ax_OnMouseDownEventHandler(m_platMapControl_OnMouseDown);
m_platMapControl.OnMouseMove +=new IMapControlEvents2_Ax_OnMouseMoveEventHandler(m_platMapControl_OnMouseMove);
m_platMapControl.OnMouseUp +=new IMapControlEvents2_Ax_OnMouseUpEventHandler(m_platMapControl_OnMouseUp);
m_platMapControl.OnDoubleClick +=new IMapControlEvents2_Ax_OnDoubleClickEventHandler(m_platMapControl_OnDoubleClick);
m_platMapControl.OnKeyDown +=new IMapControlEvents2_Ax_OnKeyDownEventHandler(m_platMapControl_OnKeyDown);
m_platMapControl.OnKeyUp +=new IMapControlEvents2_Ax_OnKeyUpEventHandler(m_platMapControl_OnKeyUp);
m_platMapControl.OnExtentUpdated +=new IMapControlEvents2_Ax_OnExtentUpdatedEventHandler(m_platMapControl_OnExtentUpdated);
m_platMapControl.OnFullExtentUpdated +=new IMapControlEvents2_Ax_OnFullExtentUpdatedEventHandler(m_platMapControl_OnFullExtentUpdated);
m_platMapControl.OnMapReplaced +=new IMapControlEvents2_Ax_OnMapReplacedEventHandler(m_platMapControl_OnMapReplaced);
m_platMapControl.OnSelectionChanged +=new EventHandler(m_platMapControl_OnSelectionChanged);
m_platMapControl.OnAfterDraw +=new IMapControlEvents2_Ax_OnAfterDrawEventHandler(m_platMapControl_OnAfterDraw);
m_platMapControl.OnViewRefreshed +=new IMapControlEvents2_Ax_OnViewRefreshedEventHandler(m_platMapControl_OnViewRefreshed);

m_platTOCControl.OnMouseDown +=new ITOCControlEvents_Ax_OnMouseDownEventHandler(m_platTOCControl_OnMouseDown);
}

/// <summary>
/// 初始化宿主程序入口
/// </summary>
/// <param name="platForm">主界面</param>
/// <param name="platDock">DockManager</param>
/// <param name="platTabbedView">多文档窗体</param>
/// <param name="platMapControl">地图控件</param>
/// <param name="platTOCCOntrol">TOC控件</param>
/// <param name="imageList">图标集合</param>
public static void InitAppContext(RibbonForm platForm, DockManager platDock, TabbedView platTabbedView, AxMapControl platMapControl, AxTOCControl platTOCCOntrol,ImageList imageList)
{
if (!m_IsInitAppContext)
{
if (platForm == null || platDock == null || platTabbedView == null || platMapControl == null)
{
return;
}
m_AppContext = new SBApplication(platForm, platDock, platTabbedView, platMapControl, platTOCCOntrol,imageList);
m_IsInitAppContext = true;
}
}

通过静态方法获取宿主程序

SBApplication.InitAppContext(this, dockManager1, tabbedView, axMapControl1, axTOCControl1, imageList1);
SBApplication.AppContext.Version = m_systemMenuAdmin.Version;
SBApplication.AppContext.LoadMenuPlugins(m_systemMenuAdmin);

m_AppContext = SBApplication.AppContext;

这里大概包含了所有的设计模式中创建对象的模式,ARCGIS Engine中还包含了很多的设计模式,后面再叙述吧····

时间: 2024-07-29 08:56:35

ArcGIS Engine中的设计模式——工厂模式的相关文章

设计模式--简单工厂模式之在springboot中使用简单工厂模式

1.前言: 不了解简单工厂模式请先移步:在商城中使用简单工厂.在这里主要是对springboot中使用简单工厂模式进行解析. 2.问题: 什么是简单工厂:它的实现方式是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例. 然而在Spring中,在启动容器对时候会通过beanFactory先创建初始化我们要用的类. 一个是要在使用的时候去创建一个产品类,一个是预先已经加载好了我们要使用的对象,那我们要如何解决这个问题呢? 3.场景:在一个商城系统中,用

ArcGIS Engine中的8种数据访问 (转)

数据是GIS的基础, 访问数据也是进行任何复杂的空间分析及空间可视化表达的前提.ArcGIS支持的数据格式比较丰富,对不同的数据格式支持的程度也有很大差异.本文主要介绍一下以下八种数据格式在ArcGIS Engine中如何访问.对ArcGIS桌面应用有一定了解的读者更适合阅读本文.本文的示例代码是用C#编写. 1.Shapefile 2.Coverage 3.Personal Geodatabase 4.Enterprise Geodatabase 5.Tin 6.Raster 7.CAD 8.

ArcGIS engine中Display类库 (局部刷新)

转自原文 ArcGIS engine中Display类库 (局部刷新) Display类库包括了用于显示GIS数据的对象.除了负责实际输出图像的主要显示对象(display object)外,这个类库还包含了表示符号和颜色的对象,用于控制在显示(display)中绘制时实体的属性.这个类库也包含了用户与显示(display)交互时的可视化反馈的对象.完成这些功能的对象被归并到一组类库子系统中. 这些类库子系统是: n         Display n         Dynamic Displ

6.大话设计模式-工厂模式

工厂模式和简单工厂有什么区别.废话不多说,对比第一篇例子应该很清楚能看出来. 优点: 工厂模式弥补了简单工厂模式中违背开放-封闭原则,又保持了封装对象创建过程的优点. using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace DesignModel{    public interface Factory   

[转载]ArcGIS Engine 中的多线程使用

ArcGIS Engine 中的多线程使用 原文链接 http://anshien.blog.163.com/blog/static/169966308201082441114173/   一直都想写写AE中多线程的使用,但一直苦于没有时间,终于在中秋假期闲了下来.呵呵,闲话不说了,进入正题! 大家都了解到ArcGIS中处理大数据量时速度是相当的慢,这时如果你的程序是单线程的,那可就让人着急坏了,不知道处理到什么地步,不能操作其他的功能,无奈~~如果在这时你能够想到用多线程技术,那就来试试该如何

设计模式---工厂模式---生产水果

设计模式---工厂模式 需要一个基本的抽象类:相当一个基本的工厂 需要若干个具体类:相当若干个产品 需要工具类:相当工厂中机器,用来选择不同的产品生产 需要主类:相当顾客所想的订单 主类 ----> 工厂类 ----> 产品类 ---> 产品具体类 老板根据顾客的订单,在工具堆中选择合适的,然后去工厂中生产适合的产品,返回给顾客 优势:能够在不修改原先的代码情况,增加所需的类与方法. 不足:会增多类文件的数量 接口:提供的内容,相当于协议,即外界使用此接口时,接口的内容是不允许外界对接口

设计模式——工厂模式学习

1.概念 工厂模式定义:实例化对象,用工厂方法代替new操作.达到解耦的目的(避免硬编码耦合).工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式. 工厂模式是我们最常用的模式了,著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见.因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例

二十三种设计模式——工厂模式

二十三种设计模式--工厂模式 简单工厂模式 简单工厂模式又称静态工厂方法(StaticFactory Method)模式,不属于23种模式之一. 简单工厂模式是工厂模式最简单使用的模式. 类图: 程序: #include <iostream> #include<string> using namespace std; class NationalFlag//父类 { public: NationalFlag(){} ~NationalFlag(){} virtual void di

设计模式-工厂模式[Factory]

先看下一个简单的实现: 1 package org.masque.designpatterns.factorymethod.one; 2 /** 3 * 4 * Description: Sample子类的标示 5 * BeanEm.java Create on 2014年7月11日 下午2:37:58 6 * @author [email protected] 7 * @version 1.0 8 * Copyright (c) 2014 Company,Inc. All Rights Res