- 浏览: 496544 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (1028)
- [发布至博客园首页] (826)
- [随笔分类]个人生活随笔 (14)
- [网站分类]首页候选区 (26)
- [网站分类]SharePoint (15)
- [网站分类]其他技术区 (6)
- [随笔分类]批处理技巧 (6)
- [随笔分类].net 2.0 (3)
- [随笔分类]SharePoint2007(MOSS2007) (0)
- [网站分类].NET新手区 (6)
- [网站分类]ASP.NET (6)
- [网站分类]架构设计 (18)
- [网站分类]程序人生 (2)
- [网站分类]SQL Server (2)
- WCF (3)
- 编程技巧 (2)
- 模式架构 (2)
- 分析设计 (4)
- 生活随笔 (0)
- 软件工程 (1)
- Android实例 (2)
最新评论
-
zilong0536:
楼主您好:
请问发表博文支持图片的功能怎么实现啊,一直没有思路 ...
新浪微博开放平台开发-android客户端(3) -
nicegege:
小弟 学习了
帮助中国移动设计10086的排队小模块 -
zl7824516:
用什么技术没说啊
通告(公告),消息(站内短信),提醒的设计:通告 -
virusswb:
源码下载: SinaWeibo2 源码下载之后,将后缀改为ra ...
新浪微博开放平台开发-android客户端(3) -
Jimmyxu0311:
找不到源码下载
新浪微博开放平台开发-android客户端(3)
服务层的相关模式
1 引言
我们把服务层看做是暴露给用户界面的一个服务集合。大多数时候,我们会发现服务层的方法很容易满足用户的行为。在大多数企业应用中,CRUD是常用的操作。有的时候在一次操作中会处理多个实体。
服务层包括角色管理,数据验证,通知,调整返回给用户界面的数据,或者是整合系统可能的需求。
在谈到这些的时候,一些设计模式可能会有帮助。下面是一些在实现服务层的过程中有帮助的模式。
2 远程外观模式Remote Facade Pattern
远程外观模式是用来修改已经实现的方法的粒度的,外观模式没有实现任何新功能。它只是在原有的API之上包装一层不同的外观。为什么会需要外观模式呢?
2.1 使用外观模式的动机
外观模式改变一个已经存在的对象的访问方式。举一个货运商在线服务的例子。每一个货运商对于注册运输的货物、跟踪货物和其他服务都有自己的API,他们的细节在你的应用中可能都用不着。通过建立一个统一的API,你可以隐藏货运商API的细节,使得你的应用有一个清晰的接口。
换句话说,如果你想要你的接口处理一个简单的接口,这些必要性强迫你创建另外一个外观。实际上,这就是经典的远程外观模式的精确定义。
外观模式的好处就是允许你在一系列定义好的细粒度对象之上,定义粗粒度的接口。
面向对象使得你创建了很多小的对象,职责分离,细粒度对象。但是这些对象不适合分布式。为了是这些对象有效,你需要做出一些调整。你不想改变细粒度对象的任何实现,但是你需要通过这些对象可以执行一批操作。在这种情况下,你需要创建新的方法,移动更大的数据。当你这么做的时候,实际上就是修改了已经存在的接口粒度,也就是创建了外观模式。让我们回到货运订单的例子。通过你自己的API你可以发送多个订单,不用使用货运商的API来发送单个的订单,这里我们假设货运商不支持多个订单的API。
2.2 远程外观模式和服务层
经过设计,服务层本质上拥有了粗粒度的接口,因为它更趋向于抽象一定数量的细小操作,来给客户端使用。在这点上,服务层已经是一种位于业务逻辑层和领域层对象之上的外观模式。
{
void Create(Order o);
List<Order> FindAll();
Order FindByID(int orderID);
}
如果你使用WCF,需要在服务层接口上添加协议attribute。
public interface IOrderService
{
[OperationContract]
void Create(Order o);
[OperationContract]
List<Order> FindAll();
[OperationContract]
Order FindByID(int orderID);
}
所有非基本类型的数据都需要添加datacontract标记。在WCF运行的时候,这些标记会为指定的类型自动创建数据传输对象DTO。
public class Order
{
[DataMember]
int OrderID {get; set;};
[DataMember]
DateTime OrderDate {get; set;};
}
如果你使用asp.net xml web service。上面的类不要添加任何标记,只需要在服务层类的方法上添加WebMethod标记就可以了。
在使用外观模式的时候,你可能会需要更粗粒度的接口,你也可能会用到DTO,或者你都会用到。下面的接口就和领域对象解耦了,更加聚焦在和表现层的交互上。
{
void Create(OrderDto o);
List<OrderDto> FindAll();
OrderDto FindByID(int orderID);
List<OrderDto> SearchOrder(QueryByExample query);
}
OrderDto可能是领域类Order的子集或者是包含Order(可能会整合依赖的对象OrderDetail),QueryByExample是一个专门的类,会传输用户界面的一些条件给服务层,我更喜欢定义写Find类,例如OrderFind。里面就是一些查询条件,例如:时间、编号、金额等等。
实际上,如果用户界面改动比较大的话,就需要修改服务层。你可能会需要重构服务层,或者是在外面再次的使用外观模式来包装。
3 数据传输对象模式
DTO(Data Transfer Object数据传输对象)仅仅是一个跨越应用边界传输数据的对象,主要的目的是最小化网络的往返。
3.1 使用DTO模式的动机
有两个主要的动机。一个是在你调用远程对象的时候,最小化网络的往返;另外一个是在前端显示和后端的领域模型之间维护一个松散的耦合关系。
在多数情况,DTO都只有属性,没有操作。DTO在领域模型方案中扮演着重要的角色。不是在所有的情况,表现层都可以直接使用本地的领域对象。如果是服务层和表现层在同一个物理层的话,例如表现层是web网页的形式,可以直接使用。如果服务层和表现层不在同一个物理层,最好不要通过领域对象来交换数据。主要的原因是你的领域对象之间可能是彼此依赖的,甚至是循环引用的关系,这会严重的影响它们的序列化能力,甚至是序列化失败的问题。
关于为什么需要DTO以及什么时候需要DTO的个人理解,仅供参考:
都在同一层的话,不存在对象通过网络传输的问题,所以可以直接使用领域模型,而且效率还高,没有网络传输和延迟。
不在同一层的话,就存在网络传输的问题,领域模型中既包含了数据,也包含了操作,数据可以在层之间传输,可是操作时不能传输的。而且为了解耦领域模型中的对象和传输的对象,而且领域模型的粒度较小,传输领域模型的话,可能需要多次调用,才可以满足一次界面的显示,这样会增加网络的往返次数。
同时,界面显示的内容可能来自几个领域模型对象,也可能是一个领域模型对象中的几个属性。所以才单独建立DTO用来在层之间传输数据。
独立出来的话,就可能就会涉及到序列化的问题。
例如,要考虑到WCF和asp.net xml web service的xml序列化都不能处理循环引用的情况。同时,如果你使用领域模型,你会发现每一个Customer对象都有多个Order对象,每一个Order对象都会对应一个Customer对象。在复杂的领域模型中,循环引用很常见。
循环引用:
循环引用就是两个对象相互引用,每个对象的都有对方类型的属性存在,这样就造成了循环引用。也就是下面的情况。
public class Order
{
public string OrderSeqNo
{
get;
set;
}
public Customer Customer
{
get;
set;
}
}
{
public List<Order> Orders
{
get;
set;
}
}
DTO可以帮助你避免这种风险,使你的系统更加整洁。但是,它也引入和新的复杂等级。我们需要额外的层,DTO适配层。
3.2 数据传输对象和服务层
当你在开始的架构会议中讨论DTO的时候,你经常会听到反对使用DTO的声音。数据传输对象可能会浪费开发时间和资源。问题是DTO的存在有他的必要性。可以不使用它们,但是他们在企业级架构中任然扮演重要的角色。
在理论上,我们提倡在两个层之间发生通信的时候使用DTO,包括表现层和服务层的通信。另外,我们还提倡在每一个截然不同的用户界面使用不同的DTO,甚至是不同的DTO请求和相应。
在实际的使用中,事情可能有所不同。DTO意味着在服务层添加新的一层代码,随着而来的是复杂性。只要没有更好的选择,这样做是可以接受的。我们在强调DTO的花销的时候很容易低估它的花销。当你拥有上百个领域对象的时候,2-3倍的类就会使噩梦了。
只在使用DTO的好处很明显,而且必要性很明显的时候再用DTO,否则就直接使用领域对象。
使用DTO我们还需要内部的、项目定制的ORM层。
对于ORM层,我们有很多工具可以选择,商业的和开源的。WCF和asp.net xml web service在序列化数据的时候生成DTO,但是对于数据格式的控制,它们提供的功能有限。通过 WCF中的[IgnoreDataMember]和asp.net xml web service中的[XmlIgnore ],你可以将一些属性从DTO中删除,也就是在DTO对象中没有这些属性。但是在请求和相应需要不同的类的时候,或者是不同的用户界面使用不同的DTO的时候,你没有自动产生特定的DTO的方法。到目前为止,还不存在这样的向导。需要我们手动来完成,自己定义DTO。
4 适配器模式
当你在分层系统中使用DTO的时候,你可能会为不同的接口而调整领域模型。你需要实现适配器模式,一个经典而且很流行的模式。适配器的本质是将一个类的接口转换为用户希望的另外一个接口。
4.1 使用适配器模式的动机
适配器的职责是将数据表现为另外一种格式。例如:适配器会将从数据库中读取的bit格式的列,转换为用户接口中的boolean,来方便使用。
在一个分层的方案中,适配器模式被用于将一个领域对象转换为DTO对象,或者是反过来。在适配器类中没有复杂的逻辑,但是你需要一些适配器类来赋值DTO对象。
4.2 适配器模式和服务层
给每一个DTO配置一个适配器类,必然会增加开发的成本。
在评估DTO的时候,对于将要产生的一大丢类,你应该持续的考虑维护他们的问题。你要记住,在每一个适配器类中, 需要有两个功能,一个是从领域对象到DTO;一个是从DTO到领域对象。
发表评论
-
NET 应用架构指导 V2 学习笔记(十六) 服务层设计指导
2010-06-04 00:13 548如果你的应用是通 ... -
NET 应用架构指导 V2 学习笔记(十七) 组件设计指导
2010-06-05 00:48 673组件提供了一种将 ... -
NET 应用架构指导 V2 学习笔记(十八) 表现层组件设计指导
2010-06-05 21:09 530本章讲述的是你在设计用户界面组件和表现层逻辑组件的时候应该 ... -
NET 应用架构指导 V2 学习笔记(十九) 表现层组件设计指导
2010-06-06 06:15 5965 决定数据绑定的 ... -
NET 应用架构指导 V2 学习笔记(二十) 业务组件设计指导
2010-06-07 06:58 617前言 业务组件 ... -
微软企业库5.0学习笔记(四十二)异常处理模块
2010-06-14 00:04 840企业库的异常处理 ... -
关于程序员在30岁、35岁之后怎么办的新思考
2010-06-14 10:40 626首先给大家问个好 ... -
NET 应用架构指导 V2 学习笔记(二十四) 跨层关注问题
2010-06-17 20:00 596概况 大部分的 ... -
微软企业库5.0学习笔记(四十三)数据验证模块
2010-06-19 08:07 999概况 任何接受用户或者是其他系统输入的应用,一定要确保 ... -
关于项目进度慢的思考----如何提高整体开发效率
2010-06-21 23:42 807我们都是软件行业 ... -
微软企业库5.0学习笔记(四十四)实战数据验证模块
2010-06-23 19:22 8431 在业务对象上添加验证 添加对程序集【Microso ... -
微软企业库5.0学习笔记(四十五)实战数据验证模块----高级篇
2010-06-24 19:41 9721、添加自定义的提示信息 验证失败的提示信息可以自定义 ... -
面向对象类设计的五大原则(一)单一职责原则Single Responsibility Principle
2010-06-29 15:45 779引言 面向对象类设计,或者说是面向对象设计,有五大原则 ... -
《深入浅出设计模式-中文版》读书笔记 开篇乱弹(一)
2010-07-01 06:42 653oreilly的《Head.First ... -
《深入浅出设计模式-中文版》读书笔记-继承与组合(三)
2010-07-03 16:53 607经过上一次的改造 ... -
《深入浅出设计模式-中文版》读书笔记-观察者模式(四)
2010-07-06 06:34 636今天要接触的是观 ... -
利用attribute实现简单的ORM
2010-07-09 15:27 684我不知道NH的ORM具 ... -
系统内部模块(子系统)之间的耦合以及模块(子系统)划分
2010-07-14 13:02 807题外话 最近已经在努力学习了,学习基本功,学习设计模式 ... -
《深入浅出设计模式-中文版》读书笔记-工厂模式(五)
2010-07-16 12:46 700今天给大家带来的是:工厂模式。 我们在代码中创建一个对 ... -
Head.First.Object-Oriented.Design.and.Analysis《深入浅出面向对象的分析与设计》读书笔记(一)
2010-07-18 21:47 673题外话 又是一本Head.First系列的书,这个系列 ...
相关推荐
在这篇文章中,我们讨论了 DDD 分层架构的三种模式:四层架构、五层架构和六层架构。每种模式都有其优点和缺点,但是它们都可以帮助我们设计高质量的软件模型。在实践中,我们可以根据实际情况选择合适的模式,并且...
JavaWeb 三层架构和五层架构介绍 JavaWeb 开发中,程序的划分是基于“高内聚低...三层架构和五层架构是JavaWeb开发中常用的架构模式,每种架构都有其特点和优缺点,选择合适的架构模式可以提高开发效率和系统性能。
分层架构设计模式有助于将应用程序组织成不同抽象层次的子任务组,便于每个层的独立开发和维护。 ## 二、详细解释及实际示例 1. **实际示例**: - 想象一下建造一座现代高层建筑,这类似于在软件开发中使用分层...
分层架构是一种常见的软件设计模式,它将应用程序分解为若干个相互独立、职责明确的层次。通常,我们会看到以下几层: 1. **表示层(Presentation Layer)**:与用户交互,负责接收输入和展示结果。 2. **业务逻辑...
其分层架构模型是DDD的核心设计模式,它将系统分为用户接口层、应用层、领域层和基础层,旨在清晰界定各层职责,促进模块化和可维护性。本文将深入探讨这四个层次的职责与功能,并结合微服务代码模型,展示如何在...
两者在实践中常常结合使用,例如,SOA服务可以部署在分层架构的不同层中,以提供更高级别的抽象和解耦。 在设计可扩展架构时,必须注意以下几点: 1. **稳定的核心接口**:接口的稳定性是保持扩展性的关键,如...
### 互联网分层架构之-DAO与服务化 #### 一、引言 随着互联网业务的不断扩张与深化,单一的系统已经无法满足日益增长的需求。为了更好地支持复杂的业务场景,提升系统的稳定性和扩展性,分层架构逐渐成为了业界...
首先,我们来看分层架构,这是一种常见的设计模式,通常包括N层,N至少为2层。例如,C/S(客户端/服务器)架构和B/S(浏览器/服务器)架构。C/S架构将用户界面和业务逻辑分离,而B/S架构则进一步简化了用户交互,...
例如:你使用数据库表模型模式的业务逻辑层,服务层会通过DataSet来进行交互。很显然,服务层合理的安排业务组件,同时也合理的安排应用的服务、工作流和业务逻辑的其他组件。服务层的职责服务层是一个额外的层,是...
.NET框架提供了强大的支持来实现分层架构,例如,ASP.NET MVC提供了一个灵活的Web应用程序开发框架,而Windows Communication Foundation(WCF)则可以用于服务层间的通信。此外,.NET Core的跨平台特性使得基于.NET...
在研究分层架构时,常通过概念性的定义或OSI七层应用(架构)来说明或解释分层架构:架构模式Layers有助于将应用程序划分为多组子任务,其中每组子任务都位于特定抽象层。图片取自《POSA,Vol.I,p22》作为一个在项目...
三层架构是分层架构的一种常见实现,包括表现层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。表现层负责用户界面,业务逻辑层处理业务规则和流程,数据访问层则...
在IT行业中,分层架构是一种常见的软件开发模式,它旨在提高代码的可读性、可维护性和可扩展性。C#作为.NET框架的主要编程语言,非常适合用于构建分层架构的应用程序。本文将深入探讨C#实现分层架构的源程序,并结合...
在软件开发中,分层架构是一种常见的设计模式,它将复杂的应用程序拆分成多个逻辑层,每个层专注于特定的功能,从而提高代码的可读性、可维护性和可扩展性。本教程通过一个完整的案例,旨在帮助开发者更直观地理解和...
1. **分层架构**:这是一种常见的架构模式,将系统划分为多个独立的层次,如表现层、业务逻辑层、数据访问层等。每个层都有明确的责任,层与层之间通过接口通信,降低了复杂性并提高了模块化。 2. **微服务架构**:...
.NET 分层架构是一种常见的软件开发模式,它将复杂的系统分解为多个独立的层次,每个层次都有特定的职责,以此提高代码的可维护性、可扩展性和可重用性。以下是对.NET分层架构的详细解释: 1. **基本原则**: - **...
在软件开发中,分层架构是一种常见的设计模式,它将应用程序划分为多个独立的层,每个层负责不同的功能,如表现层、业务逻辑层、数据访问层等。这样的设计有利于代码的可读性、可维护性和模块化。单元测试则是确保每...