论坛首页 Java企业应用论坛

Map和实体类的使用等问题的讨论

浏览 5280 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-11-26   最后修改:2012-11-26
Java Web开发也有些年了,有些体会,想在这讨论下。
1、Map和实体类,用哪个来存放传递数据比较好。
2、在一些MVC框架中,用到拦截器,然后分发处理,所有请求都先集中到一个拦截器中,会不会存在性能问题。
3、登录验证的程序都是怎么实现的,或者也可以谈谈单点登录的实现。

我的看法:
对于1,觉得使用Map写代码很方便,不用新建实体类,相加几个属性就几个,而实体类,加个属性还要getter、setter,虽然Eclipse能自动生成。实体类虽然麻烦,但结构清晰,方便代码的阅读和维护,毕竟UML中还有类图来描述一个类,用了Map不规范。
对于2,这些框架都是在Servlet容器中跑的,其本质离不开Servlet、Filter、Listener这些概念,拦截器的本质应该是属于Filter的,所有请求都提交到这个拦截器中,并且会有一些复杂的业务逻辑处理,不知道会不会有性能瓶颈。对Servlet容器的运行机制了解还不是很透彻,不过现实当中好像没什么问题。
对于3,以前很多系统都不是很重视登录验证,用的是明文传递,后面会出问题。已下是我个人的想法:利用RSA来做加解密,当然它的效率会低一些,但是在登录这个过程中,觉得可以忽略这一点。在服务器端先生成好公钥和私钥,客户端Javascript用公钥加密,传递到服务端解密。当然存到数据库的密码是经过MD5或者sha1加密过的。

有兴趣的欢迎讨论。
   发表时间:2012-11-27   最后修改:2012-11-27
1.和你说的差不多吧   如果能抽象出合理的实体,对于OO是比较清晰的。
2.拦截器和filter机制是不一样的。虽然对外暴露的行为看似相同。是否有性能瓶颈,需要综合考虑。其1,你拦截器的复杂business逻辑是否需要花费很大的资源,比如IO等,如果你的业务就很慢,那么是不可避免的。如果大并发进行拦截,可能会有一些性能损失,一般情况下不会有啥问题,JVM帮你做了很多
3.明文肯定是不行的。还有加解密的性能开销我觉得可以ignore了。毕竟不是very very复杂的算法
0 请登录后投票
   发表时间:2012-11-27   最后修改:2012-11-27
使用实体模型,

缺点:
1. 模型转换不方便(系统内各层次;跨系统)
2. 实体模型增减属性修改代价较高

优点:
有显示的类型信息,安全、开发直观

个人喜好 Map 模型,更方便一些。
0 请登录后投票
   发表时间:2012-11-27   最后修改:2012-11-27
说到底就是强类型风格和弱类型风格哪个好。

个人建议是:如果项目不大,团队不大,对跨团队协作性(另一个团队主要通过阅读代码或文档来理解你的设计意图)和跨越较长时间的维护(后来的人主要通过阅读代码或文档来理解前人的设计意图)不是太关注的话,可以用Map。不过话说回来,如果是这样,干脆不要用Java,用RoR和PHP都比这样用Java要好。Java语言的灵活性和开发效率都不如这些纯粹的动态语言,相对来说最大的好处就是强类型所带来的可静态分析性。使用强类型的好处是,只要你不用Observer之类耦合性极弱的设计模式,基本上不用运行程序,就顺藤摸瓜都能把系统的执行状态理清。这种推理既可以顺着往后推,也可以倒着往前推。怎么方便就怎么来。

用了Map,如果你能保证所有put和get都通过统一的常量key来进行,那还没有严重破坏程序的可静态分析性。不过这样和用实体没有本质区别,增减属性就要相应地增减常量。唯一问题是如果程序分支比较多,每个分支又往同一个key里塞不同的数据的话,你就很难通过静态分析确定当前value的类型是什么。另一种情况是,如果系统需要长期维护,如果你对系统的设计意图不了熟悉(因为熟悉的人要么升职了,要么跳槽了,要么过劳死了),某一天系统出了一个casting的错误要你去修正,你很难判断究竟是put的位置塞错了value,还是get的位置对value的类型预期有错。

更大的问题是,既然你用了Map,后面就一定会有人开始使用动态生成的key来往Map里塞value,这样你就连Map里究竟有些什么key,是什么时候塞进去的都不知道了。如果某一天你按照你对系统的理解,在一个Map里取数,结果取到了错误的类型或者null,你除了在运行环境中把这个Map实例从创建时到你发现错误的位置这段生命周期一路按顺序打断点跟踪下来,没有任何其他办法搞清楚它的来龙去脉。
0 请登录后投票
   发表时间:2012-11-27   最后修改:2012-11-27
关于第2点,如果每次请求都进行那些复杂的业务逻辑是实现需求所需要的,那你对性能的任何考虑也只能先服从需求。如果不是必须的,你可以考虑加入判断是否执行或者使用缓存。

性能问题不建议过早考虑。个人建议是,对于业务系统,在功能都完成得差不多时,先定好性能标准,然后用loadrunner来压,只要整体达到标准,就不要管了。如果未达标,再用jprofiler之类的检测工具找性能热点来优化,而且只要优化到达标,就不要再做无用功了。

拦截器造成性能问题还是有可能存在的,我刚加入现在的公司时参与的一个项目就曾经试过。这个项目使用了jboss的seam2,这个框架默认对任何EJB上的public方法调用时都对这个EJB实例重新执行一次注入(重新对打了@In标注的属性赋值),而注入时需要取被注入的bean的名称。问题是,系统中这个bean的名称是你所指定的名称后面加上“component”后缀,这需要做一个字符串加法。在那个项目中,由于EJB互相调用和注入属性都特别多,导致一次请求中这个“求bean名称”的动作被执行了数万次,申请了上百M的的内存,虽然没有造成泄漏,但在高并发环境下引起了频繁GC,造成服务器时常停顿。之前他们一直通过加内存条的方法来缓和这个问题,我用jprofiler排查出来后,动员几个人把整个系统的EJB扫了一遍,在那些不需要注入的公共方法或者类上打上跳过注入的标注解决问题。
0 请登录后投票
论坛首页 Java企业应用版

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