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

对于业务逻辑的组织,个人认为,最好是使用 DDD(《Domain Driven Design》) 的方式。DDD 使用领域模型来表达实体间的关系,同时在应用层使用 Service 来组织各实体间的过程式代码。二者构成了整个应用程序的核心业务逻辑(《Pattern of Enterprise Application Architecture》)。

 

OEA 是一个基于 DDD 思想的框架。在 OEA 中,使用了 Service、Controller 来组织过程式逻辑。结构如下图: 

对于大型系统来说,OEA 中的 Service 主要作为分布式调用、本地调用的 Facade 接口,主要的业务过程则使用 Controller 来编写。对于小型系统来说,则可以直接把业务过程逻辑都编写在 Service 中。

 

在设计 Controller 时,应该特别注意两点: 
* 扩展点:Controller 中表达业务过程行为的过程式方法,可以被扩展。这种扩展不应该改动调用方的代码。 
* 单向依赖:Controller 之间应该是单向依赖的。否则,将会造成业务逻辑混乱。

 

我以最近编写的一个仓库管理产品的类图,来说明如何设计,能更好地达到以上两点: 

该仓库管理产品的业务逻辑使用 Controller 组织。在编写完成产品后,可以编写扩展程序集,为产品主干程序集中的业务逻辑编写扩展。 
Client:主干程序集中的客户端程序,它调用服务完成分布式调用逻辑。 
Service:主干程序集中的服务程序,它调用工厂创建 ReceiveController 来间接完成入库逻辑。 
ReceiveController:主干程序集中的入库业务控制器,它会组织入库相关的各个领域模型(如仓库、货品等),来完成相关业务。 
ReceiveControllerExt:扩展程序集中的入库业务控制器。它继承自主干程序集中的 ReceiveController,并重写了基中的 Receive 方法,提供了新的入库业务逻辑。 
MoveController:主干程序集中的移库业务控制器。它依赖入库控制器,需要在入库业务控制器中货品到达后,执行它指定的移库逻辑。入库控制器不能依赖移库控制器,这样,某些场景下,就可以把移库控制器去除,以达到简单入库、不执行移库逻辑的目的。 
OEA.Controller: 框架提供的控制器基类,“层基类模式”。 
OEA.ControllerFactory:框架提供的控制器工厂。使用工厂模式封装了所有业务控制器的构造过程,提供以下功能: 
1. 具体控制器的创建。 
创建具体子类的控制器,而不需要修改调用方代码。例如:当 Service 指定构造 ReceiveController 时,如果已经加载了 ReceiveControllerExt 类型扩展,则 ControllerFactory 会返回 ReceiveControllerExt 类型的实例,使得执行被扩展后的业务逻辑。 
2. 控制器事件的自动挂接。 
控制器声明所依赖的其它控制器,框架会自动调用其相关的挂接程序。例如:MoveController 依赖 ReceiveController,并使用 ControllerFactory 中的方法来声明需要监听 ReceiveController 中的 Received 事件。则 ControllerFactory 在创建 ReceiveController 时,也会创建一个 MoveController 的实例,并使其挂接到 ReceiveController.Received 事件上。这样就不需要改动 ReceiveController 的代码。

 

其实,整个设计主要是使用“简单工厂模式”来封装了业务控制器的构造过程,而达到扩展的效果。 
不过由于在面向对象设计中,虚方法扩展、事件扩展是最常用的扩展设计(《Framework Design Guidelines 2nd Edition》),而同时业务控制器的设计基本上都需要这两类扩展,所以总结一下这个常用的控制器设计,以方便使用。

 

 

 

 

--------------------------------

附,使用此方案后,整个仓库系统中 Controller 的重构成果如下。解耦前:

解耦后:

 

简化图,解耦前:

解耦后:

时间: 2024-11-05 16:27:10

OEA 中的业务控制器设计模式的相关文章

OEA 中 WPF 树型表格整体重构

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

iOS 中的 21 种设计模式

iOS 中的 21 种设计模式 对象创建原型(Prototype) 使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象. 1 2 NSArray *array = [[NSArray alloc] initWithObjects:@1, nil]; NSArray *array2 = array.copy; array 就是原型了,array2 以 array 为原型,通过 copy 操作创建了 array2. 当创建的实例非常复杂且耗时,或者新实例和已存在的实例值相同,使用原型模式

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

 本次重构主要是针对OEA框架中的AutoUI部分.这个任务在月初时计划在一个月内完成,包括问题分析.设计新的结构.编写设计文档.开展设计评审.代码实现.提交评审.本系列文章用于记录整个过程中的关键项.     本篇文章主要记录了在设计评审会议前我所做的工作,包括: 历史状况分析 重构目标 逻辑设计方案 结构关系图   历史状况分析     由于是重构,所以我们需要弄清楚当前的问题是哪些,历史代码的结构,为什么这样的结构会造成这些问题.历史代码的结构原来已经写过相关的文章:<OpenExpres

《工业控制网络安全技术与实践》一一2.3 工业控制系统中的常用控制器

2.3 工业控制系统中的常用控制器 控制器(Controller)是指按照预定顺序通过改变主电路或控制电路的接线和改变电路中电阻值来控制电动机的启动.调速.制动和反向的主令装置,是发布命令的"决策机构",完成协调和指挥整个计算机系统的操作. 在工业控制系统中,常见的控制器有可编程逻辑控制器(PLC).可编程自动化控制器(PAC).远程终端单元(RTU)等,下面分别加以介绍.2.3.1 可编程逻辑控制器 可编程逻辑控制器(Programmable Logic Controller,PLC

Windows系统中配置域控制器时别忽视DNS设置

域控制器是公司网络管理的核心,它出现故障往往会导致全网用户计算机的登录失败.不过,大家在建立域控制器时往往忽视了对DNS的设置,致使域中的DNS频频引发故障.你是否知道DNS的重要性呢?如果DNS设置出问题会带来什么样的后果呢?笔者负责公司服务器的维护工作,最近在实际工作中就遇到了一起突发的与DNS相关的服务器故障. 故障现象 公司规模不是很大,大概有50多台计算机,购买了两台IBM服务器.由于内部使用的某个应用软件需要Windows域的支持,所以在这两台IBM服务器上启用了windows 20

在SOA中实现业务规则和业务流程

使用面向服务的体系结架构(SOA)的其中一大动力在于提升企业的敏捷度,并将不可避免的改变所带来的影响减到最小.这一般通过把经常改变和相当稳定的实现工件进行分离来完成.支持这种分离的常用方法是分解(decomposition)和封装(encapsulation).SOA的分解导致服务的定义代表更稳定的工件,而业务流程则代表更经常变化的工件1.在一个典型的SOA实现中,服务不会经常改变,但是非常经常地被组合和重组来构建/修改企业的解决方案. 这种分解不会直接标明业务规则的位置--整体IT实现中另一个

OEA中的缓存模块设计

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

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

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

OEA 中的多国语言实现

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