当前位置: 首页 > news >正文

第13章 层次式架构设计理论与实践

层次式架构的核心思想是将系统组成为一种层次结构,每一层为上层服务,并作为下层客户。其实不管是分层还是其他的架构都是为了解耦,更好的复用,只要秉承着这种思想去理解一切都迎刃而解了。

13.1 层次上体系结构概述

回顾一下软件体系结构的相关概念:

软件体系结构可定义为(其中一种):软件体系结构为软件系统提供了结构、行为和属性的高级抽象,由构成系统的元素描述、这些元素的相互作用、指导元素集成的模式以及这些模式的约束组
成。
软件体系结构不仅指定了系统的组织结构拓扑结构,并且显示了系统需求和构成系统的元素之间的对应关系,提供了一些设计决策的基本原理,是构建于软件系统之上的系统级复用
软件体系结构贯穿于软件研发的整个生命周期内,具有重要的影响。这主要从以下三个方
面来进行考察。
(1)利益相关人员之间的交流。
(2)系统设计的前期决策。
(3)可传递的系统级抽象。
层次式体系结构设计是将系统组成一个层次结构,每一层为上层服务,并作为下层客户。

在一些层次系统中,除了一些精心挑选的输出函数外,内部的层接口只对相邻的层可见。

连接件通过决定层间如何交互的协议来定义,拓扑约束包括对相邻层间交互的约束。由于每一层最
多只影响两层,同时只要给相邻层提供相同的接口,允许每层用不同的方法实现,同样为软件重用提供了强大的支持。
软件层次式体系结构是最通用的架构,也被叫作N层架构模式(n-tier architecture pattern)。
大部分的应用会分成表现层(或称为展示层)中间层(或称为业务层)数据访问层(或称为持久层)数据层
分层架构的一个特性就是关注分离(separation of concerns)。该层中的组件只负责本层的逻
辑,组件的划分很容易明确组件的角色和职责,也比较容易开发、测试、管理和维护。

层次式体系结构是一个可靠的通用的架构,设计时要注意以下两点:

(1)要注意的是污水池反模式。

所谓污水池反模式(architecture sinkhole anti-pattern),就是请求流简单地穿过几个层,每层里面基本没有做任何业务逻辑,或者做了很少的业务逻辑。比如一些Java EE例子,业务逻辑层只是简单的调用了持久层的接口,本身没有什么业务逻辑。
二八原则可以帮助你决定是否正在遇到污水池反模式。如果请求超过20则应该考虑让一些层变
成开放的。

(2)需要考虑的是分层架构可能会让你的应用变得庞大。

即使你的表现层和中间层可以独立发布,但它的确会带来一些潜在的问题,比如:分布模
式复杂、健壮性下降、可靠性和性能的不足,以及代码规模的膨胀等。

13.2 表现层框架设计

13.2.1 表现层设计模式

1.MVC模式

MVC强制性地把一个应用的输入、处理、输出流程按照视图、控制、模型的方式进行分离,形成了控制器、模型、视图三个核心模块。
(1)控制器(Controller):
接受用户的输入并调用模型和视图去完成用户的需求。该部分是用户界面与Model的接口。
一方面它解释来自于视图的输入,将其解释成为系统能够理解的对象,同时它也识别用户动作,并将其解释为对模型特定方法的调用
例:用户注册输入信息后,把这些信息转换成要Model好存入表中,如输入出生日期,自动计算出年龄,然后把值赋给Model中年龄字段;识别用户动作,点击查询按钮调用查询方法,点击保存按钮调用保存方法。
另一方面,它处理来自于模型的事件和模型逻辑执行的结果,调用适当的视图为用户提供反馈。
例:model返回查询的数据,controller根据结果返回给对应的view
(2)模型(Model):

应用程序的主体部分。模型表示业务数据和业务逻辑。一个模型能为多个视图提供数据。由于同一个模型可以被多个视图重用,所以提高了应用的可重用性。
1:多的例子:员工表可给员工查询view提供数据,也可给员工产量查询、部门下员工信息等等view提供数据;

(3)视图(View):
视图向用户显示相关的数据,并能接收用户输入的数据,但是它并不进行任何实际的业务处理。视图可以向模型查询业务状态,但不能改变模型。视图还能接受模型发出的数据更新事件,从而对用户界面进行同步更新。
首先,控制器接收用户的请求,并决定应该调用哪个模型来处理;
然后,模型根据用户请求进行相应的业务逻辑处理,并返回数据;
最后,控制器调用相应的视图来格式化模型返回的数据,并通过视图呈现给用户。
MVC优点:
(1)允许多种用户界面的扩展。(2)易于维护。(3)功能强大的用户界面。

2. MVP模式

MVP是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。区别:MVC中V和M可直接通信,MVP中不允许。

使用MVP模式来设计表现层,可以有以下的优点
(1)模型与视图完全分离,可以修改视图而不影响模型。
(2)可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部。
(3)可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的
有用,因为视图的变化总是比模型的变化频繁。
(4)如果把逻辑放在Presenter中,就可以脱离用户接口来测试这些逻辑(单元测试)。

目前,MVP模式被更多地用在Android开发当中。

3. MVVM模式

MVVM模式全称是模型-视图-视图模型(Model-View-ViewModel),它和MVC、MVP类似,主要目的都是为了实现视图和模型的分离,不同的是MVVM中,View与Model的交互通过ViewModel来实现。ViewModel是MVVM的核心,它通过DataBinding实现View与Model之间的双向绑定,其内容包括数据状态处理、数据绑定及数据转换。例如,View中某处的状态和Model中某部分数据绑定在一起,这部分数据一旦变更将会反映到View层。而这个机制通过ViewModel来实现。
数据的双向绑定,这使得MVVM更适用于数据驱动的场景,尤其是数据操作特别频繁的场景。
但也正是由于数据和视图的双向绑定,导致出现问题时不太好定位来源,有可能由数据问题导致、也有可能由业务逻辑中对视图属性的修改导致

13.2.2 使用XML设计表现层,统一Web Form与Windows Form的外观

这么一段XML很清晰地表示一个控件容器位置是(16,22,78,200),包含了一个不可视按钮。
总结:XML和HTML都是标记语言,而且各有千秋。

13.2.3 表现层中UIP设计思想

  • 导航和工作流控制:这些将不会出现的Ul中,但是经常因为要基于业务逻辑决定哪一个视图将被显示。这导致代码的不雅和难于管理。
  • 导航和工作流改变:用传统的UI技术改变应用程序的界面(改变页面的顺序或者添加删除页面)是非常痛苦的。
  • 状态管理:不管是在windows form还是在web form中,在视图间维护状态都是比较困难的。
  • 保存当前交互的快照:你可能想保存一个交互的快照并且在别的地方(不同的时间,不同的地点)重新开始它。
使用UIP框架的应用程序把表现层分为了以下几层。
● User Interface Components:这个组件就是原来的表现层,用户看到的和进行交互都是这
个组件,它负责获取用户的数据并且返回结果。
● User Interface Process Components:这个组件用于协调用户界面的各部分,使其配合后
台的活动,例如导航和工作流控制,以及状态和视图的管理。用户看不到这一组件,但
是这些组件为User Interface Components提供了重要的支持功能。

                        

UIP的组件主要负责的功能是:管理经过User Interface Components的信息流;管理UIP中各个事件之间的事务;修改用户过程的流程以响应异常;将概念上的用户交互流程从实现或者涉及的设备上分离出来;保持内部的事务关联状态,通常是持有一个或者多个的与用户交互的事务实体。因此,这些组件也能从UI组件收集数据,执行服务器的成组的升级或是跟踪UIP中的任务过程的管理。

13.2.4 表现层动态生成设计思想

基于XML的界面管理技术可实现灵活的界面配置、界面动态生成和界面定制。其思路是
用XML生成配置文件及界面所需的元数据,按不同需求生成界面元素及软件界面。
基于XML界面管理技术,包括界面配置、界面动态生成和界面定制三部分。

简单理解:用XML把页面需要的元素(如按钮、文本框、图标等等)及元素的位置、属性等保存起来,然后通过DOM API读取这个XML,动态的生成网页。

一些现有的框架思想也是这样,比如权限具体到页面的按钮上。

13.3 中间层架构设计

13.3.1业务逻辑层组件设计

业务逻辑组件分为接口和实现类两个部分。
接口用于定义业务逻辑组件,定义业务逻辑组件必须实现的方法是整个系统运行的核心。
通常按模块来设计业务逻辑组件,每个模块设计一个业务逻辑组件,并且每个业务逻辑组件以
多个DAO(Data Access Object)组件作为基础,从而实现对外提供系统的业务逻辑服务。增加
业务逻辑组件的接口,是为了提供更好的解耦,控制器无须与具体的业务逻辑组件耦合,而是
面向接口编程。

1.业务逻辑组件的实现类

业务逻辑组件以DAO组件为基础,必须接收Spring容器注入的DAO组件,因此必须为业
务逻辑组件的实现类提供对应的setter方法。业务逻辑组件的实现类将DAO组件接口实例作为
属性(面向接口编程),而对于复杂的业务逻辑,可能需要访问多个对象的数据,那么只需在这
个方法里调用多个DAO接口,将具体实现委派给DAO完成。

2.业务逻辑组件的配置

配置信息。

13.3.2业务逻辑层工作流设计

工作流定义为:业务流程的全部或部分自动化,在此过程中,文档、信息或任务按照一定的过程规则流转,实现组织成员间的协调工作以达到业务的整体目标。
它解决的主要问题是:使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者是促使此目标的实现。
用工作流的思想组织业务逻辑,优点是:将应用逻辑与过程逻辑分离,在不修改具体功能
的情况下,通过修改过程模型改变系统功能,完成对生产经营部分过程或全过程的集成管理,
可有效地把人、信息和应用工具合理地组织在一起,发挥系统的最大效能。
例如:

13.3.3业务逻辑层实体设计

业务逻辑层实体具有以下特点:

  • 业务逻辑层实体提供对业务数据及相关功能(在某些设计中)的状态编程访问。
  • 业务逻辑层实体可以使用具有复杂架构的数据来构建,这种数据通常来自数据库中的多个相关表。业务逻辑层实体数据可以作为业务过程的部分I/O参数传递。
  • 业务逻辑层实体可以是可序列化的,以保持它们的当前状态。例如,应用程序可能需要在本地磁盘、桌面数据库(如果应用程序脱机工作)或消息队列消息中存储实体数据。
  • 业务逻辑层实体不直接访问数据库,全部数据库访问都是由相关联的数据访问逻辑组件提供的。
  • 业务逻辑层实体不启动任何类型的事务处理,事务处理由使用业务逻辑层实体的应用程序或业务过程来启动。
将业务逻辑层实体表示为XML的优点如下。
(1)标准支持。XML是World Wide Web Consortium(W3C)的标准数据表示格式。
(2)灵活性。XML能够表示信息的层次结构和集合。
(3)互操作性。在所有平台上,XML都是与外部各方及贸易伙伴交换信息的理想选择。
举例:

将业务逻辑层实体表示为通用DataSet的优点如下。

  • (1)灵活性。DataSet可以包含数据的集合,能够表示复杂的数据关系。
  • (2)序列化。在层间传递时,DataSet本身支持序列化。
  • (3)数据绑定。可以把DataSet绑定到ASP.NET应用程序和Windows窗体应用程序的任意用户界面控件。
  • (4)排序与过滤。可以使用DataView对象排序和过滤DataSet。应用程序可以为同一个DataSet创建多个DataView对象,以便用不同方式查看数据。
  • (5)与XML的互换性。可以用XML格式读写DataSet。
  • (6)开放式并发。在更新数据时,可以配合使用数据适配器与DataSet方便地执行开放式并发检查。
  • (7)可扩展性。如果修改了数据库架构,则适当情况下数据访问逻辑组件中的方法可以创建包含修改后的DataTable和DataRelation对象的DataSet。

将业务逻辑层实体表示为有类型的DataSet。有类型的DataSet是包含具有严格类型的方法、属性和类型定义以公开DataSet中的数据和元数据的类。 将业务逻辑层实体表示为有类型的DataSet的优点如下。

  • (1)代码易读。要访问有类型的DataSet中的表和列,可以使用有类型的方法和属性。
  • (2)有类型的方法和属性的提供使得使用有类型的DataSet比使用通用DataSet更方便。使
  • 用有类型的DataSet时,IntelliSense将可用。
  • (3)编译时类型检查,无效的表名称和列名称将在编译时而不是在运行时检测。

13.3.4业务逻辑层框架

业务框架位于系统架构的中间层,是实现系统功能的核心组件。采用容器的形式,便于系统功能的开发、代码重用和管理。
例如:
从图13-10中可以看到,业务层采用业务容器(Business Container)的方式存在于整个系统当中,采用此方式可以大大降低业务层和相邻各层的耦合,表示层代码只需要将业务参数传递给业务容器,而不需要业务层多余的干预。如此一来,可以有效地防止业务层代码渗透到表示层。
在业务容器中,业务逻辑是按照Domain Model—Service—Control思想来实现的。
(1)Domain Model是领域层业务对象,它仅仅包含业务相关的属性。
(2)Service是业务过程实现的组成部分,是应用程序的不同功能单元,通过在这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,这使得构建在各种这样的系统中的服务可以以一种统一和通用的方式进行交互。这种具有中立的接口定义(没有强制绑定到特定的实现上)的特征称为服务之间的松耦合。松耦合系统的好处有两点,一是它的灵活性,二是当组成整个应用程序的每个服务的内部结构和实现逐渐地发生改变时,它能够继续存在。
(3)Control服务控制器,是服务之间的纽带,不同服务之间的切换就是通过它来实现的。
通过服务控制器控制服务切换可以将服务的实现和服务的转向控制分离,提高了服务实现的灵
活性和重用性。
以下是Domain Model—Service—Control三者的互动关系。
(1)Service的运行会依赖于Domain Model的状态,反之,Service也会根据业务规则改变
Domain Model的状态。
(2)Control作为服务控制器,根据Domain Model的状态和相关参数决定Service之间的执
行顺序及相互关系。
Domain Model—Service—Control的互动关系,是吸取了Model—View—Control的优点,在
“控制和显示的分离”的基础之上演变而来的,通过将服务和服务控制隔离,使程序具备高度的
可重用性和灵活性。

13.4 数据访问层设计

13.4.1 5种数据访问模式

1.在线访问

在线访问是最基本的数据访问模式,也是在实际开发过程中最常采用的。这种数据访问模式会占用一个数据库连接,读取数据,每个数据库操作都会通过这个连接不断地与后台的数据源进行交互。

2.DataAccess Object

DAO模式是标准J2EE设计模式之一,开发人员常常用这种模式将底层数据访问操作与高层业务逻辑分离开。
一个典型的DAO实现通常有以下组件。
(1)一个DAO工厂类。
(2)一个DAO接口。
(3)一个实现了DAO接口的具体类。
(4)数据传输对象。
这当中具体的DAO类包含访问特定数据源的数据的逻辑。

3.Data Transfer Object

Data Transfer Object是经典EJB设计模式之一。DTO本身是这样一组对象或是数据的容器,它需要跨不同的进程或是网络的边界来传输数据。这类对象本身应该不包含具体的业务逻辑,并且通常这些对象内部只能进行一些诸如内部一致性检查和基本验证之类的方法,而且这些方法最好不要再调用其他的对象行为。
在具体设计这类对象(DTO)时,通常可以有如下两种选择。
(1)使用编程语言内置的集合对象,它通常只需要一个类,就可以在整个应用程序中满足
任何数据传输目的;而且几乎所有的编程语言都内置了集合类型,不需要再另外编写实现代码。
同时,使用内置的集合对象来实现DTO对象的时候,客户端必须按位置序号(在简单数组的
情况下)或元素名称(在键控集合的情况下)访问集合内的字段。不过,集合存储的是同一类
型(通常是最基本的Object类型)的对象,这有时会导致在编译时碰到一些无法检测到的编码
错误。
(2)通过创建自定义类来实现DTO对象,通过定义显示的get或是set方法来访问数据。
这种方式能够提供与任何其他对象完全一样的、客户端应用程序可访问的强类型对象。这种对
象可以提供编译时的类型检查,但是增加了编码的工作量,若应用程序发出许多远程调用的话,
需要编写大量的调用代码。
具体实现中有许多方法试图将上述这两种方法的优点结合在一起.

4.离线数据模式

离线数据模式是以数据为中心,数据从数据源获取之后,将按照某种预定义的结构(这种结构可以是SDO中的Data图表结构,也同样可以是ADO.NET中的关系结构)存放在系统中,成为应用的中心。离线,对数据的各种操作独立于各种与后台数据源之间的连接或是事务;与XML集成,数据可以方便地与XML格式的文档之间互相转换;独立于数据源,离线数据模式的不同实现定义了数据的各异的存放结构和规则,这些都是独立于具体的某种数据源的。

5.对象/关系映射(Object/Relation Mapping,O/R Mapping)

在最近几年,采用OR映射的指导思想来进行数据持久层的设计似乎已经成了一种潮流。
对象/关系映射的基本思想来源于这样一种现实:大多数应用中的数据都是依据关系模型存储
在关系型数据库中;而很多应用程序中的数据在开发或是运行时则是以对象的形式组织起来的。
那么,对象/关系映射就提供了这样一种工具或是平台,能够帮助将应用程序中的数据转换成
关系型数据库中的记录;或是将关系数据库中的记录转换成应用程序中代码便于操作的对象。

13.4.2 工厂模式在数据访问层应用

数据库有很多种,相应的每种数据库访问类也不同,可是实际开发中,同一个功能,遇到不同的数据库就要写一个专门的访问类,或者复杂点的系统需要抽取不同种类的数据库的时候,就比较尴尬,每种数据库都得配上个访问类,而且后期的维护也不好。

那怎么办呢?搞一个专门根据不同数据库访问的一个类或者一个组件,让它来代替我们对每个数据库写一个对应的访问类,而我们直接调用它不就好了。

这时候,利用工厂思想就可以实现。

工厂模式定义一个数据库访问接口,这个接口只包含要干啥而且是通用的工作,比如所有的数据库都有类型吧(oracle、sqlserver、mysql...)需要连接吧,都需要打开连接吧,都需要执行相应的语句吧,最后还得关闭连接吧等等这些。

用子类继承这个接口,在子类里具体实现要实例化的哪种数据库。

参考代码:

// 访问接口
public interface DataAccess
{
DatabaseType DatabaseTypelget;) //数据库类型
IDbConnection DbConnection{get;} //得到数据库连接
void Open(); //打开数库连接
void Close(); //关闭数据库连接
IDbTransaction BeginTransaction(); //开始一个事务
int ExecuteNonQuery(string commandText); //执行Sq1语句
DataSet ExecuteDataset(string commandText); //执行Sq1,返回DataSet
}
//子类实现代码
public sealed class MSSqlDataAccess :AbstractDataAccess
{
…//具体实现代码
}
public class oleDbDataAccess :AbstractDataAccess
{
…//具体实现代码
}
public class OracleDataAccess ;AbstractDataAccess
{
…//具体实现代码
}

再省点事偷个懒的,把这个自动切换功能给它加上

public sealed class DataAccessFactory
{
private DataAccessFactory(){}
private static PersistenceProperty defaultPersistenceProperty;
public static PersistenceProperty DefaultPersistenceProperty
{
get{return defaultPersistenceProperty;}
set{defaultPersistenceProperty=value;}
}
public static DataAccess CreateDataAccess(PersistenceProperty pp)
{
DataAccess dataAccess;
switch(pp.DatabaseType)
{
case(DatabaseType.MSSQLServer):
dataAccess = new MSSqIDataAccess(pp.ConnectionString);
break;
case(DatabaseType.Oracle):
dataAccess = new OracleDataAccess(pp.ConnectionString);
break;
case(DatabaseType.OleDBSupported):
dataAccess = new OleDbDataAccess(pp.Connectionstring);
break;
default:
dataAccesswnew MSSqlDataAccess(pp.Connectionstring);
break;
}
return dataAccess;
}public static DataAccess CreateDataAccess()
{
return CreateDataAccess(defaultPersistenceProperty);
}
}
现在一切都完成了,客户端在代码调用的时候,可能就是采用如下形式。
PersistenceProperty pp = new PersistenceProperty();
pp.Connectionstring -"server=127.0.0.1;uid=sa;pwd=;database-Northwind;”;
pp.DatabaseType = DatabaseType.MSSQLServer;
pp.UserID =“sa”;
pp.Password -"”;
DataAccess db= DataAccessFactory.CreateDataAccess(pp)
db.Open();
…//db.需要的操作
db.Close();

切换数据库只要改变红色类型就行了。

13.4.3 ORM、Hibernate与CMP2.0设计思想

运用sql语句是需要一定的数据库知识门槛的,但是很多的开发人员并不具备这方面的知识储备,比如同样是取数据,有的人写的语句就0.01秒出结果,有的人写的需要1秒钟才出结果,如果不具备数据库方面的知识或者不够了解,那么还要花费大量的时间和精力来搞明白这些,这时候ROM思想诞生了,它们的作用就是让你像写代码一样操作数据库的语句,你只关心你的业务逻辑,至于与数据库打交道的(生成sql然后执行)让ORM来干。

ORM也是有缺点的,毕竟封装了一层比直接写语句效率低,但是随着ORM技术的发展,以及配合Cache技术等等,效率也是不错的。

13.4.4 灵活运用XML Schema

XML Schema用来描述XML文档合法结构、内容和限制。
XML Schema充分地改造了并且极大地扩展了DTDs(传统描述XML文档结构和内容限制的机制)的能力,将逐步替代DTDs。
XML Schema同XML规范、Namespace规范一起成为XML体系的坚实基础。
XML Schema规范由如下三部分组成。
(1)XML Schema Part0:Primer。一个非标准化的文档,提供了XML Schema的一个简单可
读的描述,目的是快速地理解如何利用XML Schema语言创建一个Schema(框架)。
(2)XMLSchema Partl:Structures。这一部分详细说明了XML Schema定义语言,这个语言
为描述XML1.0文档的结构和内容限制提供了便利,包括开发了XML Namespace(命名空间)
的使用。
(3)XML Schema Part2:Datatypes。这一部分定义了可用于XML Schema和其他XML规范
中的定义数据类型的方法。这个数据类型语言,本身由XML 1.0自描述,提供了说明元素和属
性数据类型的XML1.0文档类型定义(DTDs)的一个超集。这部分提出了标准的数据类型内容
集合,其中讲述了目的、需求、范围和术语。XML Schema与DTD相比,有其独特的特点,提
供了丰富的数据类型,实现了继承和复用,与命名空间紧密联系,易于使用。
特征:
ML Schema规范提供了丰富的数据类型。
XML Schema支持继承是它的另一特点。
XML Schema与XML Namespace紧密联系,使得在一个命名空间中创建元素和属性非常容易。

13.4.5 事务处理设计

ACID原则是原子性 (Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)的缩写。

13.4.6 连接对象管理设计

共享资源---连接池。

连接池简单理解:

建立、关闭数据库连接非常的消耗资源的,但是我们的应用访问数据库是很频繁的,这样不停的建立、关闭造成大量的资源损耗和浪费,

那怎么办呢?

搞一个共享的连接可以吧,连接一直开着不关闭,你用完了,我再用,我用完了它再用,这样共享连接就会减少很多的资源消耗。访问量上来了,那么一个连接共享就不够了,好吧,那么给这个应用100个连接足够了,那就系统初始化就自动建立了100个连接,这100个连接就组成了连接池(当然不代表连接池哈,连接池还得管理哪些连接用完了释放,哪些正在连接打标记等等),这个应用的所有对数据库的操作都从连接池里取连接用。

13.5 数据架构规划与设计

13.5.1数据库设计与类的设计融合

对类和类之间关系的正确识别是数据模型的关键所在。
好模型的目标是将工程项目整个生存期内的花费减至最小,同时也会考虑到随时间的推移系统将可能发生的变化,因而设计时也要考虑能适应这些变化。因此,将目光集中在最大限度地降低开发费用上是一个错误。

13.5.2数据库设计与XML设计融合

目前Web数据发展的多样化和复杂化,传统的数据库技术很难存储和管理所有的web数据了,而且XML有代替HTML趋势。

鉴于以上情况,存储数据开始考虑用XML与现有的数据库结合的方式。

XML文档分为两类:
一类是以数据为中心的文档,这种文档在结构上是规则的,在内容上是同构的,具有较少的混合内容和嵌套层次,人们只关心文档中的数据而并不关心数据元素的存放顺序,这种文档简称为数据文档,它常用来存储和传输Web数据。
另一类是以文档为中心的文档,这种文档的结构不规则,内容比较零散,具有较多的混合内容,并且元素之间的顺序是有关的,这种文档常用来在网页上发布描述性信息、产品性能介绍和E-mail信
息等。
已经提出的XML文档的存储方式有两种:基于文件的存储方式和数据库存储方式。
(1)基于文件的存储方式。基于文件的存储方式是指将XML文档按其原始文本形式存
储,主要存储技术包括操作系统文件库、通用文档管理系统和传统数据库的列(作为二进制
大对象BLOB或字符大对象CLOB)。这种存储方式需维护某种类型的附加索引,以建立文
件之间的层次结构。基于文件的存储方式的特点:无法获取XML文档中的结构化数据;通
过附加索引可以定位具有某些关键字的XML文档,一旦关键字不确定,将很难定位;查询
时,只能以原始文档的形式返回,即不能获取文档内部信息;文件管理存在容量大、管理难
的缺点。
(2)数据库存储方式。数据库在数据管理方面具有管理方便、存储占用空间小、检索速度
快、修改效率高和安全性好等优点。一种比较自然的想法是采用数据库对XML文档进行存取
和操作,这样可以利用相对成熟的数据库技术处理XML文档内部的数据。数据库存储方式的
特点:能够管理结构化和半结构化数据;具有管理和控制整个文档集合本身的能力;可以对文
档内部的数据进行操作;具有数据库技术的特性,如多用户、并发控制和一致性约束等;管理
方便,易于操作。
在某种程度上,XML及其一系列相关技术就是一个数据库系统。它提供了传统数据库所具有的特点,如存储(以XML文档形式)、数据库的模式(DTD或XMLSchema)、查询语言(XQuery、XPath、XQL和XML-QL等)和编程接口(如SAX、DOM)等。但与传统数据库相比,它在存储、索引、安全、多用户访问和事务管理等方面还存在不足之处。
在一定的环境下,例如当数据量和操作用户较少并且性能要求不高的情况下,XML文档能够作为数据库在应用程序中使用。如果应用程序有许多操作用户,并且要求严格的数据完整性和性能要求,则不宜采用XML文档。

13.6 物联网层次架构设计

物联网可以分为三个层次,
底层是用来感知数据的感知层,即利用传感器、二维码、RFID等设备随时随地获取物体的信息。第二层是数据传输处理的网络层,即通过各种传感网络与互联网的融合,将对象当前的信息实时准确地传递出去。
第三层则是与行业需求结合的应用层,即通过智能计算、云计算等将对象进行智能化控制。
网络层中的感知数据管理与处理技术是实现以数据为中心的物联网的核心技术,包括传
感网数据的存储、查询、分析、挖掘和理解,以及基于感知数据决策的理论与技术。云计算
平台作为海量感知数据的存储、分析平台,将是物联网网络层的重要组成部分,也是应用层
众多应用的基础。在产业链中,通信网络运营商和云计算平台提供商将在物联网网络层占据重要的地位。

13.7 层次式架构案例分析---看看即可

13.7.1电子商务网站(网上商店PetShop)

13.7.2基于物联网架构的电子小票服务系统

相关文章:

第13章 层次式架构设计理论与实践

层次式架构的核心思想是将系统组成为一种层次结构,每一层为上层服务,并作为下层客户。其实不管是分层还是其他的架构都是为了解耦,更好的复用,只要秉承着这种思想去理解一切都迎刃而解了。 13.1 层次上体系结构概述 回顾一下软件…...

FreeRtos进阶——消息队列的操作逻辑

消息队列(queue) 在不同的任务之间,如果我们需要互相之间通信,使用全局变量进行通信,是一种不安全的通信的方式。为保证线程安全,我们需要引入消息队列的通信方式。 粗暴的消息队列 为保证线程的安全&am…...

WordPress搭建流程

1. 简介 WordPress 是一个 PHP 编写的网站制作平台。WordPress 本身免费,并且拥有众多的主题可以使用,适合用于搭建个人博客、公司官网、独立站等。 2. 环境准备 2.1 WordPress 下载 WordPress 可以在 Worpress中文官网 下载(如果后续要将后台调成中文的话,一定要从中文…...

数据集004:跌倒检测数据集 (含数据集下载链接)

数据集简介: 该数据集为跌倒检测数据集,属于imageclassify任务,分为fall和nofall两大类,累计共1000张图片,均为人工标注 xml格式,可用于yolo训练。 数据集链接:跌倒检测数据集(1000…...

苹果与OpenAI合作在即:iOS 18中的ChatGPT引发期待与担忧

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

Android 逆向学习【2】——APK基本结构

APK安装在安卓机器上的,相当于就是windows的exe文件 APK实际上是个压缩包 只要是压缩的东西 .jar也是压缩包 里面是.class(java编译后的一些东西) APK是Android Package的缩写,即Android安装包。而apk文件其实就是一个压缩包,我们可以将apk文件的后…...

你对仲裁裁决不服怎么办?我教你四个狠招!

你对仲裁裁决不服怎么办?我教你四个狠招! 这个标题是什么意思呢?也就是说,当你(或用人单位)向劳动仲裁委提出仲裁申请后,但劳动仲裁结果没有维护你的权益,或者你不满意,…...

绿色智能:低代码开发在AI机器学习中的深度应用与实践案例

随着科技的飞速进步,软件开发的方式也在不断演变。其中,低代码开发作为一种新兴的编程方式,以其高效、便捷的特性受到了广泛关注。同时,AI机器学习技术的发展也为软件开发带来了新的可能。本文将简要介绍低代码开发的概念&#xf…...

《NoSQL数据库技术与应用》 文档存储数据库MongoDB

搜索 《NoSQL数据库技术与应用》 教学设计 课程名称:NoSQL数据库技术与应用 授课年级: 20xx年级 授课学期: 20xx学年第一学期 教师姓名: 某某老师 2020年5月6日 课题 名称 第2章 文档存储数据库MongoDB 计划学时 4 课时 内容 分…...

设置AXI主寄存器切片和AXI数据FIFO

设置AXI主寄存器切片和AXI数据FIFO 打开MHS文件&#xff0c;并为每个AXI主机设置启用寄存器切片/启用数据FIFO。到 确定正确的设置&#xff0c;使用下表中的信息搜索MHS。 进行搜索时&#xff0c;将<intf_name>替换为相关的BUS_INTERFACE名称。 例如&#xff0c;BUS_INTE…...

Golang协程和通道

文章目录 协程&#xff08;goroutine&#xff09;基本介绍GMP模型协程间共享变量 通道&#xff08;channel&#xff09;基本介绍channel的定义方式channel的读写channel的关闭channel的遍历方式只读/只写channelchannel最佳案例select语句 协程&#xff08;goroutine&#xff0…...

Enable Full Line suggestions 启用全行建议

开启后效果如下&#xff1a; 直接提示可能要输入的参数...

Java 文件操作和输入输出流

在 Java 编程中&#xff0c;文件操作和输入输出流是非常常见和重要的任务&#xff0c;它们允许你读取和写入文件、处理数据流等。 文件操作概述 文件操作是指对文件进行创建、读取、写入、删除等操作的过程。在 Java 中&#xff0c;文件操作通常涉及到使用文件对象、输入输出…...

MyBatis中的Where标签:提升你的SQL查询效率

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 理解MyBatis的Where标签 MyBatis是一款优秀的持久层框架&#xff0c;它提供了许多强大的标签来帮助编写更优雅、高效的SQL语句。其中&#xff0c;<where>标签是使用频率极高的一个&#xff0c;它能够自动处理…...

Docker(三) 容器管理

1 容器管理概述 Docker 的容器管理可以通过 Docker CLI 命令行工具来完成。Docker 提供了丰富的命令&#xff0c;用于管理容器的创建、启动、停止、删除、暂停、恢复等操作。 以下是一些常用的 Docker 容器命令&#xff1a; 1、docker run&#xff1a;用于创建并启动一个容器。…...

自己动手写docker——Namespace

Linux Namespace linux Namespace用于隔离一系列的系统资源&#xff0c;例如pid&#xff0c;userid&#xff0c;netword等&#xff0c;借助于Linux Namespace&#xff0c;可以实现容器的基本隔离。 Namespce介绍 Namespace类型系统调用参数作用Mount NamespaceCLONE_NEWNS隔离…...

【前端学习笔记】HTML基础

HTML 一、HTML介绍1.HTML概念2.文档声明3.字符编码4. HTML标签5. HTML属性 二、标签1.meta标签2.语义标签3.布局标签4.列表5.超链接6.图片7.字符实体8.内联格式9.HTML 表格10.HTML 表单 三、HTML5新特性1. 本地存储2. Cookie3. 语义化标签4.多媒体元素5.表单增强6.Canvas7.SVG …...

JS Lab

如何用 JavaScript 在浏览器中弹窗如何在 JavaScript 中制作鼠标滑过按钮改变背景颜色如何在 JS 中点击按钮使数字增加如何在 JS 中循环打印多少次 HTML <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title…...

Vue:快速上手

一、简介 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0c;…...

HTML并集,交集,子代,后代选择器

1,交集选择器 他们必须满足既是p又是.box的关系&#xff08;直接连写&#xff0c;没有任何符号&#xff09; p.box{color:red; } <div class"box"> 1 </div> <p class"box">2</p> <p>3</p> 2.并集选择器 将div,p,…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)

第一篇&#xff1a;Liunx环境下搭建PaddlePaddle 3.0基础环境&#xff08;Liunx Centos8.5安装Python3.10pip3.10&#xff09; 一&#xff1a;前言二&#xff1a;安装编译依赖二&#xff1a;安装Python3.10三&#xff1a;安装PIP3.10四&#xff1a;安装Paddlepaddle基础框架4.1…...