首页 | 资讯动态 | linux基础 | 系统管理 | 网络管理 | 编程开发 | linux数据库 | 服务器技术 | linux相关 | linux认证 | 嵌入式 | 下载中心 | 专题 | linux招聘 | 镜像站
OKLinux中文技术站
·设为首页
·加入收藏
·联系我们
系统管理: 中文环境 系统管理 桌面应用 内核技术 | Linux基础: 基础入门 安装配置 常用命令 经验技巧 软件应用 | Linux数据库: Mysql Postgre Oracle DB2 Sybase other
网络管理: 网络安全 网络应用 Linux服务器 环境配置 黑客安全 | 编程开发: PHP CC++ Python Perl Shell 嵌入式开发 java jsp | PHP技术: PHP基础 PHP技巧 PHP应用 PHP文摘
Linux资讯 Linux招聘 Linux专题 Apache | Linux相关: 硬件相关 Linux解决方案 Linux认证 企业应用 其它Unix | 相关下载: 资料下载 参考手册 开发工具 服务器类 软路由 其它
 技术搜索:
会员中心 注册会员 高级搜索  
  → 当前位置:首页>编程开发>java>java企业应用>正文

设计模式之--Decorator模式、BUG和AOP

http://www.oklinux.cn  2008-03-07  来源: 赛迪网 yqi_xian  会员收藏  游客收藏  【 】 

本文从一个案例分析设计角度,讨论了使用设计模式可以比较优雅地实现了质量、功能和性能的统一。很多人以为设计模式是抽象概念,实际上,设计模式是实战经验的总结,只有正确使用了设计模式,才明白设计模式真正的运用技巧,避免了过分设计或设计不足。

  案例需求和问题
  多个图片上传是很多系统的基本功能,一般图片是一个主体父对象的附属,如是商店的图片、是人物的图片。以下商品Product为例。

  一般一个商品Product有多个图片Image,他们是1:N关系,表单中图片的处理不同于文字,用户需要将图片专门实现上传后,后台服务器系统必须接收和处理这个图片, 有两个办法:
  (1). 首先直接保存到数据库,等Product保存时,再将两者1:N关系保存数据库中;
   这个方案的缺点是:如果用户上传图片后,不再继续Product操作,那么,数据库中就有很多垃圾图片,这些图片找不到宿主Product。

  (2). 图片不保存到数据库,先暂存在内存中,等Product其它文字属性字段保存时,同时存入数据库。这个情况将图片视为文字一样普通字段,比较符合实际流程。

  第二个方案可以将图片保存到HttpSession中,带来一个问题:用户上传图片后,有可能需要删除,图片有可能是用户刚刚上传,保存在HttpSession中,也可能是在数据库中(修改商品数据时,同时希望更换商品的图片,而这时图片是从数据库中获得的)。

  面对这个问题,很多人认为比较简单,将HttpSession和数据库都视为数据源,同时新增或同时删除,如下图:



图1

  在整个图片上传功能中,涉及到几个功能类:
  首先是图片列表功能类,用来将HttpSession和数据库中当前Product下所有图片显示出来;
  其次是图片上传功能类,显示一个图片上传界面,然后接收上传的图片。
  最后是每个图片的显示功能类,每个图片需要专门的功能类处理才能显示。

  上述三种功能类都涉及图1的操作,也就是说,这三种功能类中都要和两种数据源打交道。

  还涉及到另外可扩展性问题,现在图片缺省的宿主是Product,以后可能是Person或其它任何需要图片的对象,因此,在这种设计中,我们必须重用图片上传功能。

  但是,矛盾在于,数据库一般是和具体宿主对象Product有具体联系的,在图片上传功能中必须和数据库某个具体数据表读取数据或写入数据。如何实现图片和宿主的解耦?

  现在,复杂问题出现了,由于加入功能类增多以及重用解耦的要求,使得图片上传功能的代码实现变得复杂。类图关系如下图:



图2

  很显然,这种调用关系非常纷乱,可扩展性很差,如果我们增加新的数据源,例如,由于图片文件都很大,因此我们经常采取缓存技术,这样提高图片显示速度,这种显示速度不亚于系统从文件系统中读取图片文件。如果加入缓存,那么所有的功能类都要修改一遍。

  更重要的是,图2丝毫没有给出将宿主和图片解耦的思路,反而是理还乱。很多人的思维停在这里就没有前进了,本着够用就好,KISS或愚笨原则,就会按照图2思路实现代码,这样下去结果是非常可怕的,通常陷入头痛医头、脚疼医脚的问题,测试人员只有测试到了这个系统的BUG才去修改,但是很多情况下,这种设计错误是无法靠测试来纠正的,因为测试不可能穷尽所有实际操作。这也是很多软件系统不稳定、BUG永远清除不了的原因之一。

  解决之道
  我无法总结图1是如何跳跃到图3的(可能是对此类应用的本质了解和模式理解),但是,我们可以知道,图3给我们思路重新打开了一道门:



图3

   我们把HttpSession和数据库不并列起来,而是串行,这样HttpSession好像是数据库的过滤器Filter或代理,这样如果有Cache机制加入,实际就是在HttpSession和数据库之间再加一个filter。

   在这种情况下,如果你熟悉GoF的23种设计模式,应该可以发现图片上传功能中可以使用设计模式了, Decorator模式是我们推荐的。



图4

   图4显然要比图2清晰得多,同时似乎一劳永逸解决了伸缩性和扩展性问题,具体Decorator模式实现代码这里不罗列,在各个功能类中调用Decorator模式的代码如下:

ImageFilter imageDbFilter = new ImageProductDbFilter();
ImageFilter imageCacheFilter = new ImageCacheFilter(imageDbFilter);
imageFilter = new ImageSessionFilter(imageCacheFilter);

   从调用代码看,图片上传功能已经可以重用,因为,对于不同的宿主,只要将ImageProductDbFilter()更换为ImageItemDbFilter()就可以了。

   如果将上述代码写为:
imageFilter = new ImageSessionFilter(new ImageCacheFilter(ImageProductDbFilter()));

   联想到Ioc和依赖性注射进而AOP,是不是可以对于不同的宿主应用,将具体ImageProductDbFilter()之类实现子类注射到这个图片上传系统中,就可以实现不同应用的图片上传功能?

   至此,以后的方向更加清楚了,应该是如何使用AOP或Ioc模式将图片上传功能重用提炼到框架中了。目前已经在JdonSD框架中实现。

  本文最终想表达的是:设计模式为我们开启了一扇正确的解决之门,从此我们的系统发生了质变,从程序员自觉朴素的代码走上了和软件设计思想发展方向一致的宽广大道。

  因为你已经将你的系统或模块纳入了一个软件理论体系中,这个理论体系一直在发展,你的系统或模块将会随着体系发展而有永久的生命力。你的问题不再是孤立的问题,也不再是特殊的问题。

  我的个案如我的孩子一样,我喜欢将我的个案纳入一种体系或标准中去,自此,他就有了发展和可参考发展的余地了,他就有生命了。


上一篇:数据库相关:Hibernate对多表关联查询   下一篇:Java 安全:Java 语言的 XML 验证 API


收藏于收藏夹】 【评论】 【推荐】 【打印】 【关闭
相关文档
·数据库相关:Hibernate对多表关联查询
·Java 安全:Java 语言的 XML 验证 API
·开发框架:Struts 基础介绍及开发流程
·Java语言深入--基于JNDI的应用开发
·开发框架--讨论Spring技巧之简洁配置
·Java GUI:在Java中监控文本框的变化
·开发框架:我认为Spring的一些负面因素
·Java GUI--浅析Swing设计JOptionPane
·超级简单的 sqlmap 工具(ajf sql map)
·设计及设计模式--设计模式之事务处理
·visitor模式概念-- visitor模式进一步
·开发框架--Hibernate为什么如此成功
·开发框架--超级简单的mvc框架实现AJF
·数据库相关:hibernate O/R映射之基础
·开发框架:初学者学习Hibernate的方法
·多线程设计模式:了解wait/notify机制
发表评论
密码: 匿名评论
评论内容:

(不超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规)
 
  最新文档
·Java SE6调用Java编译器的两种新方法
·表现层框架Struts/Tapestry/JSF比较
·在Web项目中用到JNI时应该注意的问题
·JBuilder7 Weblogic7 mysql开发EJB配置
·进阶:Java Reflection (JAVA反射)详解
·以全局的固定顺序获取多个锁来避免死锁
·JAVA高级:Java中限时线程回调方式的实
·超线程多核心下Java多线程编程彻底分析
·开发JAVA编程中字符串分割的两种方法
·Java理论和实践:用软引用阻止内存泄漏
·JAVA入门基础:区分引用类型和原始类型
·学习心得 - JSP处理异常及一些高级主题
  阅读排行
·Commons-logging Log4j 的入门指南
·进阶:Java Reflection (JAVA反射)详解
·服务器及中间件:TomCat 多虚拟站点配置
·开发框架:一篇关于SSH架构的简单总结
·jboss4.0下使用MySql数据源的设置方法
·Java语言:敏捷开发技巧-消除代码异味
·Java SE6调用Java编译器的两种新方法
·使用JAVA中的动态代理实现数据库连接池
·架构与模式:多线程有几种常用的编程模
·数据库相关:Log4j和JDBMonitor的比较
·开发框架-Struts里过滤器的简单使用
·表现层框架Struts/Tapestry/JSF比较
·在Web项目中用到JNI时应该注意的问题
·Java语言深入--基于JNDI的应用开发
·开发框架:利用STRUTS实现国际化支持
网摘收藏: