谈五层逻辑构架设计

术语表

逻辑:Logical

物理:Physical

构架:Architecture

框架:Framework

表现层:Presentation

用户界面:User Interface

业务逻辑:Business Logic

数据访问:Data Access

数据和存储管理:Data and Storage Management

图形用户接口:Graphical User Interface

胖客户端:Richer Client-side

智能客户端:Smart Client

应用程序:Application

服务器端控件:Server-side control

事件驱动:Event-driven

可重用组件:Reusable component

用户控件:User Control

元数据驱动:Metadata-driven

对象关系映射:object-relational mapping

本文将探讨5层逻辑构架的程序设计。这种类型的构架一旦建立成功,就可以配置成适用于各种各样的物理构架,从而为Windows窗体、Web窗体、Web服务提供最佳的服务。

这种构架由 图1所示的五部分构成:

应该时刻记得使用 N层逻辑构架的好处是将功能清楚地划分成角色或者组,以便提升程序的可读性和可维护性。下面我们来仔细的定义一下这几个层的功能。

表现层

首先,可能你很想知道为什么我会将表现层从用户界面层分离出去。的确,从Windows应用程序的角度来看,表现层和用户界面是一回事:它们都是些可以与用户进行交互的图形用户接口。

然而从Web程序的角度来看(或者从一个基于终端的程序来看),区别应该是很明显的。典型地,浏览器仅仅是将内容显示给用户,并采集用户的输入信息。在这种情况下,所有实际的交互逻辑――产生内容输出或者分析用户输入的代码――都在Web服务器端运行(或者主框架中),而不是在客户端机器上。

当然,在现实环境中,浏览器可能会运行JavaScript脚本或者是胖客户端代码。但是,这些代码都是不可信任的(译注:可以联想下客户端表单验证)。这些代码必须被视为与你运行于服务器端的代码进行交互的独立代码。所以,即使有代码运行于浏览器中,你的应用程序的用户界面代码仍然是运行于Web服务器上的。

应该了解到,当前讨论的逻辑构架必须同时支持智能客户端和基于Web的客户端(甚至是更多其他受到一些限制的客户端,比如说手机或者其他移动设备),在很多情况下,意识到表现层必须在物理上与用户界面逻辑分离是很重要的。为了能实现这种分离,设计程序时就很有必要围绕着这个主题来进行。

注意:表现层的技术类型是非常多的,并且每个都会伴随一个新的、相对不兼容的、我们必须使用的技术。实际上,不可能创建一个完全从表现层抽象出来的程序框架。正因为如此,构架和框架将仅仅是支持不同的表现层,而不是自动创建它们。所以,我们将把注意力主要集中在简化构架中的其他层,这些层中的技术相对稳定一些。

用户界面

之前我已经讲述了表现层和用户界面之间的区别,那么后者的目的现在应该已经很清楚了。这一层的程序逻辑决定了用户看到什么、导航的路径以及如何处理用户的输入。在一个Windows应用程序中,这些是置于表单之后的代码。实际上,这些也是在Web应用程序中置于表单之后的代码,但是,在这种情况下,用户界面层也包含服务器端控件中的代码。从逻辑上来讲,这属于同一层的不同部分。

在很多应用程序中,用户界面代码非常复杂。首先,它必须对于用户非流线型的请求做出响应(很难控制用户是否点击控件,进入或离开一个表单或者页面)。用户界面代码还必须在逻辑上与业务层进行交互,以验证用户输入、执行任何需要进行的任务,或者做任何与业务层相关的功能。

基本上,用户界面层的目的是编写接受用户输入然后提供输入信息到业务逻辑层的代码,这些用户输入信息在业务逻辑层中被验证、处理或者进行其他任何的操作。用户界面层必须对用户的请求做出响应,显示与业务逻辑层交互所产生的结果。用户输入的数值正确么?如果不正确,那么是哪里除了问题?等等。

在.Net中,用户界面几乎总是事件驱动的。Windows窗体总是在用户输入或者点击表单项时做出相应,Web窗体总是在一次用户动作的客户端/服务器往返中对事件做出响应。尽管Windows窗体和Web窗体技术大量使用了面向对象设计,典型的写在用户界面中的代码却不是面向对象的,而是事件驱动的。

这就是说,创建一个支持某种类型用户界面的框架和可重用的组件是非常有价值的。当创建一个Window窗体的用户界面,开发者可以利用继承和其他面向对象技术去简化窗体的创建。当创建一个Web窗体用户界面,开发者可以使用ASP.NET用户控件和自定义服务器控件去提供可重用组件以便简化页面的开发。

业务逻辑

业务逻辑层包含了全部的业务规则,数据验证、操作、处理以及应用程序安全性。微软对于业务逻辑层的定义是这样的:业务逻辑层是企业商业运作方式的操作集合,这些操作包括验证用户输入、登录校验、数据库查询、商业条款、转换算法等。

注意:再说一次,当你进行一个用户校验时,如果校验代码运行于浏览器或者是外部的客户端上,那么这些代码是不可信的。你必须将这些程序放在你所能控制的业务逻辑层中去实现,因为只有这样才算是真正的验证。

业务逻辑必须放置于与用户界面代码完全分离的独立层之中。有时,你可能想要复制一些业务逻辑层的代码到用户界面层中去,以便提供一个更好的用户体验,但是,业务逻辑层必须实现所有的业务规则,因为它才是集中管理和维护的关键所在。

我相信,如果你想获得一个更好的可维护性和可重用性,这种业务逻辑与用户界面层功能的分离是绝对关键的。这是因为任何写入用户界面层的业务逻辑都存在于某一特殊的用户界面代码中,这样它将不能适用于日后创建的新的用户界面。

如何写入Windows窗体用户界面中的业务逻辑代码对于Web窗体程序或者Web服务来说,都是毫无意义的,并且必须重写一遍。这毫无疑问导致了如同噩梦般的重复性的代码。将这两层分离可以通过明确定义程序模型、面向对象设计和变成 的技术来实现。

在一个典型的应用程序中,意识到将会以很多种方式使用业务逻辑是很重要的。大多数应用程序都会做一些用户交互,比如说一些提供用户输入或者提供显示内容的表单。很多应用程序也会有一些完全不需要交互的过程,比如开发表、分发财产清单,或者计算税率等。

在理想情况下,当用户直接对应用程序发送数据时,业务逻辑层将有着非常丰富的交互功能。举例来说,当一个用户正在访问一个订单,他期望在他输入时,诸如税率的计算、订单的价格总计等正确的数据会即时的显示出来。这就暗示着从物理角度考虑,业务逻辑层可能会被部署在客户端工作站上,或者Web服务器上,以便满足高级的用户交互需要。

从另一方面来说,为了支持非交互的过程,业务逻辑层经常需要被部署在一个尽可能靠近数据库服务器的应用程序服务器上。举例来说,保险费用的计算需要使用大量的数据库查询并伴随少量的复杂业务规则处理。这就是发生在服务器上,用户显示器背后的事情。

幸运的是,在多个物理层上部署一个逻辑层是可能的。做这项工作非常需要一些长远的计划和技术设计,然而,最终的结果是一个分别部署在客户端工作站(或者Web服务器)和应用程序服务器上的独立业务逻辑层。这就使得应用程序具备在用户直接与应用程序对话时,提供高级用户交互体验和高效的处理非交互性操作的能力。

数据访问

数据访问层的代码与数据管理层进行交互,以便获取、插入、更新、移动数据。数据访问层并不实际的管理或者存储数据。它仅仅是提供一个业务逻辑层与数据库之间的接口。

就像表现层与用户界面层分离的原因一样,数据访问层拥有着自己的逻辑。在一些情况下,数据访问层将放置于某台机器上,这台机器与运行用户界面 或者(和) 业务逻辑层的机器并非同一台机器。在另外一些情况下,数据访问层可能与用户界面 或者(和) 业务逻辑层放置在同一台机器上,以便提高性能和容错性。

注意:把数据访问层和业务逻辑层放在同一台机器上会提高容错性听上去可能会很奇怪,但是请考虑一下Web窗体,在这种情况下每个Web服务器对于其他服务器来说都是一样的。将数据访问层代码放置于所有Web服务器上产生数据访问层、业务逻辑层、用户界面层的自动冗余。

添加一个仅仅用于数据访问的物理层将会使容错性很难实施,因为它增大了需要实施数据冗余的层数。还有一个负面效应,添加更多的物理层数也会降低单用户情况下的运行速度,所以这并不是无关紧要的事情。

逻辑上定义一个独立的数据访问层使得业务逻辑与数据库(或者其他任何数据源)之间的任何交互都分离了。这种分离对于以后是否将数据访问代码运行于现在的系统或是其他新的系统,提供了很大的灵活性。它同样可以使得在不改变应用程序的情况下更换一个数据源变得很容易。这个是很重要的,因为在一些情况下它使得可以轻易的从一种数据库转换到另一种。

说这种分离是非常有用的还有另外一个原因:微软习惯每三年就改变一次数据访问技术,这就意味着需要重新书写数据访问代码以跟进潮流(回想一下DAO, RDO, ADO 1.0, ADO2.0, 以及现在的ADO.NET)。通过将数据访问层代码分离到一个独立的层中,这种变化所造成的影响被限制在应用程序的一个很小的范围以内。

典型地,数据访问机制以一系列服务的形式被实现,每个服务都是单独的一个由业务逻辑层调用的功能,以便进行数据的获取、插入、更新。尽管这些服务通常都是以对象的形式被创建,意识到一个高效的数据访问层应该是非常流线型的是很重要的。对于一个关系数据库的访问采用尽可能多的面向对象的设计常常会导致更高的程序复杂性和更低的执行效率。

我认为实现数据访问层的最好方法是写一系列的方法,但是将这些方法封装在一个对象中以便使它们有更好的组织。

注意:如果你正在使用一个面向对象的数据库而非一个关系数据库,那么当然,数据访问代码应该是非常的面向对象的。然而,只有很少的人拥有着这样的机会,因为几乎所有的数据都是存储在关系数据库当中的。

在一些情况下,数据访问层是可以是非常简单的,仅仅由使用ADO.NET来直接获取或者存储数据的一系列方法组成。在另一些情况下,数据访问层要复杂得多,提供更加抽象或甚至是元数据驱动的方式去获取数据的方法。在这些情况下,数据访问层会包含大量的复杂代码以便提供这种更加抽象的数据访问模式。

数据访问层经常扮演的另一个角色是提供面向对象的业务逻辑与存储在数据库中的数据之间的映射。一个好的面向对象模型几乎从来不与一个好的关系数据库模型相同。对象经常包含来自于多个表甚至多个数据库的数据。将数据从一个关系模型的表中提取出来,并提供给面向对象模型的过程,被称作 对象关系映射(ORM)。

数据存储和管理

最后,还剩下数据存储和管理层。类似于SQL Server 和Oracle这样的数据库服务器通常担当这样的角色,但是逐渐地,其他的应用程序可能通过类似于Web服务这样的技术提供同样的功能。

这一层的核心是它在物理上提供了对数据的创建、获取、更新和删除。这与数据访问层是不同的,数据访问层仅仅是提出对数据进行创建、获取、更新和删除的请求。数据管理层实际地在数据库中和磁盘文件上实施这些操作。

业务逻辑层(通过数据访问层)调用数据管理层,但是这一层常常包含额外的逻辑去验证数据的正确性以及它们与其他数据之间的关系。很多时候,这是来自于数据库端的真正的关系数据模型;另一些时候,这是来自于外部应用程序的业务逻辑规则。这就意味着一个典型的数据管理层应该也包括在业务逻辑层实现的业务规则。这种情况下,复制是不可避免的,因为关系数据库被设计成为强制性的实施关系完整性;而这不过是业务逻辑的另一种形式而已。

总的来说,不管你是在SQL Server中使用存储过程,还是使用Web服务调用另一个应用程序,典型地,数据存储和管理是由一系列的可以在需要时被调用的服务和存储过程来处理的。就像数据访问层一样,意识到数据存储和管理层的设计是非常流线型(译注:流线型是相对于面向对象来说的)的是很重要的。

1. 五层逻辑层所担任的角色



角色


表现层


提供内容显示和收集用户输入。


用户界面


作为用户和业务逻辑之间的中介,获取用户输入并提供给业务逻辑层,并且将结果返回给用户


业务逻辑


提供所有的业务规则、数据校验、操作、处理,以及应用程序安全


数据访问


作为业务逻辑层与数据管理层之间的中介。同样封装了所有需要用到的数据访问技术(比如ADO.NET)


数据存储和管理


物理上创建、获取、更新、删除数据,并且进行对数据的维护。

时间: 2024-11-03 03:26:27

谈五层逻辑构架设计的相关文章

浅谈SQL Server中的事务日志(一)----事务日志的物理和逻辑构架

浅谈SQL Server中的事务日志(一)----事务日志的物理和逻辑构架 简介 SQL Server中的事务日志无疑是SQL Server中最重要的部分之一.因为SQL SERVER利用事务日志来确保持久性(Durability)和事务回滚(Rollback).从而还部分确保了事务的ACID属性.在SQL Server崩溃时,DBA还可以通过事务日志将数据恢复到指定的时间点.当SQL Server运转良好时,多了解一些事务日志的原理和概念显得并不是那么重要.但是,一旦SQL SERVER发生崩

系统构架设计应考虑的因素

系统构架设计应考虑的因素 摘要:本文从程序的运行时结构和源代码的组织结构两个方面探讨了系统构架设计应考虑的各种因素,列举了系统构架设计文档应考虑的一些问题. 关键字:系统构架.设计.考虑.因素 正文:约公元前25年,古罗马建筑师维特鲁威说:“理想的建筑师应该既是文学家又是数字家,他还应通晓历史,热衷于哲学研究,精通音乐,懂得医药知识,具有法学造诣,深谙天文学及天文计算.”(好难哪,软件构架设计师的要求呢?大家好好想想吧.) 本文目录一.与构架有关的几个基本概念: 二.构架设计应考虑的因素概揽:

[转]专访企业QQ SaaS团队,谈企业级LNMP架构设计

FROM : http://www.csdn.net/article/2014-08-20/2821302-interview-tencent-b-qq-shuai-wang 对比IaaS和PaaS,SaaS得到的关注显然要少一些.究其根本,不仅因为SaaS关注的是功能方面的探索,更偏向于某个领域或层面的实际应用,还归结于相较前两者,软件的云化已基本趋于成熟,些许突破并不能带来产业上的变革.然而,较少的关注并不意味着缺乏明星产品:放眼国外,企业级SaaS服务已成为许多公司的一项重要收益来源,比如

【开源】浅谈Hybrid技术的设计与实现第二弹

前言 接上文:浅谈Hybrid技术的设计与实现(阅读本文前,建议阅读这个先) PS:据说加个开源在前面阅读量高点,于是就试试咯...... 上文说了很多关于Hybrid的概要设计,可以算得上大而全,有说明有demo有代码,对于想接触Hybrid的朋友来说应该有一定帮助,但是对于进阶的朋友可能就不太满足了,他们会想了解其中的每一个细节,甚至是一些Native的实现,小钗这里继续抛砖引玉,希望接下来的内容对各位有一定帮助. 进入今天的内容之前我们首先谈谈两个相关技术Ionic与React Nativ

浅谈Hybrid技术的设计与实现

浅谈Hybrid技术的设计与实现 前言 随着移动浪潮的兴起,各种APP层出不穷,极速的业务扩展提升了团队对开发效率的要求,这个时候使用IOS&Andriod开发一个APP似乎成本有点过高了,而H5的低成本.高效率.跨平台等特性马上被利用起来形成了一种新的开发模式:Hybrid APP. 作为一种混合开发的模式,Hybrid APP底层依赖于Native提供的容器(UIWebview),上层使用Html&Css&JS做业务开发,底层透明化.上层多多样化,这种场景非常有利于前端介入,非

浅谈DevExpress<二>:设计一个完整界面(2)

下面来把剩下的工作做完,换肤功能昨天已近讨论过,今天就不重复了.首先建立三个全局变量,一个存放文件路径,一个存放数据,一个存放过滤条件. string DBFileName; DataView dataView; string[] filter = new string[3]; 取得数据并绑定到表格中: DBFileName = DevExpress.Utils.FilesHelper.FindingFileName(Application.StartupPath, "Products.xml&

新随笔(一) 从用户心理体验谈慎用瀑布流布局设计

新随笔(一) 从用户心理体验谈慎用瀑布流设计 最早使用瀑布流布局技术的是Pinterest,瀑布流设计确实带给用户更新鲜的视觉体验,很容易引导用户不停滚动鼠标,感觉丰富的内容永远不会结束,瀑布流的设计有他很明显的优点,但同时也有他的缺点,并不是所有网站都适用. 社交网站和移动设备适用于瀑布流设计 移动界面由于手机屏幕狭窄,列表项垂直排列,需要单手频繁的滚动,当用户向下滚动内容,自动加载更多的内容,而无需等待页面预加载.这样,用户会感觉到响应很及时,现在微博.微信均采用此方式, 社交网站之所以采用

逻辑数据库设计 - 单纯的树(递归关系数据)(转)

逻辑数据库设计 - 单纯的树(递归关系数据) 相信有过开发经验的朋友都曾碰到过这样一个需求.假设你正在为一个新闻网站开发一个评论功能,读者可以评论原文甚至相互回复. 这个需求并不简单,相互回复会导致无限多的分支,无限多的祖先-后代关系.这是一种典型的递归关系数据. 对于这个问题,以下给出几个解决方案,各位客观可斟酌后选择. 一.邻接表:依赖父节点 邻接表的方案如下(仅仅说明问题): CREATE TABLE Comments( CommentId int PK, ParentId int, --

新随笔(一) 从用户心理体验谈慎用瀑布流设计

新随笔(一) 从用户心理体验谈慎用瀑布流设计 最早使用瀑布流布局技术的是Pinterest,瀑布流设计确实带给用户更新鲜的视觉体验,很容易引导用户不停滚动鼠标,感觉丰富的内容永远不会结束,瀑布流的设计有他很明显的优点,但同时也有他的缺点,并不是所有网站都适用. 社交网站和移动设备适用于瀑布流设计 移动界面由于手机屏幕狭窄,列表项垂直排列,需要单手频繁的滚动,当用户向下滚动内容,自动加载更多的内容,而无需等待页面预加载.这样,用户会感觉到响应很及时,现在微博.微信均采用此方式, 社交网站之所以采用