⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jive.html

📁 写给JSP初级程序员的书
💻 HTML
📖 第 1 页 / 共 3 页
字号:
    <td WIDTH="100%" VALIGN="TOP">
      <tr>
        <td WIDTH="100%" CLASS="white"></td>
      </tr>
    
      <tr>
        <td WIDTH="50%" bordercolor="#FFFFFF" CLASS="t1" bgcolor="#F0F0F0" align="center" nowrap>Jive 中的设计模式 </td>
       <p> <td WIDTH="50%" bordercolor="#FFFFFF" CLASS="t1" bgcolor="#F0F0F0" align="center" nowrap>作者:SuperMMX    </td></p>
      </tr>
      <tr>        <td WIDTH="100%" bordercolor="#FFFFFF" CLASS="t" bgcolor="#F0F0F0" colspan="2">
       <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;摘要: <BR>&nbsp;&nbsp;&nbsp;&nbsp;    Jive 是一个开放源码的论坛项目, 也就是我们所常见的 BBS, 采用了 SUN <BR>&nbsp;&nbsp;&nbsp;&nbsp;公司的 JSP 技术, 相比起 j2ee 这个庞大的体系结构, 其整个的设计思想非常 <BR>&nbsp;&nbsp;&nbsp;&nbsp;精炼, 适用于中小型网站, 建立自己的论坛系统. 这篇文章我们就一起来看一看 <BR>&nbsp;&nbsp;&nbsp;&nbsp;Jive 中所应用的设计模式(Design Pattern). <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;正文: <BR>&nbsp;&nbsp;&nbsp;&nbsp;    关于设计模式, 这篇文章并不详细解释, 只是结合 Jive 来看看设计模式在一 <BR>&nbsp;&nbsp;&nbsp;&nbsp;个实际项目中的应用及其整体的设计思想. 所以在读这篇文章前, 假设您对设计模 <BR>&nbsp;&nbsp;&nbsp;&nbsp;式有一个感性的认识, 对其具体应用以及实现方法有些疑问, 并渴望了解其思想, <BR>&nbsp;&nbsp;&nbsp;&nbsp;并使用过 Jive. 本文将一同来探讨这个问题. 为什么选择 Jive 而不是选择一个新的 <BR>&nbsp;&nbsp;&nbsp;&nbsp;例子重新开始呢? 有以下两个原因: 1, 我们很多人对 bbs 这样一个事物比较熟悉, <BR>&nbsp;&nbsp;&nbsp;&nbsp;很清楚 bbs 所具有的一些基本功能, 如果自己作为设计者来设计这样一个 web bbs, <BR>&nbsp;&nbsp;&nbsp;&nbsp;会怎么想, 再看看别人是怎么实现的, 有对比才能明白自己设计上的缺点, 看到别人 <BR>&nbsp;&nbsp;&nbsp;&nbsp;的优点才能更快地进步. 2, Jive 并不是非常地复杂, 并且包括了一个完整的实现方 <BR>&nbsp;&nbsp;&nbsp;&nbsp;案, 从底层到高层, 从后端到前端, 都有很好的文档, 这些都能更好地帮助我们理解 <BR>&nbsp;&nbsp;&nbsp;&nbsp;它. <BR>&nbsp;&nbsp;&nbsp;&nbsp;    这里我们所用的 Jive 的版本采用其开发者作为正式发布的 1.0 版, 其最新版 <BR>&nbsp;&nbsp;&nbsp;&nbsp;为 1.21, 对其结构作了少量改动, 主要增加了 jsp tag 的支持, 这种技术不属于我 <BR>&nbsp;&nbsp;&nbsp;&nbsp;们的讨论范围, 以后有机会可以共同学习. <BR>&nbsp;&nbsp;&nbsp;&nbsp;    Jive 中所使用的设计模式, 对设计模式的三种类型 -- 创建型, 结构型, <BR>&nbsp;&nbsp;&nbsp;&nbsp;行为型 -- 都有涉及, 这样也能比较全面地了解设计模式. 我们先来自己设计一下, <BR>&nbsp;&nbsp;&nbsp;&nbsp;运用面向对象的思想, 可以很容易知道, 整个系统主要需要这几个对象: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;1, Forum      --    一个讨论区, 也就是一个版面. <BR>&nbsp;&nbsp;&nbsp;&nbsp;2, Thread     --    一条线索, 也就是有关同一个主题的所有的回文. <BR>&nbsp;&nbsp;&nbsp;&nbsp;3, Message    --    一条消息, 也就是一个用户发的一篇贴子. <BR>&nbsp;&nbsp;&nbsp;&nbsp;                    (以后我们就用&quot;贴子&quot;这个叫法) <BR>&nbsp;&nbsp;&nbsp;&nbsp;4, User       --    一个用户, 也就是讨论区的使用者. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    好了, 我们需要的东西都在了, 它们之间的关系十分复杂, 怎么把它们组织地 <BR>&nbsp;&nbsp;&nbsp;&nbsp;很符合我们的思路又能容易扩充呢? 我想大家都有自己的想法了, &quot;我能这么这么做&quot;, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&quot;我可以这样这样设计&quot;, 我们一起来看看 Jive 是怎么做的. 下面是其整体结构: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;                    |~~~~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                    |   Skin 设计者    | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                    |__________________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            | | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            | |  使用 <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            \ / <BR>&nbsp;&nbsp;&nbsp;&nbsp;                    |~~~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                    | 各种对象的接口  | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                    |_________________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            | | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            | |  被实现 <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            \ / <BR>&nbsp;&nbsp;&nbsp;&nbsp;                       |~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                       |  权限控制  | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                       |____________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            | | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            | |  控制 <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            \ / <BR>&nbsp;&nbsp;&nbsp;&nbsp;                |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                | 对数据库进行操作的各种对象  | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                |_____________________________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            | | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            | |  取连接 <BR>&nbsp;&nbsp;&nbsp;&nbsp;                            \ / <BR>&nbsp;&nbsp;&nbsp;&nbsp;                     |~~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                     |  数据库连接池  | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                     |________________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;             (图 1) <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    下面是其类的大概的继承情况: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;                 |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                 |          Interface  A             | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                 |___________________________________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                         |                    | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                         |    implements      | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                         |                    | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                 |~~~~~~~~~~~~~~~~~|          | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                 |   Proxy   A     |          | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                 |_________________|          | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                              | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                              | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                     |~~~~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                     |    Database A    | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                     |__________________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                  (图 2) <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    好了看到这里, 如果您对设计模式有了解的话, 从上面所写的伪名字中, 可以 <BR>&nbsp;&nbsp;&nbsp;&nbsp;看到一些熟悉的东西. 请让我做一些解释. 上面的图表示的是类的继承关系, A 代 <BR>&nbsp;&nbsp;&nbsp;&nbsp;表上面所提到的四种对象, Interface A 表示名为 A 的一个接口, 相信大家对接口 <BR>&nbsp;&nbsp;&nbsp;&nbsp;都不陌生, 接口在 java 中有着重要的作用. Proxy A 表示一个名为 ProxyA 的类, <BR>&nbsp;&nbsp;&nbsp;&nbsp;实现 A 接口. Database A 表示名为 DbA 的一个类, 实现 A 接口. 但设计模式并 <BR>&nbsp;&nbsp;&nbsp;&nbsp;没有从中体现出来,设计模式所要表现的是怎么样更好地组织对象之间的逻辑关系, <BR>&nbsp;&nbsp;&nbsp;&nbsp;怎么样才能更好地扩充现有的东西而不需要作很大的改动, 而不仅仅是类的继承. <BR>&nbsp;&nbsp;&nbsp;&nbsp;    还有一点需要说明的是, 设计模式总的原则是针对接口编程, 而不关心其具体 <BR>&nbsp;&nbsp;&nbsp;&nbsp;实现, 这样搭起来的是一个架子, 还需要作许多具体的编程才能真正的完成系统. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    下面, 我们就分别从设计模式的三种类型来看 Jive 使用了其中的哪些. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;一, 创建型模式 (Creational Patterns) <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;   这一类型的设计模式, 所要表现的是对象的创建过程及和用户所使用的对象之间 <BR>&nbsp;&nbsp;&nbsp;&nbsp;的关系. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;1,  Jive 中在 Forum 之上又加了一层, ForumFactory, 来实现对 Forum 的一些控 <BR>&nbsp;&nbsp;&nbsp;&nbsp;制, 比如创建新的讨论区, 删除一个讨论区等等. 这个类实际上是整个系统的入口, <BR>&nbsp;&nbsp;&nbsp;&nbsp;jsp 中所做的一切都要从得到这个类的一个实例开始.  它的一些子类和它的关系如 <BR>&nbsp;&nbsp;&nbsp;&nbsp;下: <BR>&nbsp;&nbsp;&nbsp;&nbsp;                        |~~~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                        |  ForumFactory   | abstract <BR>&nbsp;&nbsp;&nbsp;&nbsp;                        |_________________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                           |           | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                           |  extends  | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                           |           | <BR>&nbsp;&nbsp;&nbsp;&nbsp;              |~~~~~~~~~~~~~~~~~~~~| |~~~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;              | ForumFactoryProxy  | |  DbForumFactory | <BR>&nbsp;&nbsp;&nbsp;&nbsp;              |____________________| |_________________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;                (图 3) <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    我们来看一下得到一个 ForumFactory 实例的过程: <BR>&nbsp;&nbsp;&nbsp;&nbsp;    FactoryForum factory = ForumFactory.getInstance(aAuthorization); <BR>&nbsp;&nbsp;&nbsp;&nbsp;就得到了 ForumFactory 的实例, 这个最终用户(skin 设计人员)所使用的是它的子 <BR>&nbsp;&nbsp;&nbsp;&nbsp;类 ForumFactoryProxy 的实例, (其中涉及到另一个模式, 后面将会提到), 但实际 <BR>&nbsp;&nbsp;&nbsp;&nbsp;上真正在做实际工作的是 DbForumFactory 或者是一个指定的类的实例, 相关代码如 <BR>&nbsp;&nbsp;&nbsp;&nbsp;下: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;From ForumFactory.java <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    private static String className = &quot;com.coolservlets.forum.database.DbForumFaactory&quot;; <BR>&nbsp;&nbsp;&nbsp;&nbsp;    // 系统缺省的 ForumFactory 的一个具体的子类. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    private static ForumFactory factory = null; <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;ForumFactory.getInstance() <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    String classNameProp = PropertyManager.getProperty(&quot;ForumFactory.className&quot;) <BR>&nbsp;&nbsp;&nbsp;&nbsp;    // 可以通过配制文件来选择其他的具体的子类. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    if (classNameProp != null) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;          className = classNameProp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;    } <BR>&nbsp;&nbsp;&nbsp;&nbsp;    try { <BR>&nbsp;&nbsp;&nbsp;&nbsp;       //Load the class and create an instance. <BR>&nbsp;&nbsp;&nbsp;&nbsp;       Class c = Class.forName(className); <BR>&nbsp;&nbsp;&nbsp;&nbsp;       factory = (ForumFactory)c.newInstance(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;    } <BR>&nbsp;&nbsp;&nbsp;&nbsp;    catch (Exception e) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;       System.err.println(&quot;Failed to load ForumFactory class &quot; <BR>&nbsp;&nbsp;&nbsp;&nbsp;            + className + &quot;. Jive cannot function normally.&quot;); <BR>&nbsp;&nbsp;&nbsp;&nbsp;       e.printStackTrace(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;       return null; <BR>&nbsp;&nbsp;&nbsp;&nbsp;    } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    它使用的是 Abstract Factory (抽象工厂)设计模式. 给用户一个使用一系列相关对象 <BR>&nbsp;&nbsp;&nbsp;&nbsp;的接口, 而不需要指定其具体的类. 也就是说, skin 设计人员写的 jsp 中不应该出现 <BR>&nbsp;&nbsp;&nbsp;&nbsp;new DbForumFactory 之类的语句. Jive 中 AuthorizationFactory 也使用了这个设计模式 <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;2,  Jive 中有一个很不错的想法, 就是对贴子的内容和标题可以进行过滤, 比如过滤 html <BR>&nbsp;&nbsp;&nbsp;&nbsp;过滤一些脏话, 对附加的代码进行高亮显示, 转换链接等等. 如果我要实现这样的功能, 有有?<BR>&nbsp;&nbsp;&nbsp;&nbsp;下几种方法: (1) 在 Message.getBody() getSubject() 中进行控制, (2) 在 Thread 中得得?<BR>&nbsp;&nbsp;&nbsp;&nbsp;Message 后进行转换. 还需要考虑的问题是这些过滤的操作必须能够很方便地添加删除. 不不?<BR>&nbsp;&nbsp;&nbsp;&nbsp;的目标所用的设计方法是不一样的, Jive 是这样做的: 以版面为主, 把这些过滤器看作是鞍婷?<BR>&nbsp;&nbsp;&nbsp;&nbsp;的属性, 过滤器只对其所属的版面有效, 所以 Jive 中使用了 (2), 这并不是主要的, 重要要?<BR>&nbsp;&nbsp;&nbsp;&nbsp;是这些过滤器该怎么来组织. 我们先来看看需求: 能动态添加删除, 功能类似, 贴子的显示示?<BR>&nbsp;&nbsp;&nbsp;&nbsp;其具体怎么创建, 如何表现无关. 似乎目标只有一个 -- Prototype(原型) 设计模式. 看看 <BR>&nbsp;&nbsp;&nbsp;&nbsp;Jive 的具体实现. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                  |~~~~~~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                  |    ForumMessage    | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                  |____________________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                           | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                           | implements <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                           | <BR>&nbsp;&nbsp;&nbsp;&nbsp;   |~~~~~~~~~~~~~~~~| Prototype   |~~~~~~~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;   |  ForumThread   |-----------&gt; |  ForumMessageFilter | <BR>&nbsp;&nbsp;&nbsp;&nbsp;   |----------------|             |---------------------| <BR>&nbsp;&nbsp;&nbsp;&nbsp;   | getMessage() o |             |     clone()         | <BR>&nbsp;&nbsp;&nbsp;&nbsp;   |______________|_|             |_____________________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                  |                 /             | <BR>&nbsp;&nbsp;&nbsp;&nbsp;   |~~~~~~~~~~~~~~~~|      |~~~~~~~~~~~~~~~| |~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;   | aFilter.clone()|      | HighlightCode | |    HTML     | <BR>&nbsp;&nbsp;&nbsp;&nbsp;   |________________|      |---------------| |-------------| ...... <BR>&nbsp;&nbsp;&nbsp;&nbsp;                           |  clone()  o   | |   clone() o | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                           |___________|___| |___________|_| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                       |                 | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                           |~~~~~~~~~~~~~~~| |~~~~~~~~~~~~~~~| <BR>&nbsp;&nbsp;&nbsp;&nbsp;                           |  返回一个实例 | |  返回一个实例 | <BR>&nbsp;&nbsp;&nbsp;&nbsp;                           |_______________| |_______________| <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;                           (图 4) <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    上图作了少许的简化. Jive 用的时候是把这些过滤器存在数据库中, 可以动态设置 <BR>&nbsp;&nbsp;&nbsp;&nbsp;属性, 比较方便. 来看一些代码: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;From: DbForumThread.java <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    public ForumMessage getMessage(int messageID) <BR>&nbsp;&nbsp;&nbsp;&nbsp;            throws ForumMessageNotFoundException <BR>&nbsp;&nbsp;&nbsp;&nbsp;    { <BR>&nbsp;&nbsp;&nbsp;&nbsp;        ForumMessage message = factory.getMessage(messageID); <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        //Apply filters to message. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        message = forum.applyFilters(message); <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        //通过 Forum 来实现, 因为 Filter 是 Forum 的属性, <BR>&nbsp;&nbsp;&nbsp;&nbsp;        //Thread 只能通过 Forum 的接口来访问. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        return message; <BR>&nbsp;&nbsp;&nbsp;&nbsp;    } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;From: DbForum.java <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    public ForumMessage applyFilters(ForumMessage message) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        for (int i=0; i &lt; filters.length; i++) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;            message = filters[i].clone(message); <BR>&nbsp;&nbsp;&nbsp;&nbsp;        } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        //可能会有多个过滤器, 依次来操作. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        return message; <BR>&nbsp;&nbsp;&nbsp;&nbsp;    } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;二, 结构型模式 (Structural Patterns) <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    这一类的模式关心类和对象之间怎么组织起来形成大的结构. 主要使用继承来 <BR>&nbsp;&nbsp;&nbsp;&nbsp;组织接口或实现. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;1, 我们再接着思考一下, 用户之间应该有所区别, 有 Guest 用户, 可以让他来看一 <BR>&nbsp;&nbsp;&nbsp;&nbsp;看, 但不能发贴子, 正式用户可以发贴子, 查看自己的个人信息, 版面管理者(称之为 <BR>&nbsp;&nbsp;&nbsp;&nbsp;版主)应该可以控制贴子, 比如加上适当的标记, 收入精华区, 甚至删除贴子等等, 而 <BR>&nbsp;&nbsp;&nbsp;&nbsp;系统管理者应该具有更高的权限, 比如开新的版面, 删除用户等操作. 怎么实现这个 <BR>&nbsp;&nbsp;&nbsp;&nbsp;功能呢?  我们知道, Jive 中所有实际的操作都是由 database 目录下的类所实现的, <BR>&nbsp;&nbsp;&nbsp;&nbsp;如果把权限控制加到数据库这一层的话, 这一层不但臃肿, 而且写好以后, 如果要改 <BR>&nbsp;&nbsp;&nbsp;&nbsp;的话, 需要修改的地方很多, 还容易出错, 所以可以在这一层之上再加一层, 单独进 <BR>&nbsp;&nbsp;&nbsp;&nbsp;行权限控制. 这样就把 &quot;该不该做&quot; 和 &quot;怎么做&quot; 分割开来, 利于以后修改. 其实这 <BR>&nbsp;&nbsp;&nbsp;&nbsp;也是面象对象的一个思想 -- 一个对象不要负担太多的责任. 这种方法在设计模式中 <BR>&nbsp;&nbsp;&nbsp;&nbsp;称为 Proxy (代理) 模式. 好比生产厂家和代理商的关系. (当然, 在 Jive 中这个比 <BR>&nbsp;&nbsp;&nbsp;&nbsp;喻不太合适). Proxy 的目的就是给另一个对象提供一个代理来控制对它的访问. <BR>&nbsp;&nbsp;&nbsp;&nbsp;    Proxy 模式一直贯穿 Jive 的始终, 几乎所涉及到的对象都需要. 其结构如图 2 <BR>&nbsp;&nbsp;&nbsp;&nbsp;所示. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;  从前面已经知道, ForumFactory 是整个系统的开始. 再来看看 ForumFactory <BR>&nbsp;&nbsp;&nbsp;&nbsp;的代码: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;From ForumFactory.java <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;ForumFactory.getInstance() 的最后: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        ForumFactoryProxy proxy = new ForumFactoryProxy( <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                    factory, <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                    authorization, <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                    factory.getPermissions(authorization) <BR>&nbsp;&nbsp;&nbsp;&nbsp;                                  ); <BR>&nbsp;&nbsp;&nbsp;&nbsp;        return proxy; <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    前面得到的 factory 是 DbForumFactory 的实例, 这里把这个实例又用 <BR>&nbsp;&nbsp;&nbsp;&nbsp;ForumFactoryProxy 封装起来. 最后返回一个 ForumFactoryProxy 的实例. 也就是 <BR>&nbsp;&nbsp;&nbsp;&nbsp;说 jsp skin 的设计者所用的 ForumFactory 实际上是 ForumFactoryProxy. 接着看 <BR>&nbsp;&nbsp;&nbsp;&nbsp;看 ForumFactoryProxy 里发生了什么事, 那一个小片段做例子: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    其构造函数中的 Factory 就是一个 DbForumFactory 的实例, 由它来做具体的 <BR>&nbsp;&nbsp;&nbsp;&nbsp;工作. Authorization 可以认为是一个认证过的当前用户(指实际的浏览器的使用者), <BR>&nbsp;&nbsp;&nbsp;&nbsp;ForumPermissions 可以认为是当前用户的权限. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    public Forum createForum(String name, String description) <BR>&nbsp;&nbsp;&nbsp;&nbsp;            throws UnauthorizedException <BR>&nbsp;&nbsp;&nbsp;&nbsp;    { <BR>&nbsp;&nbsp;&nbsp;&nbsp;        //这里就对权限进行了检查, 具有系统管理员权限, 则可以进行相应的操作, <BR>&nbsp;&nbsp;&nbsp;&nbsp;        //否则抛出异常. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;            Forum newForum = factory.createForum(name, description); <BR>&nbsp;&nbsp;&nbsp;&nbsp;            return new ForumProxy(newForum, authorization, permissions); <BR>&nbsp;&nbsp;&nbsp;&nbsp;        } <BR>&nbsp;&nbsp;&nbsp;&nbsp;        else { <BR>&nbsp;&nbsp;&nbsp;&nbsp;            throw new UnauthorizedException(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;        } <BR>&nbsp;&nbsp;&nbsp;&nbsp;    } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    public Forum getForum(int ID) throws ForumNotFoundException, <BR>&nbsp;&nbsp;&nbsp;&nbsp;            UnauthorizedException <BR>&nbsp;&nbsp;&nbsp;&nbsp;    { <BR>&nbsp;&nbsp;&nbsp;&nbsp;        Forum forum = factory.getForum(ID); <BR>&nbsp;&nbsp;&nbsp;&nbsp;        ForumPermissions forumPermissions = forum.getPermissions(authorization); <BR>&nbsp;&nbsp;&nbsp;&nbsp;        //Create a new permissions object with the combination of the <BR>&nbsp;&nbsp;&nbsp;&nbsp;        //permissions of this object and tempPermissions. <BR>&nbsp;&nbsp;&nbsp;&nbsp;        ForumPermissions newPermissions = <BR>&nbsp;&nbsp;&nbsp;&nbsp;                new ForumPermissions(permissions, forumPermissions); <BR>&nbsp;&nbsp;&nbsp;&nbsp;        //Check and see if the user has READ permissions. If not, throw an <BR>&nbsp;&nbsp;&nbsp;&nbsp;        //an UnauthorizedException. <BR>&nbsp;&nbsp;&nbsp;&nbsp;        if (!( <BR>&nbsp;&nbsp;&nbsp;&nbsp;            newPermissions.get(ForumPermissions.READ) || <BR>&nbsp;&nbsp;&nbsp;&nbsp;            newPermissions.get(ForumPermissions.FORUM_ADMIN) || <BR>&nbsp;&nbsp;&nbsp;&nbsp;            newPermissions.get(ForumPermissions.SYSTEM_ADMIN) <BR>&nbsp;&nbsp;&nbsp;&nbsp;            )) <BR>&nbsp;&nbsp;&nbsp;&nbsp;        { <BR>&nbsp;&nbsp;&nbsp;&nbsp;            throw new UnauthorizedException(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;        } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        // 同上所述. <BR>&nbsp;&nbsp;&nbsp;&nbsp;        // 这里得到的 forum, 是一个 DbForum 的实例, 跟 ForumFactory 一样, <BR>&nbsp;&nbsp;&nbsp;&nbsp;        // 返回一个封装过的代理对象, 来对 forum 进行权限控制. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;        return new ForumProxy(forum, authorization, newPermissions); <BR>&nbsp;&nbsp;&nbsp;&nbsp;    } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    其他所有的对象都是类似的. 这里就不再赘述. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;三, 行为型模式 (Behavioral Patterns) <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    这一类的模式关心的是算法以及对象之间的任务分配. 它所描述的不仅仅是对象或类 <BR>&nbsp;&nbsp;&nbsp;&nbsp;的设计模式, 还有它们之间的通讯模式. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;1,  下来看看怎么从一个 Forum 中得到一些 Thread. 当然这里要涉及到数据库, 我们 <BR>&nbsp;&nbsp;&nbsp;&nbsp;先设计一个最简单的数据库表, 表名: thread, 字段 ThreadID int, ForumID int, 其 <BR>&nbsp;&nbsp;&nbsp;&nbsp;他内容我们不关心. 然后比如 Forum 中的一个方法, getThreads() 来返回当前 Forum <BR>&nbsp;&nbsp;&nbsp;&nbsp;所有的 Thread. 然后就可以这样做: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;           public ForumThread[] getThreads() <BR>&nbsp;&nbsp;&nbsp;&nbsp;           { <BR>&nbsp;&nbsp;&nbsp;&nbsp;                1, 从数据库里面查询, 取出所有的 ThreadID, <BR>&nbsp;&nbsp;&nbsp;&nbsp;                2, 根据 ThreadID 构造 ForumThread 对象, <BR>&nbsp;&nbsp;&nbsp;&nbsp;                3, 返回一个数组. <BR>&nbsp;&nbsp;&nbsp;&nbsp;           } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    这样做最省事, 最简单了, 但好不好呢? 还得看需求, 比如我要求根据时间排序, <BR>&nbsp;&nbsp;&nbsp;&nbsp;就还得修改这个方法, 也就是说需要修改 DbForum 对象. 那为什么不把取 Thread 这个 <BR>&nbsp;&nbsp;&nbsp;&nbsp;操作单独拿出来呢? 这样的好处就是功能独立化, 使 DbForum 更简单, 符合前面我们所 <BR>&nbsp;&nbsp;&nbsp;&nbsp;提到的不要让对象负担太多的责任这个原则. 也许你会说, 如果要修改的话, 不是都得 <BR>&nbsp;&nbsp;&nbsp;&nbsp;修改吗? 放哪里是一样的, 这样没错, 但只限于很小的系统, 如果系统一大, 那么就可 <BR>&nbsp;&nbsp;&nbsp;&nbsp;能做 DbForum 中的简单查询和一些比较复杂的查询的程序员就不是一个人, 这样牵扯到 <BR>&nbsp;&nbsp;&nbsp;&nbsp;需要改动的地方较多, 但分离以后, 只需要一个人改很少的地方就可以完成. 回过头来 <BR>&nbsp;&nbsp;&nbsp;&nbsp;再看看问题, 这里要返回一群 ForumThread 对象, 而且它们之间还可能有一定的先后关 <BR>&nbsp;&nbsp;&nbsp;&nbsp;系, 怎么来做这个工作呢? Iterator 设计模式是一个合适的选择.  Iterator 模式提供 <BR>&nbsp;&nbsp;&nbsp;&nbsp;了一个连续访问一大群对象的方法, 而不需要知道它们的表现形式, 比如按什么方式排 <BR>&nbsp;&nbsp;&nbsp;&nbsp;序等等. <BR>&nbsp;&nbsp;&nbsp;&nbsp;    好了, 来看看 Jive 的具体实现. 由于 Java 本身已经有这样的接口, Iterator 接 <BR>&nbsp;&nbsp;&nbsp;&nbsp;口, 所以只要实现这个接口就可以了. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;From DbForum: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    public Iterator threads() { <BR>&nbsp;&nbsp;&nbsp;&nbsp;        return new DbForumIterator(this, factory); <BR>&nbsp;&nbsp;&nbsp;&nbsp;    } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;From DbForumIterator:  (做了改动) <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;public class DbForumIterator implements Iterator { <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;     public DbForumIterator(...) <BR>&nbsp;&nbsp;&nbsp;&nbsp;     { <BR>&nbsp;&nbsp;&nbsp;&nbsp;        ... <BR>&nbsp;&nbsp;&nbsp;&nbsp;     } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;     public boolean hasNext()       //是否还有元素 <BR>&nbsp;&nbsp;&nbsp;&nbsp;     { <BR>&nbsp;&nbsp;&nbsp;&nbsp;       ... <BR>&nbsp;&nbsp;&nbsp;&nbsp;     } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;     public Object next()      // 得到下一个元素 <BR>&nbsp;&nbsp;&nbsp;&nbsp;     { <BR>&nbsp;&nbsp;&nbsp;&nbsp;       ... <BR>&nbsp;&nbsp;&nbsp;&nbsp;     } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;     ... <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    那么 jsp 中可以这样访问: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    Iterator threads = aForum.threads(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;    while (threads.hasNext()) <BR>&nbsp;&nbsp;&nbsp;&nbsp;    { <BR>&nbsp;&nbsp;&nbsp;&nbsp;        ForumThread thread = (ForumThread)threads.next(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;        做一些操作. <BR>&nbsp;&nbsp;&nbsp;&nbsp;    } <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    从中可以看出, 通过使用 Iterator 把 Threads 的一些具体细节进行了封 <BR>&nbsp;&nbsp;&nbsp;&nbsp;装, 提供统一的接口. Jive 中这个设计模式也是用的非常多, 多个用户显示, <BR>&nbsp;&nbsp;&nbsp;&nbsp;多个版面显示, 多个线索, 多个贴子都需要由它来实现. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;小结: <BR>&nbsp;&nbsp;&nbsp;&nbsp;  <BR>&nbsp;&nbsp;&nbsp;&nbsp;    上面我们一起探讨了一下设计模式在 Jive 中的应用情况, 当然只是很简单, 很 <BR>&nbsp;&nbsp;&nbsp;&nbsp;肤浅, 也很片面, 不过总算能对设计模式有些认识. 实际上, 设计模式就是吸收许多前 <BR>&nbsp;&nbsp;&nbsp;&nbsp;人的经验, 把设计中一些重要的和重复出现的一些模式总结起来, 给出一个系统的命名, <BR>&nbsp;&nbsp;&nbsp;&nbsp;给出相应的解释和评价, 这个工作最先由 4 位软件大师所做, 他们合写了一本书 -- <BR>&nbsp;&nbsp;&nbsp;&nbsp;Design Pattern: Elements of Reusable Object-Oriented Software, 后来, 人们把 <BR>&nbsp;&nbsp;&nbsp;&nbsp;他们称为 GoF (Gang Of Four). <BR>&nbsp;&nbsp;&nbsp;&nbsp;    对于设计模式, 可能在我们的实际项目中自觉不自觉地在使用着, 比如 Factory <BR>&nbsp;&nbsp;&nbsp;&nbsp;Method 模式, Abstract 模式, Singleton 模式, Iterator 模式, 等等, 只是概念不是非?<BR>&nbsp;&nbsp;&nbsp;&nbsp;的明确, 设计可能还有不太合理的地方, 处于一种跟着感觉走的状态, 相信很多有经验 <BR>&nbsp;&nbsp;&nbsp;&nbsp;的设计者, 原来没有接触设计模式, 一旦接触以后, 会有一种恍然大悟的想法, 哈, 原 <BR>&nbsp;&nbsp;&nbsp;&nbsp;来是这么回事. 学习设计模式, 能很好地帮助我们设计, 在相同的问题, 相同的背景下, <BR>&nbsp;&nbsp;&nbsp;&nbsp;可以直接使用它, 有的时候不知道该选择哪种好, 就需对问题进行更深一层的分析, 进行 <BR>&nbsp;&nbsp;&nbsp;&nbsp;综合权衡, 对设计模式也要进行更深刻的理解, 才能得到好的结果, 这也是一个进步的 <BR>&nbsp;&nbsp;&nbsp;&nbsp;过程. <BR>&nbsp;&nbsp;&nbsp;&nbsp;    对于笔者来说, 刚刚接触设计模式, 有了一点粗浅的理解, 就冒昧写了这篇算是一 <BR>&nbsp;&nbsp;&nbsp;&nbsp;点心得的东西, 也是对自己的挑战, 中间犯的一些错误, 还请指正, 谢谢. <BR>&nbsp;&nbsp;&nbsp;&nbsp;  
<!-- 设计模式 --> 

        </td>
      </tr>
    </td>
  </tr>
</div>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -