S
shsshashssha
Unregistered / Unconfirmed
GUEST, unregistred user!
关键字:多层结构,Multi-Tier,软件设计,组件,表示层,商务层,数据层
摘要: 本文主要讨论软件系统多层结构设计的思想观念。
如果没有社会化大分工,人类能有今天如此丰富的物质文明和精神文明成果吗?如果没有社会化大分工,你还能悠闲地阅读这篇文章而不用考虑衣食住行所需物资的生产问题吗?
作为人类历史上文明进步的一个重要标志,社会化大分工使得社会中的每个个体在有限的资源条件下可以只专注于自己的特定工作,同时又可以与他人交换工作成果,这极大地提高了整个社会的劳动效率。
这种分工的思想也贯穿于软件的发展历史过程中,即子程序函数过程对象组件层。分工的内容越来越完备,抽象的层次越来越高,建模的粒度越来越大,和现实世界的距离也越来越近(现实世界一词这里既指物理实体也包括它们之间的内在逻辑关系)。
在软件系统结构设计上,也存在着这种分工的思想,那就是层次结构。著名的层次结构如开放系统互连参考模型(OSI)。层次结构的特点是:上层使用下层提供的服务,且仅通过层次间的特定接口获取下层服务,下层通过特定接口为上层提供特定服务,且不依赖于上层,也不知道上层的存在。下层与相邻上层之间为一对多的关系,即同一个下层可能为不同的上层提供服务。
这里有必要澄清层的含义,这里的层指逻辑意义上的层。物理意义上的客户端应用服务器数据库服务器所构成的系统在逻辑上是三层,其计算机的布局(如恰好是三台计算机),是层次结构的布局体现,而不是层本身;物理上的计算机的布局并不是构成层次结构的一个要素,软件组件间的逻辑关系才是构成层次结构的主要要素。以下我们要讨论的实体都是指软件组件,与其所驻留的计算机无关。
所有的计算机程序的本质都是数据处理,这里的数据是广义的数据,包括数值数据,文字,图像,声音等甚至是代码本身,也就是信息的记录载体。
既然是数据处理,首先就包括如何将要处理的数据告诉计算机程序和计算机程序如何把我们要的数据告诉我们,这就是表示层,包括UI和API。其次,包括如何处理数据,即将来自界面的数据加工为需要存储的信息数据或将存储的数据加工为需要表现的信息数据,这就是商务层;在现实中占大多数的都是商业程序,且在大量的商业程序中,这种处理都是和相关的现实商务处理过程和商务规则紧密联系的,所以叫商务层。最后,如果数据需要持久存储的话,还包括如何存储数据,如何更新数据,如何取得数据,这就是数据层。
具有启发意义的两种比较:
这是我们对于软件系统的一种逻辑上的认识,然而在编写代码时,我们仍然可以在不到十行的一段代码中既处理界面又处理运算还处理结果数据的保存。也就是说,我们的软件结构没有反映问题的逻辑结构,程序空间和问题空间在结构上不是对应的映射关系。于是在问题空间和程序空间之间就无法达成一种平滑的过渡。这样,我们要通过程序来实现我们对于问题的理解和对于问题的解决方案就会存在障碍。相应地我们的代码在可理解性,可维护性和可重用性上都会存在问题。
同理,非面向对象的软件也很可能会存在同样的问题。
为什么?
因为对象化和层次化正是现实世界的基本结构特征。
对象化反映现实世界物理上的结构特征;
层次化反映现实世界宏观逻辑上的结构特征。
当我们开始用软件来解决问题时,是将现实世界特定范围进行抽象,抓住主要矛盾,忽略次要矛盾,反映到我们的头脑中,形成问题空间。由于问题空间来源于现实世界,其基本结构特征仍然是对象化和层次化。
如果我们的软件结构也对象化和层次化,就有利于在软件空间和问题空间之间建立映射关系,实现平滑过渡,进而有利于对于问题的理解和问题解决方案的实现,有利于软件的开发,维护和重用。
由于现实世界里对象的复合性和独立性,决定了软件中对象化思想进一步进化为组件化思想。一个组件是由一个或多个对象组成的可以单独存在的只完成某种特定工作的只提供某些特定服务的软件实体。这样更能代表现实世界中的实体,便于理解和使用,便于维护和重用。
这样软件空间和问题空间的更加一致可以在软件开发的理解,实现,维护,重用等方面带来好处。
由于问题空间对象化和层次化的结构特征,决定了软件的结构设计不但要组件化,还要层次化。
商业应用中,大部分应用程序所作的工作都是商务数据处理。
对于软件用户而言,他使用的软件对他事实上是一个黑箱,他只关心界面上如何操作就行了:
他在界面上选择他要发出的命令,选择或输入执行该命令需要的参数就可以了。
黑箱的透视图:
从设计上来看,软件系统的层次结构可以表达如下:
其中,表示服务和数据存取服务的角色类似于适配器(Adapter)。表示服务可以提供商务层和用户界面之间进行数据转换的服务。数据存取服务可以提供商务层和数据存储之间进行数据转换的服务。
这样,商务层就不必关心用户界面和数据存储,仅通过接口与之进行数据交换,因此可以隔离相关可变化因素,集中精力实现商务处理要求。
层次之间通过接口的隔离来进行基于服务的调用,便降低了系统的复杂性,剥离了非主营业务,实现了自己的核心价值。(同样的道理适用于层次内各对象之间的关系)
多层结构设计所带来的直接好处就是:模块重用性好。程序可维护性高。物理分布灵活。开发的并行性高。
举个例子:在一个线缆销售公司的订单处理系统中要录入订单,并保存订单。有以下要求:订单的录入界面要随所订线缆的种类不同而不同,以便于快速录入。能否开放该新订单取决于该订单的总金额和该订单的销售员的金额授权以及库存情况。如果销售员金额权限不够,要提示请销售经理进行授权审批。
这里:
订单的录入界面要随所订线缆的种类不同而不同,说明了界面的输入输出方式是多样的,这是表示的多样性,对应于表示层。
能否开放该新订单取决于该订单的总金额和该订单的销售员的金额授权以及库存情况,这
是商业规则,对应于商务层。
录入订单,并保存订单,以及如果销售员金额权限不够,要提示请销售经理进行授权审批,
是要实现的功能,这种功能是由客户端组织的,在表示层实现。
订单,销售员权限, 这是数据,对应于数据层。
但层的软件实现基础是什么呢?换句话说,层是如何实现的呢?
层是通过多组软件模块之间的经过规划的调用来实现的。软件模块可以是源程序代码级别上的子程序,函数过程,对象或二进制代码级别上的组件。如果软件模块是源代码级别上的,那么层就是依赖于源代码的,其发挥作用的范围也就只限于相应的编译后的应用程序。如果软件模块是二进制代码级别上的组件,如COM/DCOM对象或CORBAR对象,层就不依赖于源代码而可以独立地为调用者提供服务。而且可以为多个调用者提供服务,不管这些调用者是不是同一个应用。
层次结构是一种设计思想,适用于单独的本机应用程序设计,更适用于复杂的软件系统。
由于二进制代码级别上的组件在开发,维护,重用方面相对于基于源代码的软件模块的优势,层更多地由二进制代码级别上的组件来组成。例如Windows和Office的层次结构。事实上,只有基于二进制组件的层次结构(各层可以独立存在)才能真正发挥多层结构的威力。
在实际的软件系统中,每一层还可能由多个实现特定目标的子层构成。在设计时,软件模块是基于源代码级别的对象、函数过程还是基于二进制代码级别上的组件取决于系统的复杂度和系统约束。
层就是一群负有特定使命,提供特定服务的软件模块。
例如,先前说提到的订单处理系统中与订单相关的处理可以在三层结构中作如下分布:
(注:订单商务对象和数据对象接口中的参数均已省略;接口并不完备,仅作示例用;各层上还有其他相关对象没有列出)请仔细体会不同层次的对象在协同完成同一任务时的角色和思维的层次。
另外一个多层结构的一个典型例子是银行的软件系统。在银行的软件系统中,数据存放在大型机如AS/400上,后台业务交易处理可能在AS/400上也可能在微机上处理(最后提交到AS/400),前端面对用户的形式却是多种多样的:柜台,ATM,Web,电话,手机。不同的前端都是使用同样的后台处理服务。(设想一下,如果不是这样呢?)
综合以上的论述,我们可以画出多层结构系统在逻辑上和布局上的典型视图如下:
多层结构中各类对象的含义与任务是什么呢?:
数据存取对象 : 提供记录的增删改查方法,语义环境是在数据操作层次上
商务实体对象:在一个或多个数据对象之上绑定商务实体的校验规则,提供商务实体对外所应展示的的方法,语义环境是在商务实体的相关操作层次上。例如:一个订单是个商务实体,由订单概要和所订商品两个数据对象组成,对一张订单整体实施校验规则,提供订单的相关商务操作方法,如新增,修改,删除,查询。
商务功能对象:通过一个或多个商务实体对象的协同工作,实现相关的某组功能。语义环境是在商务活动层次上。例如转账,可视为一个商务功能对象,通过按照一定顺序和约定调用转账所涉及的各个商务实体对象提供的接口功能,在一个事务中来完成。
表示层中,同一数据,可能在同一个客户端运行程序内部就有不同的表现形式。也可能由不同的客户端应用程序使用同一商务层的功能。表示媒体也可能多种多样。例如:WebServer就是一种提供将数据转换为便于浏览器浏览的数据格式的表示服务程序。
根据OMG 96年的定义,商务对象有如下定义:“商务对象代表在特定商务领域中活动的事物,商务对象至少包括它代表事物的商务名称和商务定义,属性,行为,关系,法则,政策和限制。例如商务对象可能代表一个人,地方,事件,商务流程或是观念。实际的商务对象范例有:员工,产品,订单,发票和付款等。”
显然,商务对象在多层结构设计中处于核心地位,因此,在多层结构系统中,最关键的就是设计好商务层,具体来说就是设计好商务层中需要存在哪些商务对象,各商务对象任务的分配和其接口的安排。
商务层中的一个设计原则就是:分离商务对象,封装商务处理与商务规则。
总结:
软件多层结构是一种基于组件和基于服务的,将系统不同层次的功能对应分散在不同软件层次上的软件系统结构设计观念。
与社会化大分工为人类社会带来极大好处相似,多层结构设计也为软件开发带来极大好处:
可重用性:由于商务层的独立存在,那么商务层中的各种服务可以被不同的应用程序使用。将组件的重用范围从以前的的单个项目扩展到企业范围内的多个项目。
配置的灵活性:由于软件系统被分成了独立的三层或多层,可以按照企业商务的功能需求和性能需求灵活配置各层次的物理位置,功能划分,计算机数量等,为需求迅速增长的分布式应用提供了实现基础。例如不同的部门的不同应用可以连接到不同的应用服务器上。各个层次还可单独选择最恰当的开发工具。
开发并行性:由于层与层之间是采用基于服务的存取(接口调用),并且是独立存在的,所以各层可以在约定好的接口下并行开发。
系统进化的容易度:当软件需求变更时或技术进步时,只需要更改相应层中的组件,在保证接口不变的情况下,不会影响系统的其他部分,也不需重新测试系统的其他部分。而且层与层之间采用基于服务的调用方式,所以,当商务规则变化时,只要更新单一的商务层,运行表示层的各个客户端便自动地获得按照新的商务规则处理的能力。在基于商务层服务的基础上,可以采用渐增的方式增加客户端应用种类和接入媒体,因而系统可扩展性很好。
摘要: 本文主要讨论软件系统多层结构设计的思想观念。
如果没有社会化大分工,人类能有今天如此丰富的物质文明和精神文明成果吗?如果没有社会化大分工,你还能悠闲地阅读这篇文章而不用考虑衣食住行所需物资的生产问题吗?
作为人类历史上文明进步的一个重要标志,社会化大分工使得社会中的每个个体在有限的资源条件下可以只专注于自己的特定工作,同时又可以与他人交换工作成果,这极大地提高了整个社会的劳动效率。
这种分工的思想也贯穿于软件的发展历史过程中,即子程序函数过程对象组件层。分工的内容越来越完备,抽象的层次越来越高,建模的粒度越来越大,和现实世界的距离也越来越近(现实世界一词这里既指物理实体也包括它们之间的内在逻辑关系)。
在软件系统结构设计上,也存在着这种分工的思想,那就是层次结构。著名的层次结构如开放系统互连参考模型(OSI)。层次结构的特点是:上层使用下层提供的服务,且仅通过层次间的特定接口获取下层服务,下层通过特定接口为上层提供特定服务,且不依赖于上层,也不知道上层的存在。下层与相邻上层之间为一对多的关系,即同一个下层可能为不同的上层提供服务。
这里有必要澄清层的含义,这里的层指逻辑意义上的层。物理意义上的客户端应用服务器数据库服务器所构成的系统在逻辑上是三层,其计算机的布局(如恰好是三台计算机),是层次结构的布局体现,而不是层本身;物理上的计算机的布局并不是构成层次结构的一个要素,软件组件间的逻辑关系才是构成层次结构的主要要素。以下我们要讨论的实体都是指软件组件,与其所驻留的计算机无关。
所有的计算机程序的本质都是数据处理,这里的数据是广义的数据,包括数值数据,文字,图像,声音等甚至是代码本身,也就是信息的记录载体。
既然是数据处理,首先就包括如何将要处理的数据告诉计算机程序和计算机程序如何把我们要的数据告诉我们,这就是表示层,包括UI和API。其次,包括如何处理数据,即将来自界面的数据加工为需要存储的信息数据或将存储的数据加工为需要表现的信息数据,这就是商务层;在现实中占大多数的都是商业程序,且在大量的商业程序中,这种处理都是和相关的现实商务处理过程和商务规则紧密联系的,所以叫商务层。最后,如果数据需要持久存储的话,还包括如何存储数据,如何更新数据,如何取得数据,这就是数据层。
具有启发意义的两种比较:
这是我们对于软件系统的一种逻辑上的认识,然而在编写代码时,我们仍然可以在不到十行的一段代码中既处理界面又处理运算还处理结果数据的保存。也就是说,我们的软件结构没有反映问题的逻辑结构,程序空间和问题空间在结构上不是对应的映射关系。于是在问题空间和程序空间之间就无法达成一种平滑的过渡。这样,我们要通过程序来实现我们对于问题的理解和对于问题的解决方案就会存在障碍。相应地我们的代码在可理解性,可维护性和可重用性上都会存在问题。
同理,非面向对象的软件也很可能会存在同样的问题。
为什么?
因为对象化和层次化正是现实世界的基本结构特征。
对象化反映现实世界物理上的结构特征;
层次化反映现实世界宏观逻辑上的结构特征。
当我们开始用软件来解决问题时,是将现实世界特定范围进行抽象,抓住主要矛盾,忽略次要矛盾,反映到我们的头脑中,形成问题空间。由于问题空间来源于现实世界,其基本结构特征仍然是对象化和层次化。
如果我们的软件结构也对象化和层次化,就有利于在软件空间和问题空间之间建立映射关系,实现平滑过渡,进而有利于对于问题的理解和问题解决方案的实现,有利于软件的开发,维护和重用。
由于现实世界里对象的复合性和独立性,决定了软件中对象化思想进一步进化为组件化思想。一个组件是由一个或多个对象组成的可以单独存在的只完成某种特定工作的只提供某些特定服务的软件实体。这样更能代表现实世界中的实体,便于理解和使用,便于维护和重用。
这样软件空间和问题空间的更加一致可以在软件开发的理解,实现,维护,重用等方面带来好处。
由于问题空间对象化和层次化的结构特征,决定了软件的结构设计不但要组件化,还要层次化。
商业应用中,大部分应用程序所作的工作都是商务数据处理。
对于软件用户而言,他使用的软件对他事实上是一个黑箱,他只关心界面上如何操作就行了:
他在界面上选择他要发出的命令,选择或输入执行该命令需要的参数就可以了。
黑箱的透视图:
从设计上来看,软件系统的层次结构可以表达如下:
其中,表示服务和数据存取服务的角色类似于适配器(Adapter)。表示服务可以提供商务层和用户界面之间进行数据转换的服务。数据存取服务可以提供商务层和数据存储之间进行数据转换的服务。
这样,商务层就不必关心用户界面和数据存储,仅通过接口与之进行数据交换,因此可以隔离相关可变化因素,集中精力实现商务处理要求。
层次之间通过接口的隔离来进行基于服务的调用,便降低了系统的复杂性,剥离了非主营业务,实现了自己的核心价值。(同样的道理适用于层次内各对象之间的关系)
多层结构设计所带来的直接好处就是:模块重用性好。程序可维护性高。物理分布灵活。开发的并行性高。
举个例子:在一个线缆销售公司的订单处理系统中要录入订单,并保存订单。有以下要求:订单的录入界面要随所订线缆的种类不同而不同,以便于快速录入。能否开放该新订单取决于该订单的总金额和该订单的销售员的金额授权以及库存情况。如果销售员金额权限不够,要提示请销售经理进行授权审批。
这里:
订单的录入界面要随所订线缆的种类不同而不同,说明了界面的输入输出方式是多样的,这是表示的多样性,对应于表示层。
能否开放该新订单取决于该订单的总金额和该订单的销售员的金额授权以及库存情况,这
是商业规则,对应于商务层。
录入订单,并保存订单,以及如果销售员金额权限不够,要提示请销售经理进行授权审批,
是要实现的功能,这种功能是由客户端组织的,在表示层实现。
订单,销售员权限, 这是数据,对应于数据层。
但层的软件实现基础是什么呢?换句话说,层是如何实现的呢?
层是通过多组软件模块之间的经过规划的调用来实现的。软件模块可以是源程序代码级别上的子程序,函数过程,对象或二进制代码级别上的组件。如果软件模块是源代码级别上的,那么层就是依赖于源代码的,其发挥作用的范围也就只限于相应的编译后的应用程序。如果软件模块是二进制代码级别上的组件,如COM/DCOM对象或CORBAR对象,层就不依赖于源代码而可以独立地为调用者提供服务。而且可以为多个调用者提供服务,不管这些调用者是不是同一个应用。
层次结构是一种设计思想,适用于单独的本机应用程序设计,更适用于复杂的软件系统。
由于二进制代码级别上的组件在开发,维护,重用方面相对于基于源代码的软件模块的优势,层更多地由二进制代码级别上的组件来组成。例如Windows和Office的层次结构。事实上,只有基于二进制组件的层次结构(各层可以独立存在)才能真正发挥多层结构的威力。
在实际的软件系统中,每一层还可能由多个实现特定目标的子层构成。在设计时,软件模块是基于源代码级别的对象、函数过程还是基于二进制代码级别上的组件取决于系统的复杂度和系统约束。
层就是一群负有特定使命,提供特定服务的软件模块。
例如,先前说提到的订单处理系统中与订单相关的处理可以在三层结构中作如下分布:
(注:订单商务对象和数据对象接口中的参数均已省略;接口并不完备,仅作示例用;各层上还有其他相关对象没有列出)请仔细体会不同层次的对象在协同完成同一任务时的角色和思维的层次。
另外一个多层结构的一个典型例子是银行的软件系统。在银行的软件系统中,数据存放在大型机如AS/400上,后台业务交易处理可能在AS/400上也可能在微机上处理(最后提交到AS/400),前端面对用户的形式却是多种多样的:柜台,ATM,Web,电话,手机。不同的前端都是使用同样的后台处理服务。(设想一下,如果不是这样呢?)
综合以上的论述,我们可以画出多层结构系统在逻辑上和布局上的典型视图如下:
多层结构中各类对象的含义与任务是什么呢?:
数据存取对象 : 提供记录的增删改查方法,语义环境是在数据操作层次上
商务实体对象:在一个或多个数据对象之上绑定商务实体的校验规则,提供商务实体对外所应展示的的方法,语义环境是在商务实体的相关操作层次上。例如:一个订单是个商务实体,由订单概要和所订商品两个数据对象组成,对一张订单整体实施校验规则,提供订单的相关商务操作方法,如新增,修改,删除,查询。
商务功能对象:通过一个或多个商务实体对象的协同工作,实现相关的某组功能。语义环境是在商务活动层次上。例如转账,可视为一个商务功能对象,通过按照一定顺序和约定调用转账所涉及的各个商务实体对象提供的接口功能,在一个事务中来完成。
表示层中,同一数据,可能在同一个客户端运行程序内部就有不同的表现形式。也可能由不同的客户端应用程序使用同一商务层的功能。表示媒体也可能多种多样。例如:WebServer就是一种提供将数据转换为便于浏览器浏览的数据格式的表示服务程序。
根据OMG 96年的定义,商务对象有如下定义:“商务对象代表在特定商务领域中活动的事物,商务对象至少包括它代表事物的商务名称和商务定义,属性,行为,关系,法则,政策和限制。例如商务对象可能代表一个人,地方,事件,商务流程或是观念。实际的商务对象范例有:员工,产品,订单,发票和付款等。”
显然,商务对象在多层结构设计中处于核心地位,因此,在多层结构系统中,最关键的就是设计好商务层,具体来说就是设计好商务层中需要存在哪些商务对象,各商务对象任务的分配和其接口的安排。
商务层中的一个设计原则就是:分离商务对象,封装商务处理与商务规则。
总结:
软件多层结构是一种基于组件和基于服务的,将系统不同层次的功能对应分散在不同软件层次上的软件系统结构设计观念。
与社会化大分工为人类社会带来极大好处相似,多层结构设计也为软件开发带来极大好处:
可重用性:由于商务层的独立存在,那么商务层中的各种服务可以被不同的应用程序使用。将组件的重用范围从以前的的单个项目扩展到企业范围内的多个项目。
配置的灵活性:由于软件系统被分成了独立的三层或多层,可以按照企业商务的功能需求和性能需求灵活配置各层次的物理位置,功能划分,计算机数量等,为需求迅速增长的分布式应用提供了实现基础。例如不同的部门的不同应用可以连接到不同的应用服务器上。各个层次还可单独选择最恰当的开发工具。
开发并行性:由于层与层之间是采用基于服务的存取(接口调用),并且是独立存在的,所以各层可以在约定好的接口下并行开发。
系统进化的容易度:当软件需求变更时或技术进步时,只需要更改相应层中的组件,在保证接口不变的情况下,不会影响系统的其他部分,也不需重新测试系统的其他部分。而且层与层之间采用基于服务的调用方式,所以,当商务规则变化时,只要更新单一的商务层,运行表示层的各个客户端便自动地获得按照新的商务规则处理的能力。在基于商务层服务的基础上,可以采用渐增的方式增加客户端应用种类和接入媒体,因而系统可扩展性很好。