文档章节

oobbs开发手记

猪刚烈
 猪刚烈
发布于 2014/10/12 11:39
字数 3199
阅读 5
收藏 0
点赞 0
评论 0

1.关于Action中populate数据的问题:

Action的一个职责就是:创建领域对象的实例,并将从页面传来的数据populate到实例中。这个过程有一个问题:即,如果建新的对象需要的是另一个领域对象,这时候,页面传递过来的只是这个对象的id,那么这个propoerty将如何set呢?

比如在新建一个Thread的action中,要为新的thread设置forum,而页面传来的只是forum的id,那么,是在action中load这个forum,并set给thread还是在service中呢?

解决方案:使用DTO会解决这一系列的问题!同时使领域层具有更好的自封装性。也不再需要opensessioninview! DTO只是数据的载体,这与展现层的基本需求(只是读写数据而不做业务处理)的特点是相适应的。当DTO到达service后,再拆解数据,做一系列的业务操作是很好的。

引入DTO的好处在于:可以把领域对象封装在领域模型内部。本质上讲,视图层需要的仅仅是从领域层得来的数据,当然它自己也有逻辑,不过这些都是展示逻辑,与业务无关,所以说,我应该只传送数据就好。另外,如果使用领域对象做为数据载体在领域层和展现层之间进行传递,会有一些问题:如果领域对象的创建较为复杂,那么在Action里创建领域对象会变得很不方便,因为毕竟不是在领域模型里,简单例子是,如果我们需要的对象A是通过对象B的工厂方法创建的,那么这个在Action里写出来就会很怪异。另外,DTO并不是与领域对象一一对应的,它是粗粒度的,面向视图层的。这也是引入DTO的一个目的。

 

2.在应用层关于service和data的设置意图。

显然,在应用层,不存在面向对象那种数据和行为的封装,因此, service承担了“行为”,data承载的“数据”。在应用层内部,我们会创建领域对象,并把data的值populate到领域对象里,然后再通过领域对象的业务方法执行业务操作。这一模式是非常合理而有效的。

 

3.关于DTOAssembler装配DTO的问题:
一般来说,从领域对象抽取数据装配DTO没有问题,因为领域对象包含全部
可能的数据,装配DTO时只是一个选取的过程。但是反过来可能会存在问题
。比如:保存一个Thread需要设置它所属的Forum。从页面传递过来的Threa
dDTO中除了Thread的基本信息外,还提供了一个ForumId.对于Assembler来说,如果想要组装一个Thread领域对象,需要通过ForumId加载出一个Forum实例来(注:在hibernate里,要通过session.load方法加载一个代理,这样才不会有效率问题),但这需要repository的协助。

 

4.关于是否需要引入ServiceFacade的思考

目前工程已经引入了DTO。按照标准的j2ee模式,DTO总是配合ServiceFacade一起使用使用的(4月27日做出的修正:DTO并不只是配合ServiceFacade使用的,基本上我们需要引入DTO,那么ApplicationService也必将使用DTO。并不是说DTO只能出现在Facade的接口里。这一点在PoEAA和CoreJ2EEPatterns两本中的代码中都有所体现)。对于是否引入这一组件我的思考是:

传统意义上来看,DTO是面向Client(或者说是展现层)的数据结构,ServiceFacade是面向Client的UserAction,或者说是面向UseCase的。DTO和ServiceFacade联合起来构成一个Client(或者说是展现层)和业务层(领域模型)之间的适配器。典型的情况是:如果一个UserAction需要多个Service共同工作才能写成时,ServiceFacade的作用就突显出来了。它本身并没有业务逻辑,但是它会将Action的请求委派给合适的Service进行处理。

这个理念看上去很合理但是实际运用起来并不容易。首先这里有一个Facade和Service的粒度问题。如果说一个Facade的方法对应一种Action,那什么样的UserAction会需要委派给多个Service呢?具体又应该是几个呢?Service的粒度标准又是什么呢?有人说Service是面向业务的(在TransactionScript类型的工程里尤其如此),我看确切的说它的内部是业务处理,它的那些方法究竟是面向什么(或者说是以什么为依据)而梳理成一个方法的呢?我想这个标准并不好找,我们只有一个最上面的一致标准:用户请求,也就是Facade的粒度标准。问题就在这里,对于Facade与Service之间的粒度划分并没有一个很清晰明了的标准。严格来说,Facade与Service都是应用层产物,应用层的职责就是将外部应用请求(比如一个UserAction)委派给领域层进行处理。从这个角度上来看,应用层接口的粒度只有一层标准,我看Facade与Service之间真得找不出很好的粒度切分标准。绝大多数情况下一个Facade方法都是委派给一个Service方法也证明了这一点。于是我想不如将两者合二为一来得简洁利落。至于真得出现有两个以上的Action需要执行一组同样的业务操作时,我们就把这个组操作重构成一个独立的Service方法。

 

4月27日:通过对ServiceFacade和AppliationService的继续思考,我有一些新的认识:

之前提到,当一个用户请求需要多个Service来共同处理时,Facade的作用就会凸显出来,这确实是引入Facade的决定性原因。我想这种情况是确实存在的。当这种情况出现时,在Client的Controller方法里就会出现这样一种现象:这个方法调用2个以上的Service来委派用户的请求。这就是一个信号,说明应该把这些Service封装到一个统一的facade里面了。或者反向推论:如果在某种规范的约束下,要求我们只能以一个Service的一个接口来处理这个请求时,你可能会想到,是否需要让这个Service依赖那些用到的Service呢?显然,Service之间是不能用依赖的。这也从反向说明,我们确实需要一个更高层的封装来把这些用到Service放到一起了。

 

基本上ApplicationService是以实体特别是聚合根为单位组织的。我相信会有一些很heigh level的请求需要跨越多个实体或者聚合来实现的,这个时候我们就需要Facade的了。

这就是上面我反复思考的Service和Facade之间的粒度标准问题。简单总结一下就是:ApplicationService是以实体特别是聚合根为单位组织的,它的接口是直接面向用例(用户请求者是UserAction)的.而Facade的粒度没有明确的上限(或许你可以为一个模块设计一个Facade),但其下限是很明确的,即针对那些跨越两个以上实体或聚合的用例而服务。它的接口同样是面向用例的。

 

 

不过有个问题需要注意:即UserAction或许可以成为一个力度标准,但是一个UserAction可是有大有小,有时候差距是很大的。这个要引起注意。

PS:这些Service接口传入传出的数据还是DTO。

2010-4-26:今天,通过查阅《PoEAA》,我对这个问题有了一些更为深入的认识。

You don't see Remote Facade used with a Transaction Script (110) as a rule, since a Transaction Script (110) is inherently coarser grained.

第一,必须明确:RemoteFacade只存在于基于DomainModel的系统架构中。因为领域对象是细粒度的,它们需要Facade. 而TransactionScript的系统是不需要的,因为TransactionScript天生就是面向粗粒度的!

 

 

 

 

对于Service层的再认识:

我认为Service就是应用程序的API,同时也是事务和安全管理最佳层面。

在基于TransactionScript里系统里,Service非常厚重,包含了绝大多数的页务逻辑。

而在基于DomainModel的系统,Service只是一层很薄的接口,或者说是DomainModel的Facade,它通过委派领域对象完成业务处理。

 

 

 

 

Applications implement use cases that coordinate multiple Business Objects (374) and services. However, you shouldn't implement use case-coordinating behavior specifically within Business Objects (374), because it increases coupling and reduces cohesion between these Business Objects (374). Likewise, you don't want to add this business logic to a service facade, because the business logic potentially gets duplicated among different facades, reducing the reusability and maintainability of common code.

 

实现一个用例(或者简单地说一个UserAction),在DomainModel有两部分的逻辑,一部分是领域对象自身的行为逻辑(也就是方法),另一部分是协调各领域对象的逻辑,这也是非常重要的一部分。你不能把这部分逻辑写到领域对象里,这样领域对象就会耦合在一起。那这部分逻辑的在哪里呢?应用服务里!

 

ApplicationService是包含业务逻辑的,它的业务逻辑就是领域对象之间如何协作的逻辑!本身上讲它是领域对象的Facade!

 

 

 

 

 

In non-EJB applications, where you need to reduce coupling between the presentation-tier components and business-tier components such as Business Objects (374) and other services, Application Services provide that intermediary function between the two tiers. An Application Service exposes a finer-grained interface than a service facade and a coarser-grained interface than the underlying Business Objects (374) and other services.

 

应用服务的接口比ServiceFacade细,比领域对象粗,是面向用例的!

 

 

而ServiceFacade则是另外一种东西了,它是ApplicationService的Facade。那ServiceFacade到底是面向什么的呢?我们又回到了开头!

 

 

 请参考一下Core J2EE Patterns一书ApplicationService一节的SampleCode吧,我想一个Facade对应一个模块会比较合适吧,但是又为什么非要设计出这个Facade呢?

但是至少有一点我们现在非常明确了:

那就是ApplicationService传入传出的数据是DTO!这一点在PoEAA和Core J2EE Patterns一书的代码中都有验证,而ApplicationService的职责也决定它就应该使用DTO!(当然是在需要DTO的系统里)

关于DTO与所依赖的领域对象:

当们需要persist/update一个领域对象时,页面数据以DTO形式传入service,当这个领域对象依赖其他领域对象时,页面上传来的多是这个对象的ID。那么我们如何通过ID加载出这些对象并设置它们之间的关系呢?

比如:当我们新建一个thread时,它会依赖到的实体有一个forum,和一个user.那么页面传到service的只是一个forumid和一个userid.我们有两个问题:

1.这些ID是放到DTO里还是单独作为参数传入。

2.在哪里load这些实体并将它们与thread关联起来。

先思考第2个问题:我目前有很明确的倾向,即load这些实体并将它们与thread关联起来的工作不应放到assembler里!因为将实体关联起来本身就是业务逻辑一部分,放到assembler里会使业务逻辑“外流”。另一个原因时,很多时候,关系实体可能并不只是一个简单的set就能搞定的,很多时候可能会有比较复杂的业务逻辑。所以我倾向在service里load实体并将实体关联起来,这样也可以保证assembler不会依赖任何repository!

对于第1个问题,并不是一个很重要的问题。放到dto里应该会使service的接口简洁些吧。

为什么去掉了Forum的createThread()和Thread的createPost()方法?

思前想后,我还把这些简单工厂方法给去掉了。现在看来,我觉得这其中的道理可以做为一种经验记录一下:

我认为工厂方法最好能生产完备的产品。如果生产出的是一个半成品,我们还要在其他地方为这个半成品再赋值和加工的话,这个工厂方法可能就不那么必须了吧?

应用服务k考虑一下:像Swiz那样dispatch领域事件,然后委派给repository进行数据访问的方案!

A

a

a

a

本文转载自:http://blog.csdn.net/bluishglc/article/details/5373957

共有 人打赏支持
猪刚烈
粉丝 22
博文 708
码字总数 110
作品 1
海淀
程序员
《Python自动化运维开发实战》课程配套手记内容列表

自动化实战课程的手记内容手记列表 各位同学,《Python自动化运维开发实战》实战课中的配套手记内容列表如下,供大家参考学习,已经出的手记将参考大家的实际情况进行补充,其他的配套课程整...

幕客技术 ⋅ 01/12 ⋅ 0

phoenix安装手记

phoenix安装手记 知行天下2017-12-251 阅读 大数据hbasephoenix 1.下载代码 wget https://mirrors.tuna.tsinghua.edu.cn/apache … 继续阅读“phoenix安装手记” 点赞 大数据hbasephoenix 作...

知行天下 ⋅ 2017/12/25 ⋅ 0

《Java并发编程与高并发解决方案》课程相关手记汇总 - 持续更新

给《Java并发编程与高并发解决方案》课程准备的手记列表,为了方便大家阅读,单独整理成一篇汇总,学习时结合手记效果会更好哦~ 更多手记可点击我的个人首页:http://www.imooc.com/t/598062...

_Jimin_ ⋅ 05/09 ⋅ 0

有奖征文004期|从小白到大牛,进阶路上有话说?

从小白到大牛,是用无数代码堆砌出的血泪史,就问你,想不想一吐为快? 想不想让大家了解你和代码那些风花雪月的故事? 或独自一人用青春和热血挥洒代码的经历? 咳咳,其实就是想让你写写程...

慕课网官方_运营中心 ⋅ 05/29 ⋅ 0

Multi-Stage Build多阶段Build Docker镜像

我们在上一篇手记 中给大家介绍了如何完全使用Docker搭建Angular开发和测试环境,今天我们接着这个话题给大家看看如果通过Docker部署Angular项目。 我们先看看假如没有Docker,我们一般怎么去...

麦兜搞IT ⋅ 05/29 ⋅ 0

书荐——《IT项目经理成长手记》

这本书的独特之处在于,用讲故事的方式,描述了一个研发工程师的项目经理之路。说实话文笔其实一般,搞技术的能做到信达雅的确实是少之又少,但是确是有内容的。 我买这本书看冲着几点: 讲了...

悟空太多啦 ⋅ 01/25 ⋅ 0

如何第三方编辑淘宝产品《手机详情》

本人在做个小东西,想熟悉下淘宝api的开发流程。其他的照着api文档来都还算顺利。 但是遇到一个问题: 如何通过api实现第三方编辑手记详情页面? 在api中有关于编辑pc版的详情信息(taobao....

inkpark ⋅ 2015/06/30 ⋅ 0

10个iPhone开发网站、论坛、博客

整理了一下手中的iPhone开发网站、论坛和博客,精选了这10个常去的网站。其中有2篇教学文章,由于非常经典,于是单列出来,与其网站并列。 建议新入行的朋友在看教学文章的同时多上论坛,与大...

23Code.com ⋅ 2013/01/19 ⋅ 0

11个iphone开发的网站

整理了一下手中的iPhone开发网站、论坛和博客,精选了这10个常去的网站。其中有2篇教学文章,由于非常经典,于是单列出来,与其网站并列。 建议新入行的朋友在看教学文章的同时多上论坛,与大...

ilscott ⋅ 2013/06/13 ⋅ 0

Windows Mobile 开发系列文章收藏 - SQLite

Sqlite介绍 SQLite数据库 牛腩学习sqlite - 简记 概述介绍 SQLite入门与分析(一)---简介 SQLite入门与分析(二)---设计与概念 SQLite数据库扫盲 SQLite内存使用情况分析 SQLite常用资源 SQLi...

长征2号 ⋅ 2017/12/20 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JEPLUS主从功能配置之主从布局的设置——JEPLUS软件快速开发平台

JEPLUS主从功能配置之主从布局的设置 主从功能配置成功之后就需要根据业务需求来调整主从功能的数据显示方式,不同的主从数据的显示可以达到不同的主从数据显示效果,今天这篇笔记就讲解一下...

JEPLUS ⋅ 2分钟前 ⋅ 0

如何利用极光推送的新功能玩转世界杯营销

四年一次的世界杯已经于6月14日开赛!对于app的运营人员而言,这场远在俄罗斯的绿茵征战绝不仅仅牵动着球迷们的心,更拨动着众多互联网企业运营人员的神经。在这场营销大战中,push显然是app...

极光推送 ⋅ 6分钟前 ⋅ 0

Spring Cloud构建微服务架构-Hystrix依赖隔离

依赖隔离 “舱壁模式”对于熟悉Docker的读者一定不陌生,Docker通过“舱壁模式”实现进程的隔离,使得容器与容器之间不会互相影响。而Hystrix则使用该模式实现线程池的隔离,它会为每一个Hys...

itcloud ⋅ 8分钟前 ⋅ 0

SpringCloud 微服务 (八) 统一配置中心 Config Server&Client

壹 Spring Cloud Config 统一配置中心,方便维护配置文件,对一些公司对数据库密码等敏感的信息,对普通开发人员不公开,放在运维人员手上,对配置作一个隔离作用,另外项目线上的配置改动都要重新...

___大侠 ⋅ 11分钟前 ⋅ 0

echarts轮播地图并结合鼠标浮动点击

直接上代码 timeId=setInterval(function () { if(count<11){ myChart.dispatchAction({ type: 'downplay', ......

莫西摩西 ⋅ 14分钟前 ⋅ 0

基于 HTML5 的工业互联网 3D 可视化应用

工业企业中生产线处于高速运转,由工业设备所产生、采集和处理的数据量远大于企业中计算机和人工产生的数据,生产线的高速运转则对数据的实时性要求也更高。破解这些大数据就是企业在新一轮制...

xhload3d ⋅ 17分钟前 ⋅ 0

Nging启动与停止bat

start_nginx.bat @echo off  f:  cd F:\server\nginx-1.13.6  echo "nginx is starting on port 80"  start "" "nginx.exe"  exit   stop_nginx.bat @echo off::windows ......

Jay丶 ⋅ 18分钟前 ⋅ 0

SuRF: 一个优化的 Fast Succinct Tries

作者:唐刘 在前一篇文章中,我简单介绍了 Succinct Data Structure,这里我们继续介绍 SuRF。 Fast Succinct Tries SuRF 的核心数据结构就是 Fast Succinct Tries(FST),一种空间节省,支...

TiDB ⋅ 23分钟前 ⋅ 0

Kubernetes(六) - Secret和私有仓库认证

对一个公司来说安全也是最为重要的因为可能一旦出现安全问题可能这个公司就完了,所以对密码管理是一个长久不变的话题,Kubernetes对密码管理提供了Secret组件进行管理,最终映射成环境变量,文件...

喵了_个咪 ⋅ 24分钟前 ⋅ 0

DevOps的三大原则

DevOps的出现有其必然性。在软件开发生命周期中,遇到了两次瓶颈。第一次瓶颈是在需求阶段和开发阶段之间,针对不断变化的需求,对软件开发者提出了高要求,后来出现了敏捷方法论,强调适应需...

inidcard ⋅ 25分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部