前言
业务组件的设计是非常重要的工作,如果你没有正确的设计业务组件的话,结果很可能就是代码难以维护和扩展。在设计和实现应用的时候,有多种类型的业务组件。包括业务逻辑组件,业务实体,业务流程或者是工作流组件,工具和帮助组件。
设计步骤
1 确定在应用中将会使用的业务组件
在业务层,你需要创建和使用各种类型的组件来处理业务逻辑。本步骤的目标就是如何识别这些组件,发现应用需要的组件。下面的步骤帮助你确定你需要那些组件:
- 考虑使用业务逻辑组件来封装业务逻辑和应用状态。业务逻辑是一种集中于实现业务规则和行为的应用逻辑,同时包括维护全局的一致性,例如数据合法性验证。业务逻辑组件应该设计成容易测试的、独立于表现层和数据访问层。
- 考虑使用业务实体作为领域模型的一部分,来代表真实世界的业务实体,例如产品和订单。
- 如果你的应用需要支持以一种特殊的顺序进行多进程处理,考虑使用业务工作流组件。使用在多个业务逻辑组件之间进行交互所需的业务规则。通过升级工作流组件就可以改变应用的行为。如果应用一定要实现根据业务规则实现动态的业务逻辑的话,考虑使用工作流组件。考虑使用WF实现工作流组件,考虑和微软的BizTalk Server环境整合。
2 为业务组件做关键的决定
web应用中的业务组件通常处理消息为基础请求,windows form应用通常处理事件为基础的请求。另外,不同类型的应用关注点也不同。一些因素是不分应用类型的,一些因素又是每个应用类型特有的。你一定要处理的关键问题包括:
- 部署位置。你的业务逻辑组件是放在客户端吗?还是应用服务器?还是两者都有?如果应用是富客户端应用或者是RIA,想要提高性能,使用领域模型设计业务实体,考虑在客户端放一些业务组件。如果要支持多种客户端类型,如果业务组件需要访问客户端访问不到的资源,或者是安全原因,考虑将业务组件放在应用服务器上。
- 耦合。表现层组件如何与业务组件交互?是应该设计一个表现层直接知道业务组件的紧耦合,还是一个对表现层屏蔽实现细节的业务组件松耦合。如果你是一个富客户端类型或者是RIA,可以考虑紧耦合表现层和业务组件。但是松散耦合可以提高可测试性和灵活性。如果你有一个富客户端类型或者是RIA应用,将业务组件部署在应用服务器或者是web服务器,为它们之间的交互设计一个服务接口,来实现松散耦合。
- 交互。如果业务组件和表现层组件部署在同一个物理层,考虑使用通过事件和方法的组件为基础的交互,来最大化性能。但是,如果表现层和业务层部署在不同的物理层,考虑使用服务接口和消息为基础的交互方式。
3 选择适当的事务支持
业务组件负责协调和管理业务层需要的事务。但是第一步是决定是否需要事务支持。事务用来确保一些的行为都可以执行,例如数据库事务。事务以一个单独的单元来完成。如果单元中的一个行为失败,其他的行为会回滚,确保系统的一致性状态。例如:有一个操作需要更新三张表,如果一个失败,两个成功,数据库将会处于不一致状态,这时候适合用事务来执行,一个失败,大家都回滚到事务之前的状态,保证了一致性。事务包括下面的一些类型:
- System.Transactions。使用业务逻辑初始化和管理事务。包括在.NET 2.0中,实现轻量的事务管理。
- WCF Transactions。在.NET 3.0中引入,如果和WCF service进行交互,考虑使用WCF Transactions。
- ADO.NET Transactions。
- Database。
4 确定业务规则如何处理
业务规则的管理是应用最有挑战性的设计之一。通常业务规则用于业务层。但是,他们会在业务层的那里呢?你可以放在业务逻辑或者是工作流组件,或者是一个独立的业务规则引擎,又或者是包含在领域模型设计的业务实体中。参考下面的选项:
- 业务逻辑组件。
- 工作流组件。
- 业务规则引擎。
- 领域模型设计。将业务规则包括在业务实体中。
5 确定满足需求的设计模式
设计模式 | 推荐原因 |
Adapter适配器模式 | 允许没有兼容接口的类在一起工作,允许开发者实现一个多态的类为现有了类提供一个可替代的实现。 |
Command | 推荐在富客户端应用的菜单、工具条、键盘快捷键中使用,不同的组件执行相同的命令。 |
Chain of Responsibility | 可以用来代替if 。。。then。。。else语句,可以处理复杂的业务规则。 |
Decorator | 通过添加和修改操作,在运行的时候扩展对象的行为。需要一个通用的接口,有一个Decorator类来实现它。可以处理复杂的业务规则。 |
Dependency Injection | 使用一个独立的类创建对象和成员,通常基于配置文件在运行的时候创建依赖关系。配置文件中指明类型的映射关系。提供一个修改行为的灵活方式,从而实现复杂的业务规则。 |
Facade | 提供粗粒度的操作,统一多个业务组件的结果。典型的应用是,在业务层为以消息为基础的接口实现一个远程的外观,用来在表现层和业务层提供一个松散的耦合。 |
Factory | 不用指定的类型创建对象实例,需要对象实现通用的接口,或者是继承一个基类。 |
Transaction Script | 在很少的业务规则的CRUD操作中推荐使用。 |