浏览 7968 次
锁定老帖子 主题:Java Web应用的的包设计
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-01-04
在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 ... 我暂时保留观点,大家评论一下。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-01-04
与楼主的相比,我更倾向于以下的分类方法。这种方法能同时根据问题域和类的功能进行分类。
java 代码
|
|
返回顶楼 | |
发表时间:2007-01-04
用maven的结构
|
|
返回顶楼 | |
发表时间: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,好像没什么问题。真的没问题? |
|
返回顶楼 | |
发表时间:2007-01-06
uiafzhdl 写道 to kdekid: 你的这个结构,跟第一种方法没有本质的区别;
一般来说,按问题域划分子项目,按功能域划分包。这与你的第一种方法有一个本质的区别:平衡了同一个项目中类的增长速度和深度。 如果按照第一种方法划分包,当整个工程发展起来的时候,有可能在同一个项目、同一个包下会有上百个类出来,这显然不对。 按照第二种方法划分包也类似。 你的第三种方法事实上是按照更细的功能域分类,其实是第二种方法的扩展。当包的层次变得更复杂的时候,如果没有IDE的帮助,根本无法管理整个工程,而且也不利于把工程分配到子团队中实现。 个人意见是,一个好的设计,应当在包的层次和每层的数量上取得平衡(实际上是在树的深度和宽度上取得平衡),而不是盲目地划分过多的子问题域和功能域。当深度过大的时候,应当取消一定的子功能域,当宽度过大的时候,应当转移一部分的子问题到新的子项目中解决。项目对于着团队,在工程中自然有它的作用。 |
|
返回顶楼 | |
发表时间:2007-01-06
kdekid:
引用 在树的深度和宽度上取得平衡 ,你说的很令人信服。
但无论是你的划分方法,还是第一种划分方法,都有一些致命的问题: 1)包间高耦合,dao/service/model/action之间的联系远大于每个包内类间的关系,甚至在每个包内,各个类可能全无关系。 2)割裂了领域中的概念,使它们被彼此分散在各处,让开发者离领域越来越远。 所以才会有第二种、第三种方式对此进行修正。 |
|
返回顶楼 | |
发表时间:2007-01-06
我一般这样划 ---Action (包括Action及Form) ---Logic (业务逻辑) ------Function(一些特殊的业务处理,如折扣计算公食什么的) ---Service (为业务逻辑提供服务) ---Domain (领域对象) ---Dao 不说了 ---Persistence 不说了 ---Util 工具 ------Bean VO,PO等 如果工期紧Domain对象一时不好归纳,可以先放着,等完成基本功能后再从Bean中归结出来. 其实很多东西做了以后才知道,想一开始就完成所有规划是不切实际的,也是不必要的.所以我认为一开始划5-7层就差不多了,以后多了再重构,也不费多大力气. |
|
返回顶楼 | |
发表时间:2007-01-26
第一种包组织结构肯定不好,它是那种初看感觉层次很清楚,但是经不起细用,包之间的关联关系太大,往往查看某个业务,基本上所有的包都要顺序查看一次才能,我以前用的是第一种包组织结构。
现在,我比较偏向与第二中类型,楼主是按照用例来分,我喜欢按照组件,功能来分,比如学生的注册学籍,学生的考试模块等等都可以成为组件 |
|
返回顶楼 | |
发表时间:2007-01-26
开发中最重要的是什么,毫无疑问是解决客户的问题域,是业务,
如果围绕业务的重用是被期待的,那么在调用API的时候,所以程序员会期待这样寻找自己想要的API: 具体业务->层次->具体API, 而不是 层次->业务API 或者 层次->业务->业务API |
|
返回顶楼 | |
发表时间:2007-01-26
我倾向1和2的综合,先2后1。
|
|
返回顶楼 | |