论坛首页 Java企业应用论坛

Java Web应用的的包设计

浏览 7968 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-01-04  
OO
如何对Java包(Package)进行有效的组织,是一个需要仔细考虑设计问题。
在Java Web企业应用软件开发中,对于包设计,不知道大家都是怎么做的。我在下面给出一个例子,作为讨论的素材。

以网上购物商店为例,对客户来说,可能会有“浏览商品目录”、“订货”和“管理帐号”等用例,如果按照构架分层原则进行设计,可能会形成下面的包结构(暂且叫它技术驱动的包结构吧):
app.myshop.action <--Web层控制器
                 .CatalogAction
				 .OrderAction
				 ...
app.myshop.service <--服务接口及其实现
                  .CatalogService
				  .impl
				       .CatalogServiceImpl
app.myshop.dao <--数据源访问接口及其实现
              .OrderDao
			  .impl
			       .OrderDaoImpl
app.myshop.domain <--领域模型对象
                 .Order
				 .OrderLine
				 ...
app.myshop.common <-- 特别的层超类、常量及帮助类/工具类
                 .Constants
				 .BaseAction
				 .StringUtil
				 ...


如果按照用例进行设计,可能会形成下面的包结构(暂且叫它领域驱动的包结构吧):
app.myshop.catalog <--浏览商品目录用例
                  .Catalog <--目录模型对象
				  .Product <--产品模型对象
				  .CatalogSerivce <--目录服务接口
				  .CatalogDao <--Catalog及Product的数据源访问接口
				  .impl <--接口实现
				       .CatalogServiceImpl <--目录服务实现
					   .CatalogDaoImpl <--数据源访问实现
				  .CatalogAction <--Web层控制器
app.myshop.placeorder <--其他的用例
                     ...
app.myshop.common <-- 特别的层超类、常量及帮助类/工具类
                 .Constants
				 .BaseAction
				 .StringUtil
				 ...


我暂时保留观点,大家评论一下。
   发表时间:2007-01-04  
与楼主的相比,我更倾向于以下的分类方法。这种方法能同时根据问题域和类的功能进行分类。

java 代码
  1. 把整个应用按照不同的模块分成不同的项目:  
  2.   
  3. +--公共模块:  
  4. |    |  
  5. |    +--app.myshop.action <-- Web 层控制器  
  6. |    |  
  7. |    +--app.myshop.service <-- 服务接口及其实现  
  8. |    |  
  9. |    +--app.myshop.dao <-- 数据访问接口  
  10. |    |  
  11. |    +--app.myshop.model <-- 数据模型  
  12. |  
  13. +--商品目录:  
  14. |    |  
  15. |    +--app.myshop.action <-- Web 层控制器  
  16. |    |  
  17. |    +--app.myshop.service <-- 服务接口及其实现  
  18. |    |  
  19. |    +--app.myshop.dao <-- 数据访问接口  
  20. |    |  
  21. |    +--app.myshop.model <-- 数据模型  
  22. |  
  23. +……
0 请登录后投票
   发表时间:2007-01-04  
用maven的结构
0 请登录后投票
   发表时间:2007-01-06  
to kdekid: 你的这个结构,跟第一种方法没有本质的区别;
to dada: maven可不管你程序的包结构。

看来大家对此兴趣不大阿。不过我还是说一下我自己的观点吧。

评价一件事物的好坏,总的有个标准,下面是我个人比较认可的标准:

哪些原则指导包的构成?
1)包内高内聚。但在某些分布式环境下可能打破这个原则;
2)隐藏细节,特别是实现的细节;
3)面向问题域,使用该领域的一般概念组织包结构,而不是使概念支离破碎;
4)一个包内的类可以被共同重用(CRP?);

哪些原则指导包间的关系?
5)包间低耦合;
6)无循环依赖(ADP,见http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
7)稳定依赖(SDP,同上),尽量依赖稳定(稳定也意味着难以改变)的包;
8)抽象依赖(SAP,同上),稳定的包要用抽象的层(or接口)隔离。

按照这个原则看看前面的两种结构。
第一种结构违背了1)、3)和5)。1)和5)是显而易见的。对于3),强调领域驱动开发的人特别在意。
注意这个例子的问题域是网上商店。(这里要特别注意,Web应用与类库/框架开发的不同)。

第二种结构看起来都很好,但是违背了原则4)。这个程序里最能够被重用的显然是那些遍布在各个包里面
的领域模型类,尽管可以通过打包工具(ant/maven/...)把它们组织到一个jar里,但看起来还是很怪异。

so,现在隆重推出第三种解决方案:

app.myshop.application <--应用相关的包(service/action),可按用例组织
                      .catalog
					          .CatalogSerivce
							  .CatalogAction
							  .impl
							       .CatalogService
					  ... 其他用例的实现      
app.myshop.domain  <--集中了最核心的领域模型(如果复杂,可以在内部细分)
                 .Catalog
				 .Product
				 .CatalogRepository
                 ...
app.myshop.infrastructure <--基础设施,DAO也在此列
                         .util
						      .StringUtil
						 .dao
						     .CatalogDao
							 ...


匆忙的检查了一下checklist,好像没什么问题。真的没问题?
0 请登录后投票
   发表时间:2007-01-06  
uiafzhdl 写道
to kdekid: 你的这个结构,跟第一种方法没有本质的区别;

一般来说,按问题域划分子项目,按功能域划分包。这与你的第一种方法有一个本质的区别:平衡了同一个项目中类的增长速度和深度。

如果按照第一种方法划分包,当整个工程发展起来的时候,有可能在同一个项目、同一个包下会有上百个类出来,这显然不对。

按照第二种方法划分包也类似。

你的第三种方法事实上是按照更细的功能域分类,其实是第二种方法的扩展。当包的层次变得更复杂的时候,如果没有IDE的帮助,根本无法管理整个工程,而且也不利于把工程分配到子团队中实现。

个人意见是,一个好的设计,应当在包的层次和每层的数量上取得平衡(实际上是在树的深度和宽度上取得平衡),而不是盲目地划分过多的子问题域和功能域。当深度过大的时候,应当取消一定的子功能域,当宽度过大的时候,应当转移一部分的子问题到新的子项目中解决。项目对于着团队,在工程中自然有它的作用。
0 请登录后投票
   发表时间:2007-01-06  
kdekid:
引用
在树的深度和宽度上取得平衡
,你说的很令人信服。

但无论是你的划分方法,还是第一种划分方法,都有一些致命的问题:
1)包间高耦合,dao/service/model/action之间的联系远大于每个包内类间的关系,甚至在每个包内,各个类可能全无关系。
2)割裂了领域中的概念,使它们被彼此分散在各处,让开发者离领域越来越远。

所以才会有第二种、第三种方式对此进行修正。
0 请登录后投票
   发表时间:2007-01-06  


我一般这样划
---Action (包括Action及Form)
---Logic  (业务逻辑)
------Function(一些特殊的业务处理,如折扣计算公食什么的)
---Service (为业务逻辑提供服务)
---Domain  (领域对象)
---Dao    不说了
---Persistence 不说了
---Util  工具
------Bean  VO,PO等

如果工期紧Domain对象一时不好归纳,可以先放着,等完成基本功能后再从Bean中归结出来.

其实很多东西做了以后才知道,想一开始就完成所有规划是不切实际的,也是不必要的.所以我认为一开始划5-7层就差不多了,以后多了再重构,也不费多大力气.
0 请登录后投票
   发表时间:2007-01-26  
第一种包组织结构肯定不好,它是那种初看感觉层次很清楚,但是经不起细用,包之间的关联关系太大,往往查看某个业务,基本上所有的包都要顺序查看一次才能,我以前用的是第一种包组织结构。
现在,我比较偏向与第二中类型,楼主是按照用例来分,我喜欢按照组件,功能来分,比如学生的注册学籍,学生的考试模块等等都可以成为组件
0 请登录后投票
   发表时间:2007-01-26  
开发中最重要的是什么,毫无疑问是解决客户的问题域,是业务,
如果围绕业务的重用是被期待的,那么在调用API的时候,所以程序员会期待这样寻找自己想要的API:
  具体业务->层次->具体API, 而不是
  层次->业务API 或者 层次->业务->业务API
0 请登录后投票
   发表时间:2007-01-26  
我倾向1和2的综合,先2后1。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics