如何封装页面数据对象

[ 转载请注明出处 CSDN wangkaisine http://blog.csdn.net/wangkaisine/article/details/47832859 ]

前言&主题

最近在重构一个比成熟的Web应用,对这个应用页面中的数据对象进行了封装,对于很多系统甚至其他网站页面都用通用性,现在将主要的内容写出来,予以交流。

  • 页面数据对象
  • 页面对象组合
  • 页面对象抽象
  • 页面对象代码重用
  • Java代码示例

页面数据对象

为什么要封装页面数据对象?

Web数据如何显示放在页面上,是我们需要解决的问题,数据对象能够实现通用的页面数据封装,大大减少后端代码数量,方便我们使用页面实例向页面中填塞数据,且程序更易读懂。

如何封装页面数据对象_第1张图片

这是我们常见的web页面布局,其中header和footer区域,一般来说都是固定不变的,所以我们需要考虑content区域的数据元素。

而在content中,常见的数据对象包括以下的navigator、title、form、table等,其中navigator是统一的,因此也不必封装成后台对象。那么主要就是form和table对象需要在后台进行封装了。

如何封装页面数据对象_第2张图片

navigator在页面中,可以直接使用js和静态div,来陈列它的内容和样式。我们已经说了导航栏完全可以放在前端去生成和操作,因此不再这里叙述。

如何封装页面数据对象_第3张图片

下面我们来讲讲详细的页面数据封装:

如何封装页面数据对象_第4张图片

我们定义页面中最小的数据元素就是cell,用来承载数据、保存链接以及定义样式class,我们从cell中分化成两种cell,一种叫做name cell,另外一种是data cell,它们有着不同的行为模式和方法。只在表现上有相同的地方,就是都属于表格或表单的一小块内容。然而name cell用来保存table表头的变量名值,或者form表单的属性名值,而data cell用来保存数据。

页面对象组合

如何封装页面数据对象_第5张图片

如上图所示,我们使用cell了组合成不同的row,作为form或者table的行,多个cell组成一个row。例如,多个data cell组成了一个data row,它用来包括表格内的数据。多个name cell组成了一个name row,它用来表示table的第一行表头变量。一个name cell和一个data cell组成了form row,它用来表示form中的每一行属性(attribute)以及值(value)。

这样一个form的数据格式就如下图所示:
如何封装页面数据对象_第6张图片

一个datatable的数据格式就如下图所示:
如何封装页面数据对象_第7张图片

一个from的content的布局就如下图所示:
如何封装页面数据对象_第8张图片

如果你认为本文就是在简单讲这样的页面元素封装方法,那你就错了,这样的封装真的就只是方法,而不是技术。下面我们就讲讲技术的事情。

页面对象抽象

name cell:

name cell是一行属性数据,或者一列数据的表头,因此可以在它的属性中包括name,dbName,来映射它和数据库中某一字段的对应关系。在初始化页面content的时候,将table中的name row初始化,加入一个一个的name cell。

name cell还应该拥有一个helper类,来帮助我们改变和控制显示数据的格式与样式。可以创建接口NameCellHelper,其他的DefaultNameCellHelper,LinkNameCellHelper,NumberNameCellHelper,DateNameCellHelper等,来实现这个接口,这些类可以在后端对数据进行处理。

name cell helper作为一个属性(String)放在name cell中,在这个name cell被添加到table时,使用工厂获取这个属性对应的helper类示例,同时这个cell就有了对应的helper。像这样的helper,以及表格中的name cell,在启动应用的时候,就可以加载到应用中,也就是说,创建出了一个一个表格或表单的模板,它们只是还没有数据而已。在用户查询之后,表格才显示。

data table:

是从table类继承来的数据表格类,保存查询结果数据,作为一个通用的表格对象,它的name row和每一个data row都是等长的。

data table的列控制器主要就是由表头的NameCellHelper决定的,我们初始化的helper不多,但是每个name cell映射的helper确实绑定在每一个表的某一列上的,在每一行数据在输入时,需要每一列数据得到该列的helper,并输出自己的样式。

页面对象代码重用

在之前我在写Java Web的时候,需要为每一个不同的功能模块的表格或者表单写一个form或者table类,来承载这些搜索前后的数据。但是有了这样统一化的数据对象,就可以实现更高层次的代码重用。

这样的数据对象定义我写到了一个文件夹下(domain),可以理解为一个页面数据对象的资源库,再使用这些资源库中的元素,拼装成我们需要完成的功能的content页面,content的属性就包括title、form、table等这些动态数据对象。方便content做统一的数据输出。

完成一个简单的搜索功能时,你只需要定义一个servlet(其实对于servlet也可以封装的更好,没必要每个功能都定义),在servlet执行完后,转到这个功能的搜索结果页面,在这个页面中引用通用的result页面,在页面中写的是设置table的各个属性,以及数据的值,这样所有的搜索功能都可以在跳转页面之后,共同引用这个页面,数据就被加载出来了。

Java示例代码

name cell定义:

public class NameCell extends Cell {
    private String name;
    private String dbName;
    private String nameCellHelper;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }

    public String getNameCellHelper() {
        return nameCellHelper;
    }

    public void setNameCellHelper(String nameCellHelper) {
        this.nameCellHelper = nameCellHelper;
    }

    public NameCell(String name,String dbName){
        this.name = name;
        this.dbName = dbName;
    }

    public NameCell(String name,String dbName,String nameCellHelper){
        this.name = name;
        this.dbName = dbName;
        this.nameCellHelper = nameCellHelper;
    }

}

使用cell、row拼装的table可以这样写:

import java.util.List;

public class Table {
    private String title;
    private String sql;
    private List paramaternames;
    private String sqlForTotal;
    private String sqlForCount;
    private String emptyMessage = "";
    private String dbTableName;
    private int columnIndex = 0;

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getSql() {
        return sql;
    }
    public void setSql(String sql) {
        this.sql = sql;
    }
    public List getParamaternames() {
        return paramaternames;
    }
    public void setParamaternames(List paramaternames) {
        this.paramaternames = paramaternames;
    }
    public String getSqlForTotal() {
        return sqlForTotal;
    }
    public void setSqlForTotal(String sqlForTotal) {
        this.sqlForTotal = sqlForTotal;
    }
    public String getSqlForCount() {
        return sqlForCount;
    }
    public void setSqlForCount(String sqlForCount) {
        this.sqlForCount = sqlForCount;
    }
    public String getEmptyMessage() {
        return emptyMessage;
    }
    public void setEmptyMessage(String emptyMessage) {
        this.emptyMessage = emptyMessage;
    }
    public String getDbTableName() {
        return dbTableName;
    }
    public void setDbTableName(String dbTableName) {
        this.dbTableName = dbTableName;
    }
    public int getColumnIndex() {
        return columnIndex;
    }
    public void setColumnIndex(int columnIndex) {
        this.columnIndex = columnIndex;
    }

}

data table就可以按照这样的方式封装:

import java.util.List;

import cn.***.com.wangkaisine.domain.row.DataRow;
import cn.***.com.wangkaisine.domain.row.NameRow;

public class DataTable extends Table {
    private NameRow nameRow;
    private List dataRow;

    public NameRow getNameRow() {
        return nameRow;
    }
    public void setNameRow(NameRow nameRow) {
        this.nameRow = nameRow;
    }
    public List getDataRow() {
        return dataRow;
    }
    public void setDataRow(List dataRow) {
        this.dataRow = dataRow;
    }

}

后记

虽然用了很多的文字来说明这一方法,但还没有很详尽的表述如何封装和具体使用这些对象,希望以后继续加油!

你可能感兴趣的:(java-web)