OEA中的AutoUI重构(2)- 评审会议前的总体设计

 本次重构主要是针对OEA框架中的AutoUI部分。这个任务在月初时计划在一个月内完成,包括问题分析、设计新的结构、编写设计文档、开展设计评审、代码实现、提交评审。本系列文章用于记录整个过程中的关键项。

    本篇文章主要记录了在设计评审会议前我所做的工作,包括:

  1. 历史状况分析
  2. 重构目标
  3. 逻辑设计方案
  4. 结构关系图

 

历史状况分析


    由于是重构,所以我们需要弄清楚当前的问题是哪些,历史代码的结构,为什么这样的结构会造成这些问题。历史代码的结构原来已经写过相关的文章:《OpenExpressApp 框架结构(1)》、《OpenExpressApp 框架结构(2)》。这里主要说一下现有的问题。

    为了收集更全面的问题列表,我和每一个开发人员、测试人员、需求人员进行了沟通。以下以基于OEA框架的GIX4应用程序为例子,来说明现有的问题:

    从用户角度看

用户觉得,当前生成的界面不好看,虽然可以换多套皮肤,但是布局太死,不能更换一些新的布局。

另外,用户提出目前的界面中,有一些弹出窗体的界面与整个应用的风格不统一。

    从开发人员的角度看

由于我本身也是一名开发人员,平时也记录了一些小问题,觉得AutoUI目前存在的问题主要有这些:

    理想中的AutoUI:

目前的元数据包含太多信息,没有进行分离,界面生成时需要的元模型应该是纯净的。

元数据应该是可以持久化的,这样不但可以在持久层对元数据进行修改,而且更好地支持了产品的客户化。

 

重构目标


    以上的问题中,并不是所有的都需要一次性完成,经过过滤、排序,得到以下的目标列表:

    质量属性中,优先级自上而下慢慢变低。

    因为我们用的是OEA框架中的AutoUI模块,该模块的目标就是自动生成界面,以简化界面的开发、统一界面的模式、重用界面开发模式,所以可重性自然是最重要的。需要完成系统90%以上的界面生成。在默认情况下,能够生成一个完整的应用程序。这些需要生成的可重用构件包括:
大粒度:应用程序界面框架、布局模块、数据列表、树型数据列表、实体编辑面板、导航栏、工具栏等。
小粒度:按钮、属性编辑器等。

    其次,在保证可重用性的前提下,就需要保证系统的可扩展性,这也是本次重构需要重点考虑的。原来的系统中,应用程序的生成已经完全实现,但是预留的扩展点并不多,导致扩展起来并不容易。现在,需要在设计时,估计未来的应用模式并留下更多的扩展点,这些扩展点可能包括:布局模式的扩展、界面生成算法的扩展、生成后的控件的局部扩展等。当然了,更多的扩展点很可能需要在具体代码开发时才知道,到时再设计扩展点并将其文档化下来。

    其它的比较简单,不再一一具体解释。

 

逻辑设计方案


    整个逻辑设计过程,主要按照以下的几个过程展开:

    约束是指重构时需要考虑的一些限制条件。由于目前OEA已经在产品GIX4上应用,而GIX4中代码量并不小,所以这里主要的一个约束是:重构后的AutoUI模块的外部接口需要兼容原有系统。(当然,这个约束并不是100%严格,但是可以作为一个约束条件,在设计时酌情考虑。)

    然后就是细化整个重构的目标:

    需求细化后,其实就开始系统的类库结构设计了。主要还是画一些类图、包图。同时,记录一些设计的要点、权衡点。在整个设计完成后,再次回顾了质量属性。这些过程过于细节,在此就不细讲了。

 

两张重要的草稿


    上图是构思中的重构后的AutoUI的结构图。

    上图是如果扩展控件生成方案。本来是作为OEA中开发人员使用XAML编写控件的支持,不过后来决定这次暂时不实现。(主要是考虑到升级困难和模型驱动的思想有冲突。)

 

最终设计的类的结构图



    先是AutoUI涉及到的逻辑组件的依赖图

 

 

重构后整个设计的逻辑层图

 

以下是各个包内的详细设计

ViewEntity 与 Entity 分离:

图中显示的是三种可能的视图实体和领域实体的关系。使用下图中的关系来支持多样的视图模型:

 

 

 

逻辑控件/控件编辑器

 

 

布局模式

 

 

界面元数据:

单个界面组成单元的元数据

 

整个界面的元数据

这张图是本次设计中最重要的地方,它组织了多个单个块的元数据(UIBlockDefinition)来形成界面的聚合元数据(AggregateBlocks)。每个UIBlock都可以进行布局样式的应用、整个AggregateBlock也可以应用布局样式。

该设计并不是单向依赖的,最重要的几个类紧耦合在了一起。由于我觉得这样的核心元数据再进行抽象会不易于理解,所以没有再为其分离接口进行解耦。

 

 

控件工厂

 

 

逻辑视图控制器

 

 

生成界面的流程控制器

ViewControlGenerator

RegionContainers

LayoutManager

 

AutoUI 流程控制器

客户程序使用方法

AutoUI流程概要

 

小结 


    这些设计还都只是个人的构想,还需要经过接下来的设计评审后才能正式进入实现阶段。总的来说,自己觉得界面元数据那块的设计还是有点难于理解。不过时间比较紧,先就这样了。等待评审结果……

 

PS:

从开始收集问题到画出所有的设计,花了我几天的时间。一些问题还是在梦中想明白的,哈哈。不过发现最近自己效率有点低,有时候想问题专注不下来,想着想着就又乱了。

另外,这篇文章发得有点晚,其实评审会议已经完成了,下一篇会总结评审后的设计。

时间: 2024-09-17 13:49:46

OEA中的AutoUI重构(2)- 评审会议前的总体设计的相关文章

OEA中的AutoUI重构(3)- 评审会议后的设计

设计改动     大家认为 AggregateBlocks 和 BlockDefinition 的设计过于复杂,不易于理解.考虑的东西太多,有过度设计之嫌,所以这一处的设计改为使用Composite模式来组合"UI块":       另外,上次的设计中,有一个小错误:不应该把元模型的仓储 UIInfoRepository 放在单个的界面组成单元中,而是应该放在更上层的整个界面的元模型层.   相应的任务计划     会议中,大家还提出为这些任务进行简单的任务排序.计划,这样可以更好并行

OEA中的AutoUI重构(1) - Command自动生成

OEA框架的核心之一是AutoUI,其职责是面向领域模型及UI元模型进行生成统一的界面.     在本次的迭代开发中,需要对命令按钮的生成方式进行一些定制.由于原来并没有为这样的需求留有特别的扩展点,加之原来的生成代码是过程式的代码.且也变得比较冗长,所以我们决定对这一部分的代码进行重构. 原来的模式     历史代码中,为某一实体类生成命令按钮的流程是这样的: 找到实体类可用的所有命令按钮元数据. 对它们进行过滤,依靠权限.版本的客户化元信息等. 构造几个生成控件的List容器,分别是:ite

OEA 中 WPF 树型表格整体重构

为什么要重构       上两个月主要做了一件事情,那就是把 OEA 框架中的 TreeGrid 控件,从结构上重新设计,并大量重构现有代码.而花较大精力做这件事的原因,主要是因为: 业务中需要支持一系列新功能:整行编辑.上下箭头键进行导航.合计行.锁定列 等. 控件显示性能较差,需要支持列虚拟化. 和 OEA 元数据系统耦合,希望独立为单独的控件程序集,提高复用性. 不支持 xaml 声明的格式.原控件直接在后台用 OEA 代码生成,本质上作为一个 WinForm 控件来用. 整个 TreeG

12月反思 - 组内设计评审会议

现象     这个月我的工作任务中,有一项是重构OEA框架中的AutoUI部分.这个任务在月初时计划在一个月内完成,包括问题分析.设计新的结构.编写设计文档.开展设计评审.代码实现.原计划半天到一天的评审会议,最后花费了大概一天半的时间.接下来,我就评审会议中出现的问题进行一下总结.     本次AutoUI设计是我到公司以来,觉得最有挑战的一次工作.    会议之前,我和组内的人员进行了多次沟通,了解他们的需求:我们的AutoUI框架当前有些什么问题?当界面需求被提出后,我们对它的完成情况怎么

OEA 中的业务控制器设计模式

对于业务逻辑的组织,个人认为,最好是使用 DDD(<Domain Driven Design>) 的方式.DDD 使用领域模型来表达实体间的关系,同时在应用层使用 Service 来组织各实体间的过程式代码.二者构成了整个应用程序的核心业务逻辑(<Pattern of Enterprise Application Architecture>).   OEA 是一个基于 DDD 思想的框架.在 OEA 中,使用了 Service.Controller 来组织过程式逻辑.结构如下图: 

OEA 中 WPF 树型表格虚拟化设计方案

    最近用 OEA 做的仓库管理系统中,许多界面的都需要使用表格控件来显示数据.一是这些表格的列非常多,有的甚至达到了 200 列,而且一个模块的界面中可能同时显示好几个表格.这导致界面的速度比较慢,特别是较多数据需要展现时.经检测,表现虽然表格的行已经做了虚拟化,但是由于列非常多,最终还是造成可视树中的元素过多,而导致界面布局代码运行过慢.假设只有 30 行,一个单元格仅生成 5 个可视元素,200 列的单元格都会产生 3W 个可视元素,而布局系统的 Measure 方法需要对可视树中的每

OEA中的缓存模块设计

  项目组目前开发的基于OEA框架的GIX4项目,本次功能已经完成得差不多了,本次迭代的目标主要是提升产品的性能.由于GIX4是C/S结构的应用程序,所以决定实现缓存模块来提升高繁数据访问的缓存.     本篇文章主要介绍了OEA框架中的缓存模块设计与一般的缓存有什么不同,如何在OEA框架中实现缓存模块.分为以下几个小节: 一般缓存介绍 OEA缓存目标 概要设计 通用缓存框架的详细设计 OEA中集成Cache的详细设计 小结 一般缓存介绍     网上介绍缓存的文章比较多,在这里我就挑点重点说一

OEA 中的多国语言实现

  本篇博客主要描述在 OEA 框架中的多国语言框架的原理及应用.   多国语言常见实现及原理分析     管理软件平台,一般来说,都应该支持多国语言,以支持应用程序走向国际化.OEA 最近也提供了多国语言框架,它可以在修改少量甚至不修改代码的情况下,快速.灵活地,使得整个应用软件支持各个国家的语言.在 .NET 平台上,要实现多国语言切换,一般可以使用资源文件实现:在WPF中,也可以使用动态引用实现.这些可以参考以下几篇文章中讲到的方法:<WP7多国语言支持>.<一种灵活的WPF程序多

c++-请问在这个约瑟夫问题中,把数组定义在main()函数前与下面程序中定义的数组方式 有什么异同?

问题描述 请问在这个约瑟夫问题中,把数组定义在main()函数前与下面程序中定义的数组方式 有什么异同? 请问在这个约瑟夫问题中,把数组定义在main()函数前与下面程序中定义的数组方式 有什么异同? 为什么在VC6.0中认为示例程序的数组错误,而在dev C++中却没事 #include <iostream> #include <iomanip> //调用setw()函数 using namespace std; //bool str[101]; int main() { int