NGuestBook架构体系及实现指南

前几天我在我的Blog上发布了NGuestBook(点击这里下载),得到了很多反馈,在这里非常感谢大家的关注和支持。一些朋友在E-mail中提到,这个NGuestBook和我那个系列文章《基于.NET平台的分层架构实战》中讲的Demo有非常多不一样的地方,问我能不能单独写一篇文章说明一下这个新NGuestBook的架构方式和实现相关的问题。
      所以我专门写下这篇文章,对这个NGuestBook的架构体系和实现进行一个简要的说明,希望本文的内容能对大家有所帮助。
      有两点要特别说明:一是下面的内容中非正式的使用了UML包图,这里用UML只是为了描述一种架构,而不是建模,所以可能有很多不符合UML标准的地方,还请海涵了,只要您能看懂大体的结构表示就好。二是一下的描述,特别是图示,是以抽象架构工件为基本元素的,可能不会和源码中的工程、文件、类严格对应,但是,应该能很容易分辨出抽象工件元素和具体工程、文件等元素的对应关系。

  总体架构
      我们先来看NGuestBook的总体架构图,如图1所示。

图1

整体采用分层架构,这个思想很明显。从上到下依次为表示层(Web)、业务逻辑层(BusinessComponents)和数据访问层(DataComponents)。
      其中表示层直接依赖业务逻辑层,而业务逻辑层通过数据访问层接口依赖数据访问层。在业务逻辑层和数据访问层接口上,存在依赖注入组件(Factories),便于进行不同数据访问层的替换。
      这里预设了三个数据访问层,LinqDataComponents是使用linq to sql技术为ORM组件实现的数据访问层,SQLDataComponents使用传统的SQL语句访问数据库,这两个数据访问层都是以关系数据库作为数据源;XMLDataComponents是以XML文件为数据源的数据访问层,他们都是DataComponentInterfaces的实现。(特别说明:在提供的源代码中,只实现了LinqDataComponents,其他两个数据访问层只给出了扩展接口,没有具体实现。)
      Entities作为实体类组件,存放系统中用到的“贫血实体类”,这些实体类只用于存放数据,并负责在各层间数据的传递,是各层数据存取传递的媒介和标准。
      Utilities作为工具库组件,存放各种可复用的工具类。
      下面,对各个组件分别进行说明。

  实体类组件
      实体类组件是现实世界业务实体在计算机世界中的表示,负责在各层之间的数据的传递,并维护数据格式标准。说通俗一点,就是各个层都“认识”这组标准实体类,传入、传出数据都以这种格式进行。
      为什么要这样呢?因为我们整体思想是尽可能保持各层间的耦合度较低,并相对独立,但是系统要工作,各层间就不可避免交换数据,因此,我们需要一种标准的、简单的、与各层无关的数据格式,否则如果强制某层强制其它层“认识”它特有的数据格式,就可能造成污染。
      例如,如果我们以DataTable为数据交换格式,那么业务逻辑层和表示层都得认识这种数据格式才行,如果有一天,我们要换数据访问层,不需要DataTable了,那么业务逻辑层和表示层都要修改。所以,我们要使用这种标准的、与特定层无关的数据格式作为交换格式,而如果某层有特定的数据格式,要在内部实现转换,对外传递的必须是这种标准格式。
      这里的实体类采用贫血实体类,而且由于业务很简单,整个系统只有一个实体类:MessageInfo。

图2

  工具类组件
      工具类组件里是一些可复用的工具性类,这里主要包括三个:
      CacheAccessor:用于缓存的存取操作。
      SessionAccessor:用于Session的存取操作。
      ValidateHelper:用于数据验证的相关操作,主要用在表示层里。

图3

  数据访问层接口
      数据访问层接口规定了数据访问层应该实现的方法,并作为业务逻辑层的依赖接口。
      由于整体只有一个实体——Message需要数据持久化,所以数据访问层接口只有一个接口文件。

图4

  基于linq to sql的数据访问层
      NGuestBook实现的数据访问层是基于linq to sql的。总体来说,开发小型项目时,linq to sql是不错的ORM解决方案。数据访问层的内部架构如图5所示。

图5

其中DataClasses是linq to sql框架根据数据库自动生成的特有实体类,用于linq to sql的操作。而数据访问主部件MessageDataComponent仅仅依赖DataClasses,这是因为MessageDataComponent的linq to sql操作必须使用这种特殊的实体类。
      而对外交流时,又需要使用公共实体类MessageInfo,所以,我们需要一个EntityConvertor,作为两种实体类之间的转换器,这个转换器是这个Linq to sql数据访问层的内部机制,对外部一律透明。
      这里要注意,EntityConvertor是一个概念上的工件,实际实现时其功能集成于MessageDataComponent。

  业务逻辑层
  业务逻辑层实现主要业务。

  业务逻辑层有两个工件:AdminBusinessComponent和MessageBusinessComponent。其中后一个主要实现各种留言的业务操作,而前一个是管理员的业务操作。由于管理员的信息是记录在配置文件中而非持久化在数据库中,所以这个业务工件并不需要数据访问层的支持。
      这里特别提醒,朋友们可以仔细看一下业务逻辑层的方法命名和代码,就会明白,即使在如此微小的系统中,业务逻辑层也不是对数据访问层简单的封装调用,业务逻辑和数据访问是完全两个不同的概念。

图6

  依赖注入组件
      依赖注入实现了依赖配置动态选择数据访问层并注入业务逻辑层中,实现两层之间的解耦,具体实现的基础是Abstract Factory模式,并配合了反射机制和缓存机制。

图7

如图7所示,依赖注入组件的主要工件是DataComponentFactory,它是一个反射工厂,它可以通过反射机制加载某个指定的数据访问层,而后将其注入到业务逻辑层中。至于具体加载哪一个,则依赖Web.config中的配置。
      两外,它还依赖CacheAccessor实现缓存机制,对加载过的数据访问组件进行缓存,提高系统运行效率。

  表示层
     NGuestBook的表示层使用了Microsoft ASP.NET MVC框架,版本是Releasse Candidate,所以,整个表示层的架构符合MVC模式。

图8

由于ASP.NET MVC的架构原理非常复杂,这里就不将具体细节全部表述。大体架构如图8所示,Controllers控制器组件是整个MVC的核心,负责整体的调控。而Views视图组件则使用aspx页面实现,Filters是一些拦截器类,主要实现了身份验证和异常处理的功能。而Controllers直接依赖BusinessComponent完成业务功能,所以BusinessComponent实际上可以看成是MVC的Model。
      实际上,表示层还依赖工具类组件完成Session存取和数据验证的工作。

  总结
      以上就是NGuestBook架构的一个简单说明,限于篇幅,不能完全顾及到每一个细节,还请见谅。希望以上内容对大家有所帮助。

时间: 2024-12-24 17:01:47

NGuestBook架构体系及实现指南的相关文章

一起谈.NET技术,NGuestBook架构体系及实现指南

      前几天我在我的Blog上发布了NGuestBook(点击这里下载),得到了很多反馈,在这里非常感谢大家的关注和支持.一些朋友在E-mail中提到,这个NGuestBook和我那个系列文章<基于.NET平台的分层架构实战>中讲的Demo有非常多不一样的地方,问我能不能单独写一篇文章说明一下这个新NGuestBook的架构方式和实现相关的问题.      所以我专门写下这篇文章,对这个NGuestBook的架构体系和实现进行一个简要的说明,希望本文的内容能对大家有所帮助.      有

JUnit 5系列之架构体系介绍

现在,我们已经知道了 如何配置 JUnit 5 环境 及 如何写一些测试,接下来就来看一点封面下的内容吧.本篇我们将讨论 JUnit 5 的架构体系,以及它之成形如此的原因. 概述 本文章是这个 JUnit 5 系列的一部分: 环境搭建 基础入门 架构体系 扩展模型(Extension Model) 条件断言 注入 动态测试 ... (如果不喜欢看文章,你可以戳这里看我的演讲,或者看一下最近的 vJUG 讲座,或者我在 DevoxxPL 上的 PPT. 本系列文章都基于 Junit 5发布的先行

WCF技术剖析之二十五:元数据(Metadata)架构体系全景展现[元数据描述篇]

在[WS标准篇]中我花了很大的篇幅介绍了WS-MEX以及与它相关的WS规范:WS-Policy.WS-Transfer和WSDL,因为WCF元数据结构体系完全是基于WS-MEX等相关的规范之上.熟悉这些基本的WS规范,对于我们全面.深刻的理解WCF整个元数据架构体系具有十分重要的意义.不仅仅是针对元数据,对于后续章节陆续要介绍的内容,比如事务.可靠会话.安全等,我强烈建议读者在正式进行相关部分的学习之前,先对相关的WS规范作一个大致的了解. 通过对WS-MEX的介绍,我们知道:不论是采用WS-T

《企业大数据系统构建实战:技术、架构、实施与应用》——第2章 企业大数据职能规划 2.1 大数据组织架构体系

第2章 企业大数据职能规划 第1章我们介绍了企业大数据在宏观和微观层面的定位,立足于解答企业大数据的商业模式.市场机会.延伸价值.内部功能定义等问题.当企业已经确定要实施大数据战略时,应该如何针对性地建立职能架构体系以保证企业大数据的有效实施和落地?各个职能部门的职责范畴如何定义?不同体系和部门间如何协同和流程化工作? 本章将详细讲解企业大数据职能规划体系,包括如何定义大数据部门在企业中的角色,常见的大数据职能及职责分工,不同职位的职责划分以及大数据制度和流程建设等问题. 2.1 大数据组织架构

WCF服务端运行时架构体系详解[下篇]

作为WCF中一个核心概念,终结点在不同的语境中实际上指代不同的对象.站在服务描述的角度,我们所说的终结点实际上是指ServiceEndpoint对象.如果站在WCF服务端运行时框架来说,终结点实际上指代的是终结点分发器(EndpointDispatcher).而ServiceEndpoint与EndpointDispatcher是一一匹配的,并且前者是创建后者的基础.而终结点分发器具有自己的运行,即分发运行时(DispatchRuntime). 目录 一.终结点分发器(EndpointDispa

WCF服务端运行时架构体系详解[上篇]

WCF的服务端架构体系又可以成为服务寄宿端架构体系.我们知道,对于一个基于某种类型的服务进行寄宿只需要使用到一个唯一的对象,那就是ServiceHost.甚至在某种语境下,我们所说的服务实际上就是指的对应的ServiceHost对象.整个服务寄宿过程包括两个阶段,即服务描述的创建和服务端运行框架的建立.而第一个阶段创建的服务描述是为了第二个阶段对服务端运行时框架建立服务的,所以我们有必要在对服务描述进行简单的介绍. 目录: 一.从服务描述(Service Description)谈起 二.服务端

WCF客户端运行时架构体系详解[上篇]

客户端调用WCF服务的方式不外乎有两种:其一.通过代码生成工具(比如SvcUtil.exe)导入服务的元数据生成服务代理相关的类型:其二.通过ChannelFactory<TChannel>创建服务代理对象.对于前者,生成的服务代理是一个继承自ClientBase<TChannel>的类型.对于这样一个服务代理对象,其内部本质上还是借助于ChannelFactory<TChannel>创建真正用于进行服务调用的代理对象.对于WCF客户端应用编程接口来说,ChannelF

WCF客户端运行时架构体系详解[下篇]

当基于某个终结点创建的ChannelFactory<TChannel>被开启的之后,位于服务模型层的客户端运行时框架被成功构建.站在编程的角度看ChannelFactory<TChannel>,它就是一个创建用于服务调用的服务代理对象的工厂.由于服务调用需要借助于服务代理来完成,我们很有必要从整个客户端运行架构层面来了解服务代理和基于服务代理的服务调用是如何实现的. 目录 一.服务代理是一个透明代理 二.服务调用的流程       操作选择       输入参数检验       序

WCF服务端运行时架构体系详解[续篇]

终结点分发器在自己的运行时中对请求消息的处理最终肯定体现在相应操作的执行.如果从服务描述的角度来看,操作是一个OperationDescription对象.而服务端分发运行时中的操作则代表的是一个DispatchOperation对象.作为服务描述的一部分,服务所有终结点的所有操作描述(OperationDescription)在ServiceHost创建过程中被创建.而当ServiceHost被正常开始时,这些操作描述最终转换成分发操作(DispatchOperation).而Dispatch