很好的文章,谢谢banq

不是很确定是否看懂了问题。不过乍看上去,这个解决方案并不理想。
把HttpSession这个servlet api的东西和比较独立的图片上传耦合起来,怎么能够达到最大的重用性呢?

毕竟,图片上船和http session并没有直接关系,不管是http session,还是db,都不过是你实现图片上船的一个具体方法而已。

从问题的描述来看,很明显的,第一印象应该是试图抽象这个ImagePersistence接口。
让图片模块只和这个抽象的ImagePersistence交互。ImageUpload只管上船,ImagePersistence负责储存,各干各的。

然后,针对http session, cookie, db, file, memory+session, memory+file blah blah blah, 各自实现自己的ImagePersistence实现。

多谢ajoo有兴趣看这篇文章。

HttpSession只是一个暂存处,可能有其它暂存处或持久处,注意暂存处和持久处是有区别的,区别在于,前者电源一关就没了。

关键在于,要搭一个架子,让你提到的那些blash blash暂存处或持久处能够动态加入。

“ImageUpload只管上船,ImagePersistence负责储存,各干各的”
这些只是我这个架子的客户端,ImageUpload和ImagePersistence性质还不一样,ImageUpload可能要调用ImagePersistence,除了ImageUpload,还会有 ImageShow(也可能调用ImagePersistence)等,这就会发生我图2所示的情况。


你分析的不错。那么就叫ImageTemp也好。
其实,不是说电源一关就一定没有,而是说:这个ImageTemp不保证电源一关还有。:)

我对你这个解法的唯一意见在于,把HttpSession和Image不必要地耦合了。

假如,以后想抛开session,直接存在内存中(我内存无限大,你管不着),或者存在一个定时清除的硬盘上的临时目录中,你难道还要改框架?

在我看来,理想情况是:你要能找一个根本不知道什么是servlet的人,就告诉他:这是我对image upload, query, show的要求,这是我的ImageTmp的接口。
然后他就能够给你作出这个Image库来。
毕竟,这个库本质上并不依赖于servlet。

为什么这样耦合不好呢?
本着单向依赖,你的servlet应该肯定会调用image模块,
那么,就不应该让image模块再去依赖servlet。

image模块就是一个utility,无法想象java.util.Hashtable, java.lang.String会去依赖servlet或者是ejb的api。

我看了以後
X得很疑惑的是ImageFilter的接口要怎NO
不知道jdon或是榘逵延惺颤N建h
最好能以java的Z法描述

to ajoo
笨笨的小猪还是非常有执著心的啊,你也分析得非常对,现在这个图片上传是基于J2EE的,需要servlet等容器支持,为什么呢?
关键一点是,需要基于一个用户的暂存系统支持,也就是说,该用户上传图片后,需要将图片暂存在以该用户ID为Key的一个缓存的地方,生存周期是该用户登陆时间,这样,该用户在下一步操作才能将上一步操作的图片取出。

当然,在内存其它地方做这种类似HttpSession的暂存处也可以,暂存处的生命周期需要不少代码去支持,相当于做一个实现HttpSession 的底层机制,我想这偏离了应用为本的方向了吧?:)

to popcorny
ImageFilter的接口实际是图片的相关操作, ImageFilter也是Facade作用。

不是说现在要抛开http session,自制session什么的。
是要保留变化余地,避免双向依赖。

该用http session自然照样用。但是通过接口,让image模块依赖于抽象,而不是直接依赖于http session这个实现细节。

我想,此时正如你说,不能KISS, 必须设计一个灵活的框架了。

看起来这个问题是一个多步事务处理的问题,存product信息和图片信息是一个产品信息存储中的两个过程,需要事务处理以保证数据的一致性。利用statefull session bean,或者HttpSession管理内存结构也是解决办法之一。

有几个地方有待商拓:

> 在整个图片上传功能中,涉及到几个功能类:
> ...
>  最后是每个图片的显示功能类,每个图片需要专门的功能类处理才能显示。

"每个图片要专门的类来处理"是什么意思呢,应该一个类应该就可以了。

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

这个联系就是数据固有的特性,解藕会带来什么好处呢?

banq提到用AOP里面的插入技术做缓存处理也是比较合适的。
直接利用HttpSession做filter的确是增加了对于servlet的依赖性,这个是要考虑的。

enoh 分析得很有道理

>如何实现图片和宿主的解耦?

>这个联系就是数据固有的特性,解藕会带来什么好处呢?

和父对象解耦主要是最大程度实现重用,这样,这个功能不只是商品图片,可以是任何主体的图片,如文章的图片、示例的图片等。

这个重用已经包括到Jsp页面的功能,使得它类似一个Form表单控件一样。

因为也包含了部分Jsp页面,因此request是一个贯穿主线,这就不得不依赖Servlet的Request了。

这也是需要进一步提升的地方。

其实这并不是一个什么复杂的问题,感觉有点硬性的使用设计模式的感觉,本身图片上传就应该做成一个模块,模块内部实现尽可能的优化以提高效率,和外界尽可能的减少耦合,而在模块的数据库相关部分可以考虑使用hibernate的一些技术来优化速度缓存的一些相关问题,就可以了。这些和servlet没什么关系。

>图片上传就应该做成一个模块
关键是如何做成一个耦合性小的独立模块,设计模式提供了实现途径。

我想发表点意见,不知我有没有理解错误,有就请见谅!
我不知为什么ajoo一定要针对httpSession来说和xssily为什么说并不复杂,好像有点太过针对特实的实现来研究,设计模式本就是用来把实现抽象出来,而且在这个例子中,banq也已经说明了图片功能已经从数据库或其它地方解耦出来,只要用依赖注射就可以将其它的操作(如宿主)注射进去!
我觉得banq那里没有什么问题,已经说明了一个很好的设计模式!