No silver bullet
设计方法的分类:
1. 结构化设计(自顶向下)——没有提供适当的方法解决并发性问题。
2. 数据驱动设计——广泛应用于信息管理系统,它关注系统的输入输出。
3. 面向对象设计——适应复杂开发并具有良好复用性。
面向对象的本质:抽象、封装、多态、继承。第一要着的抽象是不确定的,它具有层次,可以排列成为一种层次。
框架——软件复用的发展方式:程序主体反主为客,并让辅助组件反客为主,即控制反转。如果一个程序库负担了整个应用程序来于运行的主干算法,并实现了主动的事件循环、事件处理机制、控制流程。则为框架。
所谓的应用架构的外在本质是把“技术问题和业务问题分离”,而其内在本质是抽象,把一个系统抽象为技术和业务。以达到技术的复用。任何一个系统都存在技术问题,虽然他们的业务问题可能不一样。
技术层面上,建立一个应用架构从宏观层面来看第一要著是使系统结构化,结构化的途径有三个:分层,管道和过虑,黑板。
分层模式是一种解决打系统的良好的方法,无论是J2EE还是.Net都应用这种技术。本质上讲分层是抽象的排列。因为大系统复杂性较高,它的抽象层面也相应较多。
管道和过虑通过用来解决数据流的较好方式。
黑板则是用来解决不确定性问题的首要途径。当一个问题解决方法缺乏一定模式,而现有的方法集中的每个方法都只能解决问题的一个部分,并各自不相交。黑板可以成为较好的抽象机制。
因此开发一个应用系统,分层成为设计的首先。以下将详细讨论分层模式下的抽象机制:
(图1)
数据访问逻辑层采用domain model,同时使用object/relational mapping pattern的Data mapper pattern和active record pattern向上提供数据访问服务。而在Data mapper和active record中进行concurrency pattern进行并发性控制。
如下图:
(图2)
业务逻辑层分成三个部分,如下图:
(图3)
基础:
1. 业务实体由实体集和实体组成,这些来自数据访问逻辑层。
2. 业务规则定义了对业务实体内部关系,以及业务实体间的关系。
1.业务实体内部关系:(除非只有一个规则,否则)可以采用职责链模式。(这样可以避免过多的条件判断。)
2.业务实体外部关系:
2.1 非强制一对多:可以采用职责链模式。(这样可以避免过多的条件判断。)
2.2 强制一对多:采用observer观察者模式。
2.3 多对一:可以采用mediator中介者模式。
3. 业务外观把业务实体和业务规则统一起来。
中级:
1. 考虑一个业务规则,其有严格的限制,联系到多个业务对象,同时其关系成网状,例如:一个实体的方法实现必须满足多个实体的状态值,大量的条件判断不可避免。当系统复杂性提高时,网状的关系将不可避免。此时采用以上简单的方法不能满足要求。这时采用扩展有限状态机来实现将可以解决问题。
2. 业务外观层联系实体和规则,当业务的流程性很强时可以采用工作流技术。同时无论是否采用工作流技术,但系统复杂性提高时,应该采用扩展有限状态机来做控制系统。
高级:
1. 业务规则和业务外观的外在本质上是一个控制系统。业务规则实现状态的转换,而业务外观委派状态的行为。
在业务规则层采用传统方法设计,将不可避免得造成如下之一的情况:1. 控制器庞大而条件判断过多; 2. 产生多个控制系统;3. 多态后系统控制系统之间继续关联关系复杂。造成控制系统维护的困难性提高。 而解决方案就是: 有限状态机。作为一个严格的数学模型,其在状态转换的控制上有明显的优势。
2. 业务逻辑的内在本质上只是一个抽象——解决计算方法、约束条件、转换状态三个问题的控制系统的抽象
表现层:
基础:
表现层作为系统用户界面层,有两个工作:1.界面转换控制;2.用户交互数据收集及其完整性与有效性验证。
1. 界面的转换控制: 当系统的转换复杂化后,对转换的控制变的难以接受,系统将出现多个控制器,对系统的行为变的不可把握。因此在这一层可以采用扩展有限状态机来作为控制系统,这样可以保证系统的行为在可控制范围内,同时可以实现分布式协调控制。
2. 用户交互数据收集及其完整性与有效性验证: 用户界面另一个重要工作。对其的验证包括:1. 对数据的有效性如格式,系统可接受范围检查;2. 数据收集的完整性,例如:1.一些数据用户必填;2. 当用户选择某个选项后,另一些数据成为必填。
同时一个系统的界面将是多而复杂,在每个界面中实现将变的复杂而困难, 因此必须通知统一的交互数据控制器+XML配置文件进行控制。
高级:
表现层为一个交互应用系统,要解决的最大问题保持内核独立于用户接口,解决方法有三种:MVC和PAC。
MVC应用较广泛。本质是变更传播机制确保用户接口和模型间的一致性。
PAC(Presentation-Abstaction-Control)应用较少,但是它解决了MVC没有解决的问题——怎样有效组织功能内核的不同部分和用户接口间的通信。因而这个模式尤其适用于由几个不同自给子系统组成的系统。本质是利用agent抽象层。
然而根据已知,抽象还同时具有不确定性,因而从技术的另一个角度看一个应该架构的抽象还可以如下排列。
技术问题——本质上是一个控制系统的抽象排列:
命名服务。
持久服务。
事务处理。
分布式访问用。
资源管理(资源的创建和销毁)。
实例的标识和管理。
缓存和池化。
出错处理。
对应这些抽象技术问题,一个应用架构中必须包含如下服务中心:
1. Core中心。提供核心服务和运行环境。采用组件配置模式和接口模式
提供缓存服务。
提供事务服务。
提供代理服务。
提供工厂服务。
载入Name服务接口。
载入EP服务接口。
2. Name中心。
提供注册接口和运行入口接口。
提供查询接口。
3. Auth中心。提供验证服务和注册服务。
提供验证加密服务。
提供授权码服务。
4. Service中心。提供应用服务。
提供运行入口。
实现事务服务。
载入通讯服务接口。
载入同步和并发接口和服务。
5. Pesistence中心。提供统一的持久化服务。
提供统一的CUID接口。
6. UIForm中心。提供界面载入服务。
提供装载Service服务接口。使用扩展有限状态机控制界面间转换。
7. DataRule中心。提供交互数据收集的完整性和有效性验证。
8. Community中心。提供通讯服务。
提供通讯服务接口。
9. Concurrency中心。提供同步和并发接口和服务。
10. EP中心
提供事件处理模式接口。
完成多路分解工作。
11. BizRule中心。
使用扩展有限状态机控制业务规则。
12. WorkFlow中心
提供工作流管理服务。可以采用使用扩展有限状态机控制。
No silver bullet
不要过度设计或者过度工程。不要为不存在的扩展做设计。因为代码一旦存在,通常代码并不会被删除,因为那样很麻烦,容易导致问题,而你期待着它将在某个时候被使用。于是代码随着系统增长变的冗长,变得需要更多的人来维护。不幸的事,当更多得人加入时,分工产生了,于是代码被重复,系统再一次增加。当新人加入,每个人都必须读懂旧的代码,尽管它没有用。
软件开发的第一特性是可操作性。在面向结构时代,算法是可操作性的代表,可以通过一个阶段的重复性操作得到问题的解。在面向对象时代,模式则为代表。从这个意义上看,模式和算法是一致的,它们反映了人们对世界可操作性的认识。
然而有什么理由认为:所有的东西都具有可操作性的?这样的观点我们证明过吗?当我们将这种理论推广到“世界所有的东西都是对象”的时候,我们对于理性、可操作性的过分信任已经让我们陷入了狂妄和自大。
软件开发的可操作性的主体——需求。我们存在的需求电阻。需求不存在或者需求不正确时,我们失去了操作主体