`
javatar
  • 浏览: 1704543 次
  • 性别: Icon_minigender_1
  • 来自: 杭州699号
社区版块
存档分类
最新评论

服务器端分包结构回顾

阅读更多
现在很多的Java应用都采用Eric在《DDD》中提出的域分层结构,
所以大部分项目看起来像下面这个样子分包:
action
service
dao
domain
exception
util

最近做的这个项目也采用了类似的结构,
其中service和dao的关系是一个老生常谈的问题,
dao只对数据访问进行隔离,比如:Hibernate过时了,我们需要按一套全新的持久化方案,只需把Dao的实现类替换掉就行了。
service包括所有的业务逻辑,使用dao存取数据,并向Action功能提供服务。
然而,大部分企业应用中,业务逻辑就是对数据库的操作,
所以就出现了大量的service变成了dao的代理,
为此,有人提出,如果只是简单数据操作,action可以直接调用dao,因为同样保持着单向依赖。
但是,允许这样做后,dao函数的粒度较小,action变相的成了业务逻辑处理中心。
还有一个问题是,复杂的SQL语句,是业务还是数据操作?该放在dao,还是service?
其实放在dao或service, 都能说得通,
但我觉得应该放在service, SQL语句本身是业务逻辑,只是执行它的应该是数据操作接口,
如果dao只是作为数据操作接口,在现在数据自动映射处理框架的面前,是否有必要存在?
我比较赞同统一dao接口为一个特殊的服务, 如:PersistentService
持久化服务接口:
public interface PersistentService extends Service {

	void save(Entity entity);

	void batchSave(Collection<Entity> entities);

	void update(Entity entity);

	void batchUpdate(Collection<Entity> entities);

	void saveOrUpdate(Entity entity);

	void batchSaveOrUpdate(Collection<Entity> entities);

	void remove(Entity entity);

	void batchRemove(Collection<Entity> entities);

	void remove(Class<?> entityClass, Long id);

	void batchRemove(Class<?> entityClass, Collection<Long> entityIds);

	Entity get(Entity entity);

	Entity get(Class<?> entityClass, Long id);

	Entity get(Class<?> entityClass, String property, Serializable value);

	Collection<Entity> find(Entity entity);

	Collection<Entity> find(Class<?> entityClass, String property, Serializable value);

	Collection<Entity> find(String query);

	Page<Entity> findPage(Entity entity);

	Page<Entity> findPage(Class<?> entityClass, String property, Serializable value);

	Page<Entity> findPage(String query);

	......

}


然后,实现不同ORM框架的映射,如:
public class HibernatePersistentService implements PersistentService {

	......

}


或者SQL映射框架,如:
public class IbatisPersistentService implements PersistentService {

	......

}


或者非数据库持久化,如:
public class XmlPersistentService implements PersistentService {

	......

}



然后,在其它业务类服务基类中缺省由框架自动注入持久化服务:
public abstract class AbstractService implements Service {

	/**
	 * 日志输出接口
	 */
	protected final Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 持久化服务
	 */
	protected PersistentService persistentService;

	// IoC注入接口
	public void setPersistentService(PersistentService persistentService) {
		this.persistentService = persistentService;
	}

}


业务类服务中使用如:
public class UserServiceImpl extends AbstractService implements UserService {

	public User login(String username, String password) {
		// 直接使用持久化服务接口
		User user = persistentService.get(User.class, "username" username);
		....
	}

}


这样统一后,
service表示无状态的服务模型,服务可以再依赖服务,并且像邮件发送等也应该成为服务,而不是util工具。
action表示有状态的功能模型,代表一个用户可具体操作的功能。
模块间服务模型共享,并定义好依赖关系。
模块间功能模型使用名称空间相互区隔,互不干扰。

如:
雇员管理服务:包括雇员增删改查接口,数据一致性检查等。
雇员管理功能:包括新增雇员的界面,界面控制,数据传输等。

提成管理功能,也可依赖雇员管理服务,通过服务获取提成雇员的信息。
但提成管理功能却不会依赖雇员管理功能,因为它不关心雇员信息是怎么维护的。

如果雇员信息是从HR系统同步过来的,那样就只需要雇员管理服务,而不需要雇员管理功能,或者同步过程就是雇员管理功能。

所以服务模型和功能模型应该分别打成jar包,便于部署。
分享到:
评论
9 楼 javatar 2008-11-06  
只是举例,可以改为:
Entity get(Class<?> entityClass, Serializable id);
8 楼 laiseeme 2008-11-05  
Entity get(Class<?> entityClass, Long id);  

为啥不是
Entity get(Class<?> entityClass, Object id);  
7 楼 jander 2008-11-05  
这个好像只能O/R mapping这样用。对象数据库没用过,应该也可以。
但是spring jdbc template, 或者 jdbc就不行。
6 楼 z494627 2008-11-05  
Service中操作的是对象,而DAO操作的是数据库.
5 楼 javatar 2008-11-01  
其实怎么样设计都可以,主要考虑现实中的需要,Dao模式来源于《J2EE核心模式》,其主要目的是分离(或透明化)主动域实体(或充血模型)的持久化过程,在领域驱动设计中,Service + Dao的设计也可以作为“防腐战略”设计的一部分,自然有它的合理性,但实际很多时候,不需要这样的“过度”设计,因为通常项目的工期都很紧,我们有时候以快速开发为主,如果你觉得JSP + JavaBean + JDBC的方式更好,我也不反对。
4 楼 超级潜水员 2008-10-30  
实际应用中,只有一种DaoImpl,什么HibernateDaoImpl,IbatisDaoImpl是不存在的.
所以实际开发中,我是No Dao Interface.
3 楼 yananay 2008-10-30  
其实 DAO 确实应该只是接口,其实我觉得根本不应该叫 “DAO”,而应该叫 Persistence。因为持久数据的方式有很多种,数据库只是其中一个。
俺赞同梁兄的设计
2 楼 jasin2008 2008-10-28  
sql写在service还是dao,个人更倾向于写在dao,service操作都是面向对象的,传到dao的也是一个pojo对象。这样对于简单的crud,service确实会退化为一个dao的代理,而对于复杂的业务逻辑,涉及到多个表的操作的时候,复杂sql写在dao层,service看起来更加简洁。
1 楼 jindw 2008-10-26  
javatar 写道
dao只对数据访问进行隔离,比如:Hibernate过时了,我们需要按一套全新的持久化方案,只需把Dao的实现类替换掉就行了。


这句话我总认为是听起来很美,不知道有没有人真正从中受益过。
如果hibernate过时了,那么我们开发的软件是否之前已经过时了呢。

真正要换掉dao层的时候,我想可能也不会像想象中那么简单的,其实DAO的代码相对倒是简单,更复杂的在于底层技术的一些细节。

甚至接口都要变化。

javatar 写道

还有一个问题是,复杂的SQL语句,是业务还是数据操作?该放在dao,还是service?
其实放在dao或service, 都能说得通,
但我觉得应该放在service, SQL语句本身是业务逻辑,只是执行它的应该是数据操作接口,


这个问题就更加复杂了,如果我们吧复杂查询放在DAO,那么我们的Service可就真的成了一个DAO的代理了,鸡勒。

如果我们放在service层,那么以前承诺的DAO层的可替换涉及也就落空了。你hibernate的HQL切换成其他查询语言,这个工作量可比我们换掉dao的代码复杂的多。


说一下我的做法。
DAO设计的时候给一个约定:只允许命名查询。
查询接口事制定查询名称和参数集合。这样,虽然查询还是在DAO做的,但是不是那种一个查询一个方法的方式。

这样做的好处就是Service不再像一个代理了。而DAO层也做了该做的事情。
还有一个好处就是,这样的DAO是可以自动生成的。

更多细节可以参看以前写的一个给予xdoclet的代码生成工具:
http://code.google.com/p/txdoc/downloads/list
http://txdoc.googlecode.com/svn/trunk/codegen/
这个项目虽然有点明日黄花了,一些想法还是有点参考价值。


相关推荐

    Netty粘包分包服务器端客户端完整例子

    这个项目可能包含了使用`LineBasedFrameDecoder`和`DelimiterBasedFrameDecoder`的服务器端和客户端实现,通过这些文件,开发者可以学习如何在实际项目中应用Netty来处理粘包和分包问题。 总之,理解和正确使用...

    全志OTA客户端服务器端完整文档以及服务器端 客户端源代码(按文档操作验证可以使用)

    总结来说,这个压缩包提供了一套完整的OTA解决方案,包括服务器端和客户端的源代码,以及差分包的生成方法,对于希望在全志平台上实现固件自动更新的开发者来说是一份宝贵的资源。通过深入理解和实践这些内容,...

    易语言客户源码,易语言服务器源码,易语言图片分包发送

    本压缩包文件包含的是易语言的客户端和服务器端源码,以及用于图片分包发送的相关实现。下面我们将深入探讨这些知识点。 首先,我们来理解“易语言客户源码”。在计算机网络应用中,客户端通常指的是用户交互的界面...

    钢结构厂房分包合同.pdf

    该文档是关于钢结构厂房分包合同的详细条款,主要涵盖了工程概述、分包内容、工程主要内容、价格计算和工期等方面。以下是对这些知识点的详细解释: 1. **合同依据**: - 这份合同基于《中华人民共和国合同法》、...

    android基于WiFi的socket客户端和服务器端

    在Android平台上实现基于WiFi的Socket通信,涉及到网络编程的核心概念,包括TCP/IP协议、套接字(Socket)以及客户端(Client)与服务器端(Server)的交互。本篇将详细阐述这些知识点,并以"SocketServer"和"Socket...

    TCP/IP文件传输服务器端

    在IT行业中,TCP/IP文件传输服务器端是一种常见的网络通信服务,它允许客户端通过TCP/IP协议栈从服务器上下载或上传文件。在这个项目中,我们利用MFC(Microsoft Foundation Classes)库来实现这样的功能,MFC是微软...

    结构加固专业分包合同.doc

    【结构加固专业分包合同】 本合同为一份关于结构加固工程的专业分包协议,由甲方(第一建筑工程团体)与乙方签订,旨在明确双方在工程中的权利和义务。根据《合同法》的规定,双方就工程需求达成一致,由乙方负责...

    Telnet服务器端源程序

    【标题】"Telnet服务器端源程序" 是一个基于Delphi编程环境开发的网络通信工具,主要用于实现远程终端服务。Delphi是一种强大的面向对象的编程语言,它以其高效的编译器和直观的集成开发环境(IDE)而闻名,是开发...

    使用udp client端分包发送图片数据、server端校验udp包的正确性合包将图片生成的例子

    2.client端 将图片数据转换成字节数据 增加鉴权 进行分包发送 3.server端校验udp包的正确性(避免其他人发送的错误包被解析) 4.server端将收到的udp包进行合并 5.server端合并后正确的生成一张图片。 6.使用说明...

    laya分包简单教程(无需积分和付费)

    今天,我们将深入探讨Laya分包简单教程,帮助开发者们轻松掌握如何在Laya游戏引擎中实现分包操作,无需积分和付费,旨在帮助您的游戏顺利上架并满足平台要求。 首先,了解是否需要进行分包是实施Laya分包操作的前提...

    客户端和服务器端通信程序

    - **TCP/IP协议**:客户端与服务器端通信通常基于TCP/IP协议,它确保了数据的可靠传输,包括连接建立、数据分包和重传机制。 - **Socket编程**:.NET中的`System.Net.Sockets.Socket`类是进行网络通信的核心,它...

    TCP 客户端与服务器端通信

    TCP客户端和服务器端之间的通信是互联网应用的基础,如网页浏览、电子邮件、文件传输等。本篇文章将深入探讨TCP客户端与服务器端通信的原理、实现方式以及C++编程中的应用。 首先,TCP通信的核心概念是三次握手建立...

    易语言文件传输分包模块

    3. **服务器与客户端交互**:服务器端负责文件的分发,客户端则负责请求和接收这些数据包。服务器需要维持一个队列来管理待发送的数据包,而客户端需要按顺序接收并验证这些数据包。 4. **错误恢复机制**:在接收端...

    易语言图片分包发送

    而在服务器端,我们需要监听并接收这些分包,按照接收到的顺序存储,同时对每个分包进行校验,确保数据的正确性。 在"服务器.e"和"客户.e"这两个源文件中,分别实现了服务器端和客户端的功能。服务器端负责接收和...

    stm32f407-TCP服务器数据收发实验_stm32f407TCP服务器端_

    在stm32f407的平台下,进行TCP的服务器端数据收发

    移动项目分包策略.docx

    • 从分包结构能够大致了解App的功能。 • 高度模块化大大提高了代码的可读性及可维护性。 • 包与包之间耦合度降低,拆分、添加或删除功能模块变得简单。 • 更加抽象化、模块化,方便扩展和重用。

    qt tcp udp socket 通信 实现文字、图片、文件、语音和实时对讲 包括客户端和服务器端,带有报告,所有功能支持

    qt tcp udp socket 通信。 实现文字、图片、文件、语音和实时对讲。 包括客户端和服务器端,带有报告,所有功能支持客户端和... 处理:与图片传输一致,做了分包粘包和客户端 服务器端的交互; 有简单协议封装。 6.对

    最简单的c++tcp/ip服务器端和客户端程序

    本项目提供了最简单的C++实现的TCP/IP服务器端和客户端程序,对于初学者理解网络编程概念以及进阶开发者进行快速原型设计都非常有帮助。 首先,TCP(传输控制协议)和IP(互联网协议)构成了Internet的基础。TCP...

    武汉市建设工程专业分包和劳务分包管理办法.doc

    总承包企业不得将工程肢解分包,且主体结构施工需自行完成。分包企业不能再次分包,除非特殊情况,如树建立项单位指定。 5. 总承包与分包企业的权利和责任: 总承包企业对工程质量、安全负总责,提供施工条件,监督...

Global site tag (gtag.js) - Google Analytics