首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

分层构造的方法的参数的传递

2012-10-24 
分层结构的方法的参数的传递公司的项目分层,是公司自己搭建的框架,分为form层、web service层、biz层,其中bi

分层结构的方法的参数的传递
公司的项目分层,是公司自己搭建的框架,分为form层、web service层、biz层,其中biz层负责访问数据库,web service负责调用biz层,而form层则不和biz直接打交道,而调用的是ws层。在这当中,经常会用到这种情况。其实form层需要调用的方法,其实在ws和biz层使用的都是同名的方法,这样也方便调用。本来这样也无可厚非,而且还更不容易出错。但是这样,业务模块多了之后也发现另外一个问题。因为各层的方法名以及方法参数几乎一摸一样,在开发的时候,写每层的方法还可以直接copy和paste,但是一旦修改起来,这可就麻烦大了。重复工作量大。而且最要命的是方法不修改,但是修改参数个数或者参数类型,结果稍不留意就会把类型搞错或者参数不对应。后来有一想法,但是始终没有最后这样实施,但是个人觉得,这样还是很有好处,可能上层决策层不这么认为吧。
比如一个方法GetAllEmp(string name,bool sex, string address, int age),这里有四个参数,这样每一层都会有一个GetAllEmp(string name,bool sex, string address, int age)方法,但是我的想法不是每一层都去写一个参数,而是把参数封装起来,封装成一个对象一个ArrayList对象或者是一个object对象,这样在层与层之间方法的参数的传递的时候,就不会去在意这些参数的类型与个数的问题。当这个单个的对象传递到具体的层的时候,在对这个对象进行类型转换。只要在当初封装的时候没有问题,这个对象的封装与解封装是应该不会出问题的。这种方法,至少到目前为止,可能是因为我的目光以及水平问题,还只看到了他的有点,他有什么缺陷还真没有意识到。
抛砖引玉。
23 楼 downpour 2009-05-04   抛出异常的爱 写道

错误的标准在哪里能下载到?
跪球 : 传送门.

PS:如果没有网络版给,讲一下大体上的方式可以么

PS2:
如果不用map 是怎么防止类暴炸的?
我可以作到参数套参数...
把类与参数 数量减少到一定的数量
但项目组里大多数人
不会喜欢作这么图劳无功的事
所以推行起来可能会有很大障碍.

对于一个具备强类型特征的语言来说,抛弃强类型的语法检查肯定不是最佳实践。更何况,对于WebService来说,使用Map作为参数进行传递完全就是不负责任的做法。从哲学上说,一个对外的接口,必须让调用者有明确的契约认识。对于把Map作为参数进行传递的做法,对于调用者而言,既不知道你Map中到底有哪些key值,又不知道你Map中每个key值所包含的数据类型和数据格式,请问这个接口还有什么意义?事实上,我见到过无数这样的接口,甚至连Java Doc都没有,让调用者一头雾水,害人害己。

至于使用DTO作为参数进行传递,事实上也早已经被证明是一个反模式。DTO这种模式很早就不应该存在了,除非在一些系统与系统之间的接口调用时,需要用到DTO(比如Ajax进行远程调用,返回的可能是一个DTO)。

正确的做法,应该从系统架构的实际出发,设计出最符合系统间服务调用的契约。对于典型的增删改操作,参数只需要直接与entity挂钩即可。对于查询操作,就有点麻烦,可能需要根据实际情况的不同,设计出来多种不同的函数契约,至于参数,不超过5个情况下,直接写清楚即可,对于超过5个的情况,就需要设计一个完整的能够表达契约约定的类来进行表述。 24 楼 lgcpeter 2009-05-04   在biz层直接写HQL语句最简练,业务做细了或以后扩展都简单。
否则dao的方法参数总要改。 25 楼 funnywiser 2009-05-04   其实这些问题,都是由于分层过细引起的。
分层确实也是个值得探讨的问题。本身分层就是希望低耦合,以便于将来修改,但是他只适合于逻辑算法的变化,并不适合于接口的变化或者数据结构的变化,包括参数的变化。当发生接口或者参数的变化时,反而使得增个变更变得更加复杂。
如果想因此,放弃分层,却发现这种方式,会放纵程序员,最终也使得维护比较麻烦。
我们是自己做开发平台的,因此接口的维护是可以配置的。至于分层是由平台提供。但是从原理来说,也存在这种接口变化问题。仔细分析话,我们使用Map来存储接口参数的,当然这个Map会一层层传下去,包括最后回传的时候,也是一层层再传回来。
这样不光参数是可变的,而且返回值也是可以多个,而且是可变的。
你要说性能,其实也是非常快的。因此这个Map只生成一次,数据只在一个地方存储。如果用原始方式实现,将数据放到类中的属性来实现,要多次复制数据。这个不光影响速度而且也消耗内存。 26 楼 neora 2009-05-04   抛出异常的爱 写道downpour 写道抛出异常的爱 写道
理解一下业务....看看参数是否是一个 bean的片段....如果是的话...{
    用这个bean.

}如果不是,看这个参数数量是否大于3.{
    不大于3可直串.
}如果参数大于3{
    用map传.
}其它{
    新建一个传参bean
}

完全扯淡,不懂不要随便误导别人。

使用DTO或者Map作为参数传递都是典型的错误做法。除了工具方法,与业务逻辑相关的接口,都不应该使用DTO或者Map作为参数。



错误的标准在哪里能下载到?
跪球 : 传送门.

PS:如果没有网络版给,讲一下大体上的方式可以么

PS2:
如果不用map 是怎么防止类暴炸的?
我可以作到参数套参数...
把类与参数 数量减少到一定的数量
但项目组里大多数人
不会喜欢作这么图劳无功的事
所以推行起来可能会有很大障碍.

造成需要Map或者DTO的原因有三个,一个是领域划分不清,业务对象没有承担应有的职责。二是Java语言的静态性限制了走捷径。三是的确少部分调用特别是从WEB层传递下来的操作,的确需要太多的参数。然而其实在第三种情况下用DTO也会比Map要好些,它毕竟是一个参数对象,除了getter/setter还可以加入一些特定层次需要的一些method。很多这类方法加在这种所谓的Dto中,要比加在Util中更自然,更舒服。
如果是开发框架,Map的用途是很大的,但不建议直接暴露给App的开发人员。在开发App的过程中,Map还是能不用就不用就不用吧。 27 楼 steeven 2009-05-04   对于查询, 直接让客户传HQL进来吧, 或者可以很容易翻译成HQL的string.
反正后台也不过是简单拼装一下. 记得用varargs来做参数. 这样接口就完美了.

关于查询结构, hibernate里面好像有个对象来表达复杂的查询条件的. 28 楼 leadyu 2009-05-04   不同的层次应该有不同的数据对象,哪怕他们的实体都是一个,但职责角色肯定是不同的。这是我判断是否需要划分层次的一个原则,这时候在不同层次进行传递才需要DTO。

如果模块简单到各层次对象结构都一样,那说明职责上就不需要,起码不那么需要划分多一个层次,设计时就得考虑。

而对于系统中这种简单模块,这时候为了保有整个系统层次划分的一致性,可以写个通用的Adaptor转发一下,直接跳过不需要的层次。

这是我的办法。^^ 29 楼 凤舞凰扬 2009-05-05   魔力猫咪 写道
没错。就是把业务放到Action或Dao中了。我觉得把Dao作为一个组件看待的话,完全可以直接调用,不用非得傻傻的写个转发的空方法。当然,这个前提是业务只是最简单的CRUD,没有一点其他业务在里面。
   如果系统真的很简单,项目也很小。我个人并不反对这样做,只是希望猫咪理解为何要分层就可以了。 30 楼 凤舞凰扬 2009-05-05   downpour 写道jonson 写道
凤舞凰扬,你的想法我觉得很有道理,但这这里其实存在一个问题的。 你说的 “明确系统所提供的功能与服务”最后还不是体现在UI上吗?所以如果说有人“表现层需要什么,就设计web service,然后在变成业务层。”也无可厚非吧。关键是做的时候是否进行功能点归并等的工作吧。


你错了,并不是所有的功能与服务都体现在UI上的。设计系统是一个复杂的过程,可以采用很多种方式。现在的很多情况下,UI驱动设计成为了很重要的一种工作方法。不过真正的Web Service,可能要涉及到系统间接口,针对UI的接口等各种各样的考虑。
   谢谢downpour回答了这个问题。
   我更想和jonson说明一下,首先你要理解的是MVC,为什么会有MVC,也就是为什么要将数据和表示相分离。UI只是一个人机的接口,只是提供给用户如何去操作系统的界面。而系统的核心价值在哪里,或者系统的功能在哪里?它也就是你的服务,你的系统能提供什么样的服务,能提供什么样的功能,这才是最重要的。所以这也是SOA最为核心的一个部分。
   你发布WS的原因在哪里?如果只是一个简单的管理信息系统,丝毫没有任何必要这样做,像有些朋友所说的将DAO直接注射入Action夜并非不可取。Jonson所在的项目组的架构师应该准确地认识和分析这些东西,而非形而上学(哈哈,我喜欢这个词,最近也常用)。 31 楼 凤舞凰扬 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#或者其他,便会出现问题,无法有效处理甚至无法识别。这对于一个基于服务的系统来说是不合适的。
32 楼 凤舞凰扬 2009-05-05   steeven 写道对于查询, 直接让客户传HQL进来吧, 或者可以很容易翻译成HQL的string.
反正后台也不过是简单拼装一下. 记得用varargs来做参数. 这样接口就完美了.

关于查询结构, hibernate里面好像有个对象来表达复杂的查询条件的.
   看到这种观点,呵呵,我要打屎滴文的PP了........... 33 楼 mimo 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而造成其它的无法处理的,我们不可以在封装吗;如果还是无法封装,我们为什么要考虑那么多,一个系统的开发也有个范围,没有完美的事情。 34 楼 抛出异常的爱 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的参数总数量.

这两点对于一般服务性业务来说(非平台软件)还是有必要的

35 楼 chandler 2009-05-06     如果换个思路来想,你的这个方法的作用不是获得User全部信息。
  而是你有一个User,这个方法就是判断这个User是否存在,如果存在或取其全部信息。
  把所有这些东西抽象成一个数据类型不可以么? 36 楼 downpour 2009-05-06   抛出异常的爱 写道

对于契约封装这种方式来说很正解

但我认为尽量减少理解困难角度来讲
map可以作为ibatis的参数减少dao与mapping的代码
map可以当作(非业务必须)参数的页面显示用的容器,减少action的参数总数量.

这两点对于一般服务性业务来说(非平台软件)还是有必要的



抛同学,dao中使用Map做参数当然是没有问题的,难道你不把dao作为一个很工具的层面去看吗?在我看来,一切DAO和工具类没什么两样,除了HQL和参数以外,应该没有其他业务了。

但是在业务逻辑层,我是坚决反对使用Map或者毫无意义的DTO作为参数进行传递的,因为它实际上破坏的接口的契约含义,使得制定接口的意义变得几乎没有。

至于谈到WebService的接口设计,又是另外一回事情了,可能连entity都不适合作为参数进行传递。这个时候,函数签名的设计更加重要。

不知道你是否能同意我的观点。 37 楼 mydolors 2009-05-06      关于接口传参数问题,当数量多于5个的时候,我赞同用有意义的DTO的形式进行组织参数。强烈反对把参数Map化,Object化。
   1.因为用Map这种聚集类型作为接口的参数,会使应用人员或者维护人员不知道这个map对象里究竟装的什么东西。 (我不记得是谁曾说过可以在该接口上面写/** */注释标明里面的参数情况。无语....)
   2.甚至这个map对象有时候会从web层一直传到dao层,维护起来极为不方便(开发到是很方便,不用写那么多代码转来转去的)。
   3.如果参数有变(例如map中的key值的发生改变,以前是A1现在改成A2),那么查找引用的地方非常麻烦。稍有不慎将给系统留下隐藏的bug,查找这种bug是比较耗时、耗力的工作。 38 楼 凤舞凰扬 2009-05-07   mimo 写道
赞同,如果直接使用entity而造成其它的无法处理的,我们不可以在封装吗;如果还是无法封装,我们为什么要考虑那么多,一个系统的开发也有个范围,没有完美的事情。
   看来mimo都不清楚java是如何发布WS的,或者说不清楚java,xml binding的(不用JAXB的原因是不仅仅只有JAXB这种binding方式),呵呵。这个时候,任何封装都没有用的。 39 楼 凤舞凰扬 2009-05-07   抛出异常的爱 写道
对于契约封装这种方式来说很正解

但我认为尽量减少理解困难角度来讲
map可以作为ibatis的参数减少dao与mapping的代码
map可以当作(非业务必须)参数的页面显示用的容器,减少action的参数总数量.

这两点对于一般服务性业务来说(非平台软件)还是有必要的


   其实downpour的观点并非不能用map,而是不应该在对外服务级接口使用。Map作为参数,最合适的是在功能级的接口参数,例如工具方法或者不确定变量等,其实对于不确定变量参数内容,也应该是通过类Map的context对象方式传递,而不是Map本身,因为Map是无法序列化,并且无法知道其内部对象是否支持序列化,这对于网络应用(包括web)是潜在的风险的。 40 楼 downpour 2009-05-07   凤舞凰扬 写道抛出异常的爱 写道
对于契约封装这种方式来说很正解

但我认为尽量减少理解困难角度来讲
map可以作为ibatis的参数减少dao与mapping的代码
map可以当作(非业务必须)参数的页面显示用的容器,减少action的参数总数量.

这两点对于一般服务性业务来说(非平台软件)还是有必要的


   其实downpour的观点并非不能用map,而是不应该在对外服务级接口使用。Map作为参数,最合适的是在功能级的接口参数,例如工具方法或者不确定变量等,其实对于不确定变量参数内容,也应该是通过类Map的context对象方式传递,而不是Map本身,因为Map是无法序列化,并且无法知道其内部对象是否支持序列化,这对于网络应用(包括web)是潜在的风险的。

补充得太完美,每句都是我想说的。 41 楼 funnywiser 2009-05-07   如果是手工编码开发,那么按照面向接口编程的原则,参数在接口中是确定的。如果需要动态的话,那么用接口类的Object来进行传递,返回值也是这样考虑。
但由于我们采用代码自动生成方式的,因此不需要手写编写程序来处理Map中的数据。因此Map还是最灵活一种方式。 42 楼 抛出异常的爱 2009-05-07   downpour 写道抛出异常的爱 写道

对于契约封装这种方式来说很正解

但我认为尽量减少理解困难角度来讲
map可以作为ibatis的参数减少dao与mapping的代码
map可以当作(非业务必须)参数的页面显示用的容器,减少action的参数总数量.

这两点对于一般服务性业务来说(非平台软件)还是有必要的



抛同学,dao中使用Map做参数当然是没有问题的,难道你不把dao作为一个很工具的层面去看吗?在我看来,一切DAO和工具类没什么两样,除了HQL和参数以外,应该没有其他业务了。

但是在业务逻辑层,我是坚决反对使用Map或者毫无意义的DTO作为参数进行传递的,因为它实际上破坏的接口的契约含义,使得制定接口的意义变得几乎没有。

至于谈到WebService的接口设计,又是另外一回事情了,可能连entity都不适合作为参数进行传递。这个时候,函数签名的设计更加重要。

不知道你是否能同意我的观点。

同意你的观点但在本例上面
的问题是对
多参数的优化

多参数的方案:
第一条我主张使用某个
有逻辑意义的bean来放数据
这样最好
但这个世界上有最好
就有作不到

所以第二我提出来直接放数值
对于指定的功能可能更要合适一些
因为一眼就能明白这个方法的需要

当然这样就出了楼主的问题
参数过多

一般的好的实践是整合参数
把对应的参数放入对应意义bean中
使数据总量再减少...
当然这样作的好处可以看的见
但实际编程人员不这样认为
更有可能
变的更不可控制.
所以实际推广难度非常之大

不得已使用了更好推广的方式
恶心的map
为了防止 map 中的 key 值拼写问题
用了另一个恶心方工
那就是:接口中存放的静态变量
用这种静态变量作为key

当然使用dto也可以
但上个项目中爆发的dto
心有余忌....
大多数时候否定此方案.


当然对于平台开发来说可能这是不好的实践
但在服务业务开发团队来说是可操作的的.

对于我这种无神论者
就是好用的规则那是好规则
无法被团队成员接受的规则
踢到一边去.

不必一上来就要求别人用最佳实践.
而是先把好上手的实践普及
再考虑不好上手的最佳实践

楼上反对我用map都是从平台角度
上说的我非常理解.
是好东西.
但如果真的需要我会设计成非map类的.
现在先这样吧.

热点排行