锁定老帖子 主题:分层结构的方法的参数的传递
精华帖 (1) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-05-05
downpour 写道 jonson 写道 凤舞凰扬,你的想法我觉得很有道理,但这这里其实存在一个问题的。 你说的 “明确系统所提供的功能与服务”最后还不是体现在UI上吗?所以如果说有人“表现层需要什么,就设计web service,然后在变成业务层。”也无可厚非吧。关键是做的时候是否进行功能点归并等的工作吧。 你错了,并不是所有的功能与服务都体现在UI上的。设计系统是一个复杂的过程,可以采用很多种方式。现在的很多情况下,UI驱动设计成为了很重要的一种工作方法。不过真正的Web Service,可能要涉及到系统间接口,针对UI的接口等各种各样的考虑。 谢谢downpour回答了这个问题。 我更想和jonson说明一下,首先你要理解的是MVC,为什么会有MVC,也就是为什么要将数据和表示相分离。UI只是一个人机的接口,只是提供给用户如何去操作系统的界面。而系统的核心价值在哪里,或者系统的功能在哪里?它也就是你的服务,你的系统能提供什么样的服务,能提供什么样的功能,这才是最重要的。所以这也是SOA最为核心的一个部分。 你发布WS的原因在哪里?如果只是一个简单的管理信息系统,丝毫没有任何必要这样做,像有些朋友所说的将DAO直接注射入Action夜并非不可取。Jonson所在的项目组的架构师应该准确地认识和分析这些东西,而非形而上学(哈哈,我喜欢这个词,最近也常用)。 |
|
返回顶楼 | |
发表时间:2009-05-05
downpour 写道 抛出异常的爱 写道 错误的标准在哪里能下载到? 跪球 : 传送门. PS:如果没有网络版给,讲一下大体上的方式可以么 PS2: 如果不用map 是怎么防止类暴炸的? 我可以作到参数套参数... 把类与参数 数量减少到一定的数量 但项目组里大多数人 不会喜欢作这么图劳无功的事 所以推行起来可能会有很大障碍. 对于一个具备强类型特征的语言来说,抛弃强类型的语法检查肯定不是最佳实践。更何况,对于WebService来说,使用Map作为参数进行传递完全就是不负责任的做法。从哲学上说,一个对外的接口,必须让调用者有明确的契约认识。对于把Map作为参数进行传递的做法,对于调用者而言,既不知道你Map中到底有哪些key值,又不知道你Map中每个key值所包含的数据类型和数据格式,请问这个接口还有什么意义?事实上,我见到过无数这样的接口,甚至连Java Doc都没有,让调用者一头雾水,害人害己。 至于使用DTO作为参数进行传递,事实上也早已经被证明是一个反模式。DTO这种模式很早就不应该存在了,除非在一些系统与系统之间的接口调用时,需要用到DTO(比如Ajax进行远程调用,返回的可能是一个DTO)。 正确的做法,应该从系统架构的实际出发,设计出最符合系统间服务调用的契约。对于典型的增删改操作,参数只需要直接与entity挂钩即可。对于查询操作,就有点麻烦,可能需要根据实际情况的不同,设计出来多种不同的函数契约,至于参数,不超过5个情况下,直接写清楚即可,对于超过5个的情况,就需要设计一个完整的能够表达契约约定的类来进行表述。 基本赞同downpour的观点,不过关于DTO的部分补充一下,个人不赞成直接使用entity,这里存在一个这样的问题,也就是web service的受众以及web service发布采用的标准。对于Jax-rpc来说,如果直接将entity作为参数发布,就可能遇到使用到java的集合类型(Collection/List/Set/Map)的,而如果受众并非java,是c#或者其他,便会出现问题,无法有效处理甚至无法识别。这对于一个基于服务的系统来说是不合适的。 |
|
返回顶楼 | |
发表时间:2009-05-05
steeven 写道 对于查询, 直接让客户传HQL进来吧, 或者可以很容易翻译成HQL的string.
反正后台也不过是简单拼装一下. 记得用varargs来做参数. 这样接口就完美了. 关于查询结构, hibernate里面好像有个对象来表达复杂的查询条件的. 看到这种观点,呵呵,我要打屎滴文的PP了........... |
|
返回顶楼 | |
发表时间:2009-05-06
凤舞凰扬 写道 downpour 写道 抛出异常的爱 写道 错误的标准在哪里能下载到? 跪球 : 传送门. PS:如果没有网络版给,讲一下大体上的方式可以么 PS2: 如果不用map 是怎么防止类暴炸的? 我可以作到参数套参数... 把类与参数 数量减少到一定的数量 但项目组里大多数人 不会喜欢作这么图劳无功的事 所以推行起来可能会有很大障碍. 对于一个具备强类型特征的语言来说,抛弃强类型的语法检查肯定不是最佳实践。更何况,对于WebService来说,使用Map作为参数进行传递完全就是不负责任的做法。从哲学上说,一个对外的接口,必须让调用者有明确的契约认识。对于把Map作为参数进行传递的做法,对于调用者而言,既不知道你Map中到底有哪些key值,又不知道你Map中每个key值所包含的数据类型和数据格式,请问这个接口还有什么意义?事实上,我见到过无数这样的接口,甚至连Java Doc都没有,让调用者一头雾水,害人害己。 至于使用DTO作为参数进行传递,事实上也早已经被证明是一个反模式。DTO这种模式很早就不应该存在了,除非在一些系统与系统之间的接口调用时,需要用到DTO(比如Ajax进行远程调用,返回的可能是一个DTO)。 正确的做法,应该从系统架构的实际出发,设计出最符合系统间服务调用的契约。对于典型的增删改操作,参数只需要直接与entity挂钩即可。对于查询操作,就有点麻烦,可能需要根据实际情况的不同,设计出来多种不同的函数契约,至于参数,不超过5个情况下,直接写清楚即可,对于超过5个的情况,就需要设计一个完整的能够表达契约约定的类来进行表述。 基本赞同downpour的观点,不过关于DTO的部分补充一下,个人不赞成直接使用entity,这里存在一个这样的问题,也就是web service的受众以及web service发布采用的标准。对于Jax-rpc来说,如果直接将entity作为参数发布,就可能遇到使用到java的集合类型(Collection/List/Set/Map)的,而如果受众并非java,是c#或者其他,便会出现问题,无法有效处理甚至无法识别。这对于一个基于服务的系统来说是不合适的。 赞同,如果直接使用entity而造成其它的无法处理的,我们不可以在封装吗;如果还是无法封装,我们为什么要考虑那么多,一个系统的开发也有个范围,没有完美的事情。 |
|
返回顶楼 | |
发表时间:2009-05-06
mimo 写道 凤舞凰扬 写道 downpour 写道 抛出异常的爱 写道 错误的标准在哪里能下载到? 跪球 : 传送门. PS:如果没有网络版给,讲一下大体上的方式可以么 PS2: 如果不用map 是怎么防止类暴炸的? 我可以作到参数套参数... 把类与参数 数量减少到一定的数量 但项目组里大多数人 不会喜欢作这么图劳无功的事 所以推行起来可能会有很大障碍. 对于一个具备强类型特征的语言来说,抛弃强类型的语法检查肯定不是最佳实践。更何况,对于WebService来说,使用Map作为参数进行传递完全就是不负责任的做法。从哲学上说,一个对外的接口,必须让调用者有明确的契约认识。对于把Map作为参数进行传递的做法,对于调用者而言,既不知道你Map中到底有哪些key值,又不知道你Map中每个key值所包含的数据类型和数据格式,请问这个接口还有什么意义?事实上,我见到过无数这样的接口,甚至连Java Doc都没有,让调用者一头雾水,害人害己。 至于使用DTO作为参数进行传递,事实上也早已经被证明是一个反模式。DTO这种模式很早就不应该存在了,除非在一些系统与系统之间的接口调用时,需要用到DTO(比如Ajax进行远程调用,返回的可能是一个DTO)。 正确的做法,应该从系统架构的实际出发,设计出最符合系统间服务调用的契约。对于典型的增删改操作,参数只需要直接与entity挂钩即可。对于查询操作,就有点麻烦,可能需要根据实际情况的不同,设计出来多种不同的函数契约,至于参数,不超过5个情况下,直接写清楚即可,对于超过5个的情况,就需要设计一个完整的能够表达契约约定的类来进行表述。 基本赞同downpour的观点,不过关于DTO的部分补充一下,个人不赞成直接使用entity,这里存在一个这样的问题,也就是web service的受众以及web service发布采用的标准。对于Jax-rpc来说,如果直接将entity作为参数发布,就可能遇到使用到java的集合类型(Collection/List/Set/Map)的,而如果受众并非java,是c#或者其他,便会出现问题,无法有效处理甚至无法识别。这对于一个基于服务的系统来说是不合适的。 赞同,如果直接使用entity而造成其它的无法处理的,我们不可以在封装吗;如果还是无法封装,我们为什么要考虑那么多,一个系统的开发也有个范围,没有完美的事情。 对于契约封装这种方式来说很正解 但我认为尽量减少理解困难角度来讲 map可以作为ibatis的参数减少dao与mapping的代码 map可以当作(非业务必须)参数的页面显示用的容器,减少action的参数总数量. 这两点对于一般服务性业务来说(非平台软件)还是有必要的 |
|
返回顶楼 | |
发表时间:2009-05-06
如果换个思路来想,你的这个方法的作用不是获得User全部信息。
而是你有一个User,这个方法就是判断这个User是否存在,如果存在或取其全部信息。 把所有这些东西抽象成一个数据类型不可以么? |
|
返回顶楼 | |
发表时间:2009-05-06
抛出异常的爱 写道 对于契约封装这种方式来说很正解 但我认为尽量减少理解困难角度来讲 map可以作为ibatis的参数减少dao与mapping的代码 map可以当作(非业务必须)参数的页面显示用的容器,减少action的参数总数量. 这两点对于一般服务性业务来说(非平台软件)还是有必要的 抛同学,dao中使用Map做参数当然是没有问题的,难道你不把dao作为一个很工具的层面去看吗?在我看来,一切DAO和工具类没什么两样,除了HQL和参数以外,应该没有其他业务了。 但是在业务逻辑层,我是坚决反对使用Map或者毫无意义的DTO作为参数进行传递的,因为它实际上破坏的接口的契约含义,使得制定接口的意义变得几乎没有。 至于谈到WebService的接口设计,又是另外一回事情了,可能连entity都不适合作为参数进行传递。这个时候,函数签名的设计更加重要。 不知道你是否能同意我的观点。 |
|
返回顶楼 | |
发表时间:2009-05-06
最后修改:2009-05-06
关于接口传参数问题,当数量多于5个的时候,我赞同用有意义的DTO的形式进行组织参数。强烈反对把参数Map化,Object化。
1.因为用Map这种聚集类型作为接口的参数,会使应用人员或者维护人员不知道这个map对象里究竟装的什么东西。 (我不记得是谁曾说过可以在该接口上面写/** */注释标明里面的参数情况。无语....) 2.甚至这个map对象有时候会从web层一直传到dao层,维护起来极为不方便(开发到是很方便,不用写那么多代码转来转去的)。 3.如果参数有变(例如map中的key值的发生改变,以前是A1现在改成A2),那么查找引用的地方非常麻烦。稍有不慎将给系统留下隐藏的bug,查找这种bug是比较耗时、耗力的工作。 |
|
返回顶楼 | |
发表时间:2009-05-07
mimo 写道 赞同,如果直接使用entity而造成其它的无法处理的,我们不可以在封装吗;如果还是无法封装,我们为什么要考虑那么多,一个系统的开发也有个范围,没有完美的事情。 看来mimo都不清楚java是如何发布WS的,或者说不清楚java,xml binding的(不用JAXB的原因是不仅仅只有JAXB这种binding方式),呵呵。这个时候,任何封装都没有用的。 |
|
返回顶楼 | |
发表时间:2009-05-07
抛出异常的爱 写道 对于契约封装这种方式来说很正解 但我认为尽量减少理解困难角度来讲 map可以作为ibatis的参数减少dao与mapping的代码 map可以当作(非业务必须)参数的页面显示用的容器,减少action的参数总数量. 这两点对于一般服务性业务来说(非平台软件)还是有必要的 其实downpour的观点并非不能用map,而是不应该在对外服务级接口使用。Map作为参数,最合适的是在功能级的接口参数,例如工具方法或者不确定变量等,其实对于不确定变量参数内容,也应该是通过类Map的context对象方式传递,而不是Map本身,因为Map是无法序列化,并且无法知道其内部对象是否支持序列化,这对于网络应用(包括web)是潜在的风险的。 |
|
返回顶楼 | |