张艳明 张敏
摘要:针对传统表单定制的不足,提出一种基于抽象工厂模式的动态表单设计方案.该方案以抽象表单元素工厂引擎为核心,利用表单元素数据预处理模块加载的表单数据,动态实现了表单元素产品的构建,最终由表单动态构建组件完成表单元素的组装.企业级开发应用实践表明,该模式可以快速、灵活构建Web表单,满足多UI风格的运行需求,提高了表单的可维护性和扩展性.
关键词:表单定制;动态表单;抽象表单元素工厂
中图分类号:TP311 文献标识码:A 文章编号:1673-260X(2019)06-0050-03
1 引言
Web表单是一种实现互联网产品用户界面交互的重要组件.传统的Web表单开发主要采用事先编写好的静态HTML页面,这种开发模式直接简单[1-2].但对于表单数量多、表单样式和表单元素内容存在频繁变动需求的企业应用,传统表单开发方式已经无法适应,其缺点也显而易见,复用程度不高,扩展性差,开发效率非常低下[3-4].
与此同时,在移动互联网时代,Web前端技术的发展速度越来越快,各式各样的终端UI框架如雨后春笋般涌现.表单的开发和实现方式也在发生着巨大的变化,朝着更加兼容和开放的方向发展[5].目前市面上的动态表单定制更多基于某一种特定的UI风格,无法适应页面风格的灵活切换.
本文提出一种基于抽象表单工厂模式、面向多UI框架风格的动态表单实现方案.该设计旨在进一步提升表单开发的效率,满足不同UI偏好风格开发人员的动态表单个性化定制需求.
2 抽象工厂模式
GoF(Gamma, Helm, Johnson & Vlissides, Addison-Wesley)在1995年出版的《Design Patterns: Elements of Reusable Object-Oriented Software》一书中提出了23种经典的Java设计模式,产生了巨大的影响,一直延续至今,抽象工厂模式是其中之一.
抽象工厂模式向客户端提供一个接口,在不必指定具体产品类的情况下,用于创建相关或者依赖对象的家族[6-7].抽象工厂模式的类图如图1所示.
AbstractFactory抽象工厂定义成接口,接口包含一组工厂方法用来生产产品,所有具体工厂实现该接口.实现接口的具体工厂ConcreteFactory1,ConcreteFactory2用于生产不同的产品家族.客户使用具体的工厂去创建一个具体的产品对象,不需要自己去实例化产品.
AbstractProductA,AbstractProductB為相关产品的接口,与实现接口的具体产品们构成产品家族,每个具体工厂都能够生产一整组的产品.按照这种设计逻辑,客户代码中只需依赖于抽象工厂,根据运行时动态绑定原理,将自动使用实际的工厂.
3 基于抽象工厂模式动态表单的总体设计
3.1 设计思路
本文借鉴抽象工厂设计模式,通过抽象表单元素工厂,来创建表单元素产品家族.将表单及包括文本框、下拉列表、单选按钮组、复选框组等在内的各类表单元素都表示成产品,对每一类产品的共性进行提取,形成对应的抽象表单和元素产品接口,由实现这些接口的具体产品类负责具体实现.表单元素产品的创建通过工厂负责完成,对不同风格工厂的共性进行提取,形成对应的抽象表单元素工厂接口,由实现该接口的具体表单元素工厂负责具体实现.
通过抽象表单元素工厂提供的接口,可以创建表单元素产品的家族,能够在不同上下文中实现各式各样的表单元素工厂,制造出各种不同的表单元素产品,比如不同的HTML版本,不同的UI外观样式等.
设计遵循依赖倒置原则,表单的创建者依赖于抽象,而不依赖具体类.因为代码从实际的产品中解耦了,可以替换不同的表单元素工厂来获取不同的表单元素产品.
构成表单的各类元素产品构建完成后,再进行组装完成表单的创建.可以将表单的创建过程看待成一个XML文档树的生成过程,遍历所有的表单元素,利用XML操作API,根据表单元素的位置属性,将表单元素一一附加在XML文档树中正确的位置.
表单元素的各类数据属性,包括位置属性,采用数据库表的形式进行存储,为了适应表单字段动态变化,表单元素表按照Key-Value的形式进行纵向存储,每一行存储一个独立的表单元素字段内容.
3.2 总体架构
基于抽象工厂模式动态表单的构成部分主要包含抽象表单元素工厂引擎、表单元素数据预处理模块、表单动态构建组件及相关表单产品对象家族.表单元素预处理模块根据传入的待创建表单参数,负责从关系数据库中的动态表单数据存储表中读取相关联的表单元素属性,并以列表的形式存储在内存中,供抽象表单元素工厂引擎使用.抽象表单元素工厂引擎通过服务管理接口动态加载待构建的表单元素属性,再根据配置数据启动具体的表单元素工厂,完成具体表单元素的生成过程.最后,调用表单动态构建组件,按照XML文档树的生成规则,循环遍历表单元素并将其附加在文档树的相应位置,最终完成一个具体风格表单产品的构建和显示.总体架构如图2所示.
3.3 类图
FormElementFatory是抽象的表单元素工厂接口,它定义了如何生产相关表单元素产品的家族.BootStrapFEFactory,JQueryEasyUIFEFactory这些具体工厂负责生成具体表单元素,每个工厂都知道如何生产符合自己风格的表单元素对象.根据开发需要,可以实现其他不同风格的表单元素工厂.关于表单元素产品家族,上图列出了Input,Select,对于这些表单元素产品,每个工厂都有不同的实现.FEFactoryClient是抽象表单元素工厂的客户,通过依赖注入,在运行期间动态绑定具体的工厂,最终产生具体的表单及元素产品.
4 动态表单实现
4.1 表单数据存储模型
基于抽象工厂模式动态表单设计已经应用于安徽合大环境检测办公平台的研制开发,该应用面向环境检测行业领域,涉及的业务范围广泛,指标体系丰富多样,涵盖水质、气体、固废、噪声等诸多方面,需要展现的具体表单数量非常巨大且变化因素很多.该应用的动态表单数据存储模型(部分字段)如图4所示.
4.2 表单元素工厂引擎
下面给出抽象表单元素工厂引擎在运行期间涉及的部分核心类和服务接口及其使用说明.
Form:抽象类,内部持有表单元素对象列表引用,主要方法包括prepare(),createElement()和buildTree()等,prepare完成表单构建的初始化准备工作,载入表单数据到元素对象列表中,createElement方法设计成模板方法,在prepare准备完毕后,完成表单元素对象列表中各个表单元素的具体创建工作,创建过程由具体实现类调用依赖注入的表单元素工厂负责完成.bulidTree方法将创建完成的表单元素组装成完整的表单HTML文档树,通过调用4.3节描述的动态表单构建组件来实现.
4.3 动态表单构建组件
其中,executeInsert方法负责将FormElement表单元素对象动态附加到文档树的正确节点位置.该方法首先根据表单元素的行位置属性,查询定位到行所在文档节点根元素,再通过add(index,element)方法附加到指定列位置.如果上述行定位查詢结果为空,则创建新的行元素.灵活起见,executeInsert方法可以被定义成抽象方法,由具体子类实现,在运行期间动态决定行列元素的创建方式.
5 结束语
本文从实际需求出发,提出了基于抽象工厂模式的动态表单设计方案,实现了不同风格表单元素产品的动态构建和组装,通过实践应用证明了方案在Web动态表单开发方面的高效性,并具有较好的灵活性和可扩展性.
参考文献:
〔1〕喻莹莹,李新,陈远平.前后端分离的终端自适应动态表单设计[J].计算机系统应用,2018,27(4):70-75.
〔2〕潘华,孙林夫,刘述雅.面向SaaS平台的动态表单定制技术研究[J].计算机应用研究,2013,30(10):3026-3029.
〔3〕张佳强,王士同.信息管理系统动态表单技术的研究与实现[J].计算机应用与软件,2010,27(8):83-87.
〔4〕王刚,程建平.面向业务的敏捷界面定制构件的设计[J].微型机与应用,2012,31(7):11-16.
〔5〕杜艳美,黄晓芳.面向企业级web应用的前后端分离开发模式及实践[J].西南科技大学学报,2018,33(2):83-87.
〔6〕Gamma E, Helm R, Johnson R, et a1.设计模式:可复用面向对象软件的基础(英文版)[M].北京:机械工业出版社,2002.
〔7〕华铨平,庞倩超,谢颖.抽象工厂设计模式在3层结构开发中的应用[J].大庆石油学院学报,2009,33(3):112-115.