架构设计中服务层的简单理解

如果你对项目管理、系统架构有兴趣,请加微信订阅号“softjg”,加入这个PM、架构师的大家庭


在ddd设计中我们经常会提到服务层,服务层是什么?职责是什么?有什么好处?。

先看简单的层次图(注:这里并没有考虑其他多余的领域逻辑数据层存储,或者UOW这些细节)


我的理解是服务层是处于我的应用程序业务层和表现层之间的应用程序边界,边界可能是很薄的一层类设计或者是分布式服务网络跃点。它是一个与技术无关的名词。由表现层直接调用,契约,执行命令(修改状态(CUD))或者是查询返回dto(数据迁移对象)(cms,命令-查询分离)。他对业务逻辑层接口很清楚,组织业务逻辑
微服务形成宏服务,适配表现层。

这里谈到宏服务和微服务,宏服务有一些列粗粒度的服务组成。用户的一次操作usecase,比如电子商务下单,CreateOrder就是一个宏服务,而不是下单中的细粒度的商品库存检查,订单合法性等。而与之对应的微服务(有时也叫应用程序服务),则表现为问题领域逻辑细节,就如上面的库存检查和合法性检查这些细粒度的服务。宏服务是由一个或者多个微服务组成,有时我们的usecase逻辑很简单服务层仅由单一微服务组成,变现为很简单的几句微服务调用。

服务层的职责:

1:在面软件开发不管是结构化编程(sp)还是面向对象编程(oop)我们一直都强调高内聚低耦合,分离关注点(soc)。服务层处于应用程序和业务层之间,应用边界,使得两次直接解耦,利用第三个对象破坏两对象直接的依赖,并转化适配领域对象(do)和试图对象(vo)的差异。

2:服务层隐藏了业务逻辑层的细节,其内部需要组织业务微服务,提供更宏观,面向表现层的服务逻辑,利用契约接口暴露,包装。系统所有的交互都是从表现层进入。

目前流行SOA架构,提供了一种分布式服务架构,以服务为关注点,提高服务和业务逻辑的重用,但是这里说的服务并不是特定的技术wcf或者webservice,服务同时候可能是一次规定契约的一些列粗粒度组织的类组成。但是利用SOA或者MTS建立服务会让我们的服务得到跟多的附加优势,例如安全,事物,日志,扩展性的提升。

服务层带来的优势:如上所述服务层为表现层提供的同一的接口契约和入口。让我们的业务层可以关注与实现问题领域逻辑,问题领域实际需求。组织微服务避免太多的细粒度服务的调用充斥在我们的项目表现层和问题领域中,过多的交互。如果采用soa等服务领域可以让我们的应用程序轻易的跨过应用程序边界和网络跃点。但是需要付出一点的性能代价。

数据迁移对象(dto)就是携带数据穿过应用程序边界的对象,减少数据的交互次数,常常我们将其作为值对象,只是一组简单的get,set属性组成,不存在行为操作,仅仅为数据的载体。在领域设计中dto是一个很重要的模式,不是我们所有的领域对象都能轻松的到达表现层,仅仅表现层和领域层部署在同一物理位置。如果需要穿过网络跃点或者进程边界,因为领域对象使我们的业务的核心存在很多的自然世界的关系,依赖,甚至可能存在循环依赖比如电商用户和订单,用户用户一组订单的集合,而每个订单都指向一个特定的用户,我们就必须破换掉这种循环依赖,才可能使其可序列化,穿过跃点。其次我们的领域对象往往都是一堆领域富对象,存在大量数据,很多时候我们的场景并不需要全部的数据信息。有了dto的存在就能很好的解决这些问题,是的我们的项目变得simple(keep
it simple,Stupid。 KISS原则)。

但是与此同时dto存在会为我们带来一些额外的复杂度,我们必须有一层do到dto的映射适配层。

理论上完美的设计我们需要为每一个应用定义一个dto,但是在一个复杂的系统中我们可能存在很多的领域对象,加入500个do,每个do一般都会存在多个dto,这将一个增加一个庞大的集合和mapping逻辑,对于维护也存在不小的挑战。在软件领域存在一句话就是bug的数量随着代码量增加,代码量增加需要测试点也随着增加。除非我们必须跨越应用程序网络跃点边界,我觉得否则我们也可以存在一些简单do的直接使用。根据世界项目,情形由我们的架构师决定。

如果你对项目管理、系统架构有兴趣,请加微信订阅号“softjg”,加入这个PM、架构师的大家庭

架构设计中服务层的简单理解,布布扣,bubuko.com

时间: 2024-10-12 12:39:39

架构设计中服务层的简单理解的相关文章

万剑归宗—架构设计中的抽象思维与具象思维

新项目上线,用户量不断增加,工作中继续不断发现问题,解决问题.花一点时间来总结一下自己对架构设计的理解. 小小的打个广告.这篇文章是发布在neil的微信公众号上.neil的文章都会第一时间发布在微信公众号上.欢迎小伙伴们关注. 微信公众号:互联网与作曲家 武侠小说中的"万剑归宗"----极致的抽象思维 一点题外话.自己从小就是武侠迷,金庸古龙的经典作品都看过很多遍.最喜欢的女主,是<倚天屠龙记>中的赵敏:敢爱敢恨,邵敏郡主.其扮演者黎姿,是我心目中两位女神之一,性格与赵敏非

架构设计中的6种常见安全误区

[架构源码地址] 自然世界中,先天有缺陷的生物总是容易被细菌病毒入侵,而健壮的生物更能抵抗细菌病毒的攻击,计算机系统也是一样,若有先天的架构设计安全缺陷,那么在面临网络攻击的时候,就更容易被入侵或者破坏,甚至因为设计架构的原因,有些漏洞完全没有办法修复!本文将讲述架构设计中需要避免出现的安全误区,以帮助我们研发人员设计出更安全健壮的软件架构.本文的举例既有硬件架构,也有软件架构,还有基础架构等等不同的架构,但其中原理适用于所有的架构设计.下文将从兼容性设计误区,降低成本设计误区,数据和代码不分离

挖财首席架构师王福强:架构设计中的6大关键点

编者按:要开发出用户满意的软件并不是件容易的事,软件架构师必须全面把握各种各样的需求.权衡需求之间有可能的矛盾之处,分门别类地将不同需求一一满足.在UPYUN Open Talk 第二期"移动时代互联网金融架构趋势"的技术分享中,挖财首席架构师王福强带来了<挖财的互联网金融技术探索>,王福强重点分享了当前挖财架构设计中的6大关键点: 1. 系统层级分离 从大的体系来讲,挖财主要在做四个纬度的事情,第一个是会员中心,挖财有一套自己的会员体系,第二个是现金流,第三个是风控中心,

【原】iOS 设计中 图片后期简单处理的完美组合

iOS 设计中 图片后期简单处理的完美组合 四张图+.DS_Store (3张alpha通道“是”,1张没有alpha通道) 5,909,971 字节(磁盘上的 5.9 MB),共 5 项 第一步:转非alpha通道,工具 Alpha-Channel-Remover https://github.com/bpolat/Alpha-Channel-Remover  这个地址就哦了 http://alphachannelremover.blogspot.com 这个墙内墙外都试过没打开 转完后:变小

看懂架构设计中的服务隔离

前言 我们在做系统架构设计的时候,经常离不开的一个话题就是进行服务的隔离设计. 那什么是「服务隔离」呢? 顾名思义,它是指将系统按照一定的原则划分为若干个服务模块,各个模块之间相对独立,无强依赖.当有故障发生时,能将问题和影响隔离在某个模块内部,而不扩散风险,不波及其它模块,不影响整体的系统服务. 其实隔离设计并非软件行业独创,它是借鉴于造船行业.行业有一个专业术语叫做「舱壁隔离」.利用舱壁将不同的船舱隔离起来,如果某一个船舱进了水,那么就可以立即封闭舱门,形成舱壁隔离,只损失那一个船舱,其他船

对Django框架中Cookie的简单理解

概念的理解:首先Cookie和Session一样,是django中用于视图保持状态的方案之一.为什么要进行视图保留呢,这是因为浏览器在向服务器发出请求时,服务器不会像人一样,有记忆,服务器像鱼一样,在你一次请求结束后她会很快忘掉你的,对她来说你的每一次请求都是新鲜的,这要是爱情就好了哈,可以爱情保鲜!闲话不多说,这种状态就是所谓的 "浏览器请求服务器是无状态",根本原因就复杂一些了,需要简单了解些网络编程中套接字Socket的通信方式,简单来说就是,浏览器和服务器进行通信需要使用Soc

web系统架构设计中需要知道的点(前端篇)

上周没写东西,这周写点互联网系统开发中需要了解的技术点,每个点都可以发散出去,连接更多的知识点,打算做个逐步细化的记录. 一个应用的整个生命周期中(生,老,病,死)都需要有一个整体规划. 前期 评估需求,根据需求提炼出其中隐含的非功能性要求,做为容量评估的参考.一般就是大致估算一下,技术发展到现在,如果是聊天或游戏应用,随便一个服务器单机能能维持100W-160W左右的tcp长连接并进行通讯.所以普通的创业起步阶段的应用一般不必太担心设计问题,可以等业务量慢慢上来慢慢调整系统架构. 互联网上许多

PHP中的traits简单理解

Traits可以理解为一组能被不同的类都能调用到的方法集合,但Traits不是类!不能被实例化.先来例子看下语法: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php trait myTrait{   function traitMethod1(){}   function traitMethod2(){} } //然后是调用这个traits,语法为: class myClass{   use myTrait; } //这样就可以通过use myT

架构设计中常见的语义耦合类型的总结

语义耦合是隐性的,不易察觉的耦合类型 ,是导致代码重构.调试.修改复杂度急剧增加的主要原因. 1,操作顺序耦合 使用一个对象,需要先调用Init(),之后才能调用DoAnything().这种顺序耦合,即使在文档中remark也是极为不优雅的做法. 2,全局参数传递 模块A修改了某个全局参数g_val,模块B读取该值.模块B必须知道模块A已经对该参数赋值. 3,业务封装不够紧密 模块A向模块B传一个参数,模块B根据该参数选择对应的操作.模块A必须知道与业务相关的所有的操作类型.对于模块A,仅传递