java设计模式基于Jlivebanq总结.docx

上传人:b****1 文档编号:10192173 上传时间:2023-05-24 格式:DOCX 页数:30 大小:57.99KB
下载 相关 举报
java设计模式基于Jlivebanq总结.docx_第1页
第1页 / 共30页
java设计模式基于Jlivebanq总结.docx_第2页
第2页 / 共30页
java设计模式基于Jlivebanq总结.docx_第3页
第3页 / 共30页
java设计模式基于Jlivebanq总结.docx_第4页
第4页 / 共30页
java设计模式基于Jlivebanq总结.docx_第5页
第5页 / 共30页
java设计模式基于Jlivebanq总结.docx_第6页
第6页 / 共30页
java设计模式基于Jlivebanq总结.docx_第7页
第7页 / 共30页
java设计模式基于Jlivebanq总结.docx_第8页
第8页 / 共30页
java设计模式基于Jlivebanq总结.docx_第9页
第9页 / 共30页
java设计模式基于Jlivebanq总结.docx_第10页
第10页 / 共30页
java设计模式基于Jlivebanq总结.docx_第11页
第11页 / 共30页
java设计模式基于Jlivebanq总结.docx_第12页
第12页 / 共30页
java设计模式基于Jlivebanq总结.docx_第13页
第13页 / 共30页
java设计模式基于Jlivebanq总结.docx_第14页
第14页 / 共30页
java设计模式基于Jlivebanq总结.docx_第15页
第15页 / 共30页
java设计模式基于Jlivebanq总结.docx_第16页
第16页 / 共30页
java设计模式基于Jlivebanq总结.docx_第17页
第17页 / 共30页
java设计模式基于Jlivebanq总结.docx_第18页
第18页 / 共30页
java设计模式基于Jlivebanq总结.docx_第19页
第19页 / 共30页
java设计模式基于Jlivebanq总结.docx_第20页
第20页 / 共30页
亲,该文档总共30页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

java设计模式基于Jlivebanq总结.docx

《java设计模式基于Jlivebanq总结.docx》由会员分享,可在线阅读,更多相关《java设计模式基于Jlivebanq总结.docx(30页珍藏版)》请在冰点文库上搜索。

java设计模式基于Jlivebanq总结.docx

java设计模式基于Jlivebanq总结

2 Jive与设计模式

Jive论坛系统使用大量设计模式巧妙地实现了一系列功能。

因为设计模式的通用性和可理解性,将帮助更多人很快地理解Jive论坛源码,从而可以依据一种“协定”来动态地扩展它。

那么使用设计模式还有哪些好处?

2.1 设计模式

设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

毫无疑问,设计模式于己于他人于系统都是多赢的。

设计模式使代码编制真正工程化,设计模式是软件工程的基石。

GOF(设计模式作者简称)《设计模式》这本书第一次将设计模式提升到理论高度,并将之规范化,该书提出了23种基本设计模式。

自此,在可复用面向对象软件的发展过程中,新的大量的设计模式不断出现。

很多人都知道Java是完全面向对象的设计和编程语言,但是由于接受教育以及经验的原因,大多数程序员或设计人员都是从传统的过程语言转变而来,因此在思维习惯上要完全转变为面向对象的设计和开发方式是困难的,而学习设计模式可以更好地帮助和坚固这种转变。

凡是学习完成设计模式的人都有一种类似重生的感觉,这种重生可以从很多方面去解释。

换一种新的角度来看待和解决问题应该是一种比较贴切的解释,而这种新的思维角度培养属于基础培训,因此,设计模式是学习Java的必读基础课程之一。

由于设计模式概念比较抽象,对于初学者学习有一定的难度,因此结合Jive论坛系统学习设计模式将是一种很好的选择。

掌握了设计模式,将会帮助程序员或设计人员以更加可重用性、可伸缩性的眼光来开发应用系统,甚至开发通用的框架系统。

框架系统是构成一类特定软件可复用设计的一组相互协作的类,主要是对应用系统中反复重用部分的提炼,类似一种模板,这是一种结构性的模板。

框架通常定义了应用体系的整体结构、类和对象的关系等设计参数,以便于具体应用实现者能集中精力于应用本身的特定细节。

框架强调设计复用,而设计模式最小的可重用单位,因此框架不可避免地会反复使用到设计模式。

关于通用框架系统的设计开发将在以后章节中讨论。

其实Jive论坛本身也形成了一个基于Web结构的通用框架系统,因为它很多设计思想是可以重用的,例如设定一个总体入口,通过入口检查用户的访问控制权限,当然还有其他各方面的功能实现方式都是值得在其他系统中借鉴的,也正因为它以模式的形式表现出来,这种可重用性和可借鉴性就更强。

2.2 ForumFactory与工厂模式

工厂模式是GOF设计模式的主要常用模式,它主要是为创建对象提供了一种接口,工厂模式主要是封装了创建对象的细节过程,从而使得外界调用一个对象时,根本无需关心这个对象是如何产生的。

在GOF设计模式中,工厂模式分为工厂方法模式和抽象工厂模式。

两者主要区别是,工厂方法是创建一种产品接口下的产品对象,而抽象工厂模式是创建多种产品接口下的产品对象,非常类似Builder生成器模式。

在平时实践中,使用较多的基本是工厂方法模式。

以类SampleOne为例,要创建SampleOne的对象实例:

SampleOnesampleOne=newSampleOne();

如果Sample类有几个相近的类:

SampleTwo或SampleThree,那么创建它们的实例分别是:

SampleTwosampleTwo=newSampleTwo();

SampleThreesampleThree=newSampleThree();

其实这3个类都有一些共同的特征,如网上商店中销售书籍、玩具或者化妆品。

虽然它们是不同的具体产品,但是它们有一个共同特征,可以抽象为“商品”。

日常生活中很多东西都可以这样高度抽象成一种接口形式。

上面这3个类如果可以抽象为一个统一接口SampleIF,那么上面语句就可以成为:

SampleIFsampleOne=newSampleOne();

SampleIFsampleTwo=newSampleTwo();

SampleIFsampleThree=newSampleThree();

在实际情况中,有时并不需要同时生成3种对象,而是根据情况在3者之中选一个。

在这种情况下,需要使用工厂方法来完成了,创建一个叫SampleFactory的抽象类:

publicclassSampleFactory{

  publicabstractSampleIFcreator();

}

在这个抽象工厂类中有一个抽象方法creator,但是没有具体实现,而是延迟到它的子类中实现,创建子类SampleFactoryImp:

publicclassSampleFactoryImpextendsSampleFactory{

  publicSampleIFcreator(){

   //根据其他因素综合判断返回具体产品

   //假设应该返回SampleOne对象

      returnnewSampleOne();

}

}

在SampleFactoryImp中根据具体情况来选择返回SampleOne、SampleTwo或SampleThree。

所谓具体情况有很多种:

上下文其他过程计算结果;直接根据配置文件中配置。

上述工厂方法模式中涉及到一个抽象产品接口Sample,如果还有其他完全不同的产品接口,如Product等,一个子类SampleFactoryImp只能实现一套系列产品方案的生产,如果还需要另外一套系统产品方案,就可能需要另外一个子类SampleFactoryImpTwo来实现。

这样,多个产品系列、多个工厂方法就形成了抽象工厂模式。

前面已经讨论在Jive中设置了论坛统一入口,这个统一入口就是ForumFactory,以下是ForumFactory的主要代码:

publicabstractclassForumFactory{

  privatestaticObjectinitLock=newObject();

  privatestaticStringclassName="com.Yasna.forum.database.DbForumFactory";

  privatestaticForumFactoryfactory=null;

  

  publicstaticForumFactorygetInstance(Authorizationauthorization){

    if(authorization==null){

      returnnull;

    }

    //以下使用了Singleton单态模式,将在2.3节讨论

    if(factory==null){

      synchronized(initLock){

        if(factory==null){

            ...//从配置文件中获得当前className

          try{

              //动态装载类

              Classc=Class.forName(className);

              factory=(ForumFactory)c.newInstance();

          }

          catch(Exceptione){

              returnnull;

          }

        }

      }

    }

    //返回proxy.用来限制授权对forum的访问

    returnnewForumFactoryProxy(authorization,factory,factory.getPermissions(authorization));

  }

  //创键产品接口Forum的具体对象实例

  publicabstractForumcreateForum(Stringname,Stringdescription)

  throwsUnauthorizedException,ForumAlreadyExistsException;

  //创键产品接口ForumThread的具体对象实例

publicabstractForumThreadcreateThread(ForumMessagerootMessage)

throwsUnauthorizedException;

//创键产品接口ForumMessage的具体对象实例

 

 

   publicabstractForumMessagecreateMessage();

  ....

}

ForumFactory中提供了很多抽象方法如createForum、createThread和createMessage()等,它们是创建各自产品接口下的具体对象,这3个接口就是前面分析的基本业务对象Forum、ForumThread和ForumMessage,这些创建方法在ForumFactory中却不立即执行,而是推迟到ForumFactory子类中实现。

ForumFactory的子类实现是com.Yasna.forum.database.DbForumFactory,这是一种数据库实现方式。

即在DbForumFactory中分别实现了在数据库中createForum、createThread和createMessage()等3种方法,当然也提供了动态扩展到另外一套系列产品的生产方案的可能。

如果使用XML来实现,那么可以编制一个XmlForumFactory的具体工厂子类来分别实现3种创建方法。

因此,Jive论坛在统一入口处使用了抽象工厂模式来动态地创建论坛中所需要的各种产品,如图3-4所示。

图3-4 ForumFactory抽象工厂模式图

图3-4中,XmlForumFactory和DbForumFactory作为抽象工厂ForumFactory的两个具体实现,而Forum、ForumThread和ForumMessage分别作为3个系列抽象产品接口,依靠不同的工厂实现方式,会产生不同的产品对象。

从抽象工厂模式去理解Jive论坛统一入口处,可以一步到位掌握了几个类之间的大概关系。

因为使用了抽象工厂模式这种通用的设计模式,可以方便源码阅读者快速地掌握整个系统的结构和来龙去脉,图3-4这张图已经初步展示了Jive的主要框架结构。

细心的读者也许会发现,在上面ForumFactory有一个getInstance比较令人费解,这将在2.3节进行讨论。

2.3 统一入口与单态模式

在上面ForumFactory的getInstance方法使用单态(SingleTon)模式。

单态模式是保证一个类有且仅有一个对象实例,并提供一个访问它的全局访问点。

前面曾提到ForumFactory是Jive提供客户端访问数据库系统的统一入口。

为了保证所有的客户端请求都要经过这个ForumFactory,如果不使用单态模式,客户端下列调用语句表示生成了ForumFactory实例:

ForumFactoryfactory=newDbForumFactory();

客户端每发生一次请求都调用这条语句,这就会发生每次都生成不同factory对象实例,这显然不符合设计要求,因此必须使用单态模式。

一般在Java实现单态模式有几种选择,最常用而且安全的用法如下:

publicclassSingleton{

  privateSingleton(){}

  //在自己内部定义自己一个实例,是不是很奇怪

  //注意这是private,只供内部调用

  privatestaticSingletoninstance=newSingleton();

  //这里提供了一个供外部访问本class的静态方法,可以直接访问

  publicstaticSingletongetInstance(){

    returninstance;

  }

}

单态模式一共使用了两条语句实现:

第一条直接生成自己的对象,第二条提供一个方法供外部调用这个对象,同时最好将构造函数设置为private,以防止其他程序员直接使用newSingleton生成实例。

还有一种Java单态模式实现:

publicclassSingleton{

  privateSingleton(){}

  privatestaticSingletoninstance=null;

  publicstaticsynchronizedSingletongetInstance(){

    if(instance==null)

      instance=newSingleton()

    returninstance;

  }

在上面代码中,使用了判断语句。

如果instance为空,再进行实例化,这成为lazyinitialization。

注意getInstance()方法的synchronized,这个synchronized很重要。

如果没有synchronized,那么使用getInstance()在第一次被访问时有可能得到多个Singleton实例。

关于lazyinitialization的Singleton有很多涉及double-checkedlocking(DCL)的讨论,有兴趣者可以进一步研究。

一般认为第一种形式要更加安全些;但是后者可以用在类初始化时需要参数输入的情况下。

在Jive的ForumFactory中采取了后者lazyinitialization形式,这是为了能够动态配置指定ForumFactory的具体子类。

在getInstance中,从配置文件中获得当前工厂的具体实现,如果需要启动XmlForumFactory,就不必修改ForumFactory代码,直接在配置文件中指定className的名字为XmlForumFactory。

这样通过下列动态装载机制生成ForumFactory具体对象:

Classc=Class.forName(className);

factory=(ForumFactory)c.newInstance();

这是利用Java的反射机制,可以通过动态指定className的数值而达到生成对象的方式。

使用单态模式的目标是为了控制对象的创建,单态模式经常使用在控制资源的访问上。

例如数据库连接或Socket连接等。

单态模式可以控制在某个时刻只有一个线程访问资源。

由于Java中没有全局变量的概念,因此使用单态模式有时可以起到这种作用,当然需要注意是在一个JVM中。

2.4 访问控制与代理模式

仔细研究会发现,在ForumFactory的getInstance方法中最后的返回值有些奇怪。

按照单态模式的概念应该直接返回factory这个对象实例,但是却返回了ForumFactoryProxy的一个实例,这实际上改变了单态模式的初衷。

这样客户端每次通过调用ForumFactory的getInstance返回的就不是ForumFactory的惟一实例,而是新的对象。

之所以这样做是为了访问权限的控制,姑且不论这样做的优劣,先看看什么是代理模式。

代理模式是属于设计模式结构型模式中一种,它是实际访问对象的代理对象,或者影子对象,主要达到控制实际对象的访问。

这种控制的目的很多,例如提高性能等。

即远程代理模式,这种模式将在以后章节讨论。

其中一个主要的控制目的是控制客户端对实际对象的访问权限。

在Jive系统中,因为有角色权限的分别,对于Forum、ForumThread和FroumMessage的访问操作必须经过权限机制验证后才能进行。

以ForumFactoryProxy中的createForum方法为例,其实ForumFactoryProxy也是FroumFactory的一种工厂实现,它的createForum具体实现如下:

publicForumcreateForum(Stringname,Stringdescription)

           throwsUnauthorizedException,ForumAlreadyExistsException

   {

       if(permissions.get(ForumPermissions.SYSTEM_ADMIN)){

           ForumnewForum=factory.createForum(name,description);

           returnnewForumProxy(newForum,authorization,permissions);

       }

       else{

           thrownewUnauthorizedException();

       }

}

在这个方法中进行了权限验证,判断是否属于系统管理员。

如果是,将直接从DbForumFactory对象factory的方法createForum中获得一个新的Forum对象,然后再返回Forum的子类代理对象ForumProxy。

因为在Forum中也还有很多属性和操作方法,这些也需要进行权限验证。

ForumProxy和ForumFactoryProxy起到类似的作用。

Jive中有下列几个代理类:

∙         ForumFactoryProxy:

客户端和DbForumFactory之间的代理。

客户端访问DbForumFactory的任何方法都要先经过ForumFactoryProxy相应方法代理一次。

以下意思相同。

∙         ForumProxy:

客户端和DbForum之间的代理,研究Forum对象的每个方法,必须先看ForumProxy对象的方法。

∙         ForumMessageProxy:

客户端和DbForumMessage之间的代理。

∙         ForumThreadProxy:

客户端和DbForumThread之间的代理。

User和Group也有相应的代理类。

由以上分析看出,每个数据对象都有一个代理。

如果系统中数据对象非常多,依据这种一对一的代理关系,会有很多代理类,将使系统变得不是非常干净,因此可以使用动态代理来代替这所有的代理类,具体实现将在以后章节讨论。

2.5 批量分页查询与迭代模式

迭代(Iterator)模式是提供一种顺序访问某个集合各个元素的方法,确保不暴露该集合的内部表现。

迭代模式应用于对大量数据的访问,JavaCollectionAPI中Iterator就是迭代模式的一种实现。

在前面章节已经讨论过,用户查询大量数据,从数据库不应该直接返回ResultSet,应该是Collection。

但是有一个问题,如果这个数据很大,需要分页面显示。

如果一下子将所有页面要显示的数据都查询出来放在Collection,会影响性能。

而使用迭代模式则不必将全部集合都展现出来,只有遍历到某个元素时才会查询数据库获得这个元素的数据。

以论坛中显示帖子主题为例,在一个页面中不可能显示所有主题,只有分页面显示,如图3-5所示。

图3-5中一共分15页来显示所有论坛帖子,可以从显示Forum.jsp中发现下列语句可以完成上述结果:

ResultFilterfilter=newResultFilter(); //设置结果过滤器

  filter.setStartIndex(start);            //设置开始点

  filter.setNumResults(range);         //设置范围

  ForumThreadIteratorthreads=forum.threads(filter); //获得迭代器

  while(threads.hasNext){

      //逐个显示threads中帖子主题,输出图3-5中的每一行

  }

图3-5 分页显示所有帖子

上述代码中主要是从Forum的threads方法获得迭代器ForumThreadIterator的实例,依据前面代理模式中分析、研究Forum对象的方法,首先是看ForumProxy中对应方法,然后再看DbForum中对应方法的具体实现。

在ForumProxy中,threads方法如下:

publicForumThreadIteratorthreads(ResultFilterresultFilter){

    ForumThreadIteratoriterator=forum.threads(resultFilter);

     returnnewForumThreadIteratorProxy(iterator,authorization,permissions);

}

首先是调用了DbForum中具体的threads方法,再追踪到DbForum中看看,它的threads方法代码如下:

publicForumThreadIteratorthreads(ResultFilterresultFilter){

//按resultFilter设置范围要求获得SQL查询语句

  Stringquery=getThreadListSQL(resultFilter,false); 

  //获得resultFilter设置范围内的所有ThreadID集合

  long[]threadBlock=getThreadBlock(query.toString(),resultFilter.getStartIndex());

  //以下是计算查询区域的开始点和终点

  intstartIndex=resultFilter.getStartIndex();

  intendIndex;

  //Ifnumberofresultsissettoinifinite,setendIndextothetotal

 //numberofthreadsintheforum.

  if(resultFilter.getNumResults()==ResultFilter.NULL_INT){

    endIndex=(int)getThreadCount(resultFilter);

   }else{

    endIndex=resultFilter.getNumResults()+startIndex;

  }

  returnnewForumThreadBlockIterator(threadBlock,query.toString(),

              startIndex,endIndex,this.id,factory);

}

ResultFilter是一个查询结果类,可以对论坛主题Thread和帖子内容Message进行过滤或排序,这样就可以根据用户要求定制特殊的查询范围。

如查询某个用户去年在这个论坛发表的所有帖子,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2