﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-经验不在于年限，在于积累-随笔分类-设计模式</title><link>http://www.blogjava.net/hankchen/category/41469.html</link><description>欢迎来到陈新汉的个人博客</description><language>zh-cn</language><lastBuildDate>Sat, 19 Sep 2009 08:06:57 GMT</lastBuildDate><pubDate>Sat, 19 Sep 2009 08:06:57 GMT</pubDate><ttl>60</ttl><item><title>设计模式重构应用---Decorator模式</title><link>http://www.blogjava.net/hankchen/archive/2009/09/19/295648.html</link><dc:creator>陈新汉</dc:creator><author>陈新汉</author><pubDate>Sat, 19 Sep 2009 02:52:00 GMT</pubDate><guid>http://www.blogjava.net/hankchen/archive/2009/09/19/295648.html</guid><wfw:comment>http://www.blogjava.net/hankchen/comments/295648.html</wfw:comment><comments>http://www.blogjava.net/hankchen/archive/2009/09/19/295648.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hankchen/comments/commentRss/295648.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hankchen/services/trackbacks/295648.html</trackback:ping><description><![CDATA[<p>先简单介绍Decorator 模式（装饰模式）的内容和应用场景。
<p>装饰模式可以动态地给一个对象添加额外的职责。虽然，利用子类继承也可以实现这样的功能，但是装饰模式提供了一个更灵活的方式。<br />
因为继承会为类型引入的静态特质，使得这种扩展方式缺乏灵活性；<br />
并且随着子类的增多（扩展功能的增多），各种子类的组合（扩展功能的组合）会导致更多子类的膨胀。
<p>下面是标准Decorator 模式的UML结构图：
<p><a href="http://www.blogjava.net/images/blogjava_net/hankchen/WindowsLiveWriter/Decorator_ACFA/clip_image001_2.gif"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="366" alt="clip_image001" src="http://www.blogjava.net/images/blogjava_net/hankchen/WindowsLiveWriter/Decorator_ACFA/clip_image001_thumb.gif" width="441" border="0" /></a>
<p>[此图来自GOF 《设计模式》一书]
<p>现在结合我实际开发的一个例子谈谈这个模式的重构应用。
<p>还是那个SEO的项目，涉及群登录、群发帖、群回复等功能。为了客户调用简单和代码重用，<br />
设计的时候使用三个类来封装这些功能：SiteLogin、SitePost、SiteReply。每个站点的登录发帖回复功能都是调用这三个类实现的。
<p>刚开始设计时，只考虑一般HTTP协议的GET、POST请求，因为刚开始预研的时候，发现几个网站都是这样处理登录发帖回复的。
<p>随着后来，网站对象的不断增加，发现有下面的两个新需求：
<p>1. 有些站点采用Content-Type为multipart/form-data的方式提交，而不是默认的application/x-www-form-urlencoded方式。<br />
这两种方式，在httpclient 3.1 中处理方法是完全不同的（虽然4.0版本已经合并到一起了）。
<p>2. 有些站点是采用https的方式提交的（增加额外的功能）。
<p>3. 有些网站是这两种扩展需求都存在。
<p>当然，为了应付这样的变数，处理方法有很多，可以在代码中直接使用if语句来判断，也可以通过子类继承的方式增强这样的功能。<br />
使用if语句的方式，处理这样比较大的需求，是不优雅的。子类继承的方式，在需求组合时会出现子类数目爆炸式增长。<br />
通过使用Decorator 模式的重构，可以比较好的处理这类问题。
<p>最后设计的UML图如下（代码就不贴出来了）：
<p><a href="http://www.blogjava.net/images/blogjava_net/hankchen/WindowsLiveWriter/Decorator_ACFA/image_2.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="373" alt="image" src="http://www.blogjava.net/images/blogjava_net/hankchen/WindowsLiveWriter/Decorator_ACFA/image_thumb.png" width="535" border="0" /></a> </p>
友情提示：本博文章欢迎转载，但请注明出处：<a href='http://www.blogjava.net/hankchen' >陈新汉</a><img src ="http://www.blogjava.net/hankchen/aggbug/295648.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hankchen/" target="_blank">陈新汉</a> 2009-09-19 10:52 <a href="http://www.blogjava.net/hankchen/archive/2009/09/19/295648.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式重构应用---Template Method模式</title><link>http://www.blogjava.net/hankchen/archive/2009/09/18/295586.html</link><dc:creator>陈新汉</dc:creator><author>陈新汉</author><pubDate>Fri, 18 Sep 2009 08:22:00 GMT</pubDate><guid>http://www.blogjava.net/hankchen/archive/2009/09/18/295586.html</guid><wfw:comment>http://www.blogjava.net/hankchen/comments/295586.html</wfw:comment><comments>http://www.blogjava.net/hankchen/archive/2009/09/18/295586.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hankchen/comments/commentRss/295586.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hankchen/services/trackbacks/295586.html</trackback:ping><description><![CDATA[<p>先简单介绍Template Method模式的内容和应用场景。
<p>Template Method模式也叫模板方法模式，它把具有特定步骤算法中的某些必要的处理委让给抽象方法，通过子类继承对抽象方法的不同实现改变整个算法的行为。
<p>在作为抽象类的父类里，定义了一个具有固定算法并可以细分为多个步骤的模板方法（public），Template Method模式把这些可以被细分的可变步骤抽象为可以被子类重载的抽象方法（protected abstract），并通过在子类中的重载（重新定义），做到无需改变模板方法的算法步骤而可以重新定义该算法中的某些特定的步骤。
<p>Template Method模式的UML图如下：
<p><a href="http://www.blogjava.net/images/blogjava_net/hankchen/WindowsLiveWriter/TemplateMethod_FB6D/image_4.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="300" alt="image" src="http://www.blogjava.net/images/blogjava_net/hankchen/WindowsLiveWriter/TemplateMethod_FB6D/image_thumb_1.png" width="412" border="0" /></a>
<p>（注意：版权所有<a href='http://www.blogjava.net/hankchen'>hankchen</a>）
<p>Template Method模式一般应用在具有以下条件的应用中：
<p>1. 具有统一的操作步骤或操作过程
<p>2. 具有不同的操作细节
<p>3. 存在多个具有同样操作步骤的应用场景，但某些具体的操作细节却各不相同
<p>前一段时间，做了一个SEO的项目，需要到一些站点发帖回复增加外链的数目，期望提高搜索引擎的排名顺序。先不管这个项目的可行性和定位，现在只谈涉及的设计技术（模式与重构）。
<p>由于涉及多个站点（SitePost），并且站点的数目未来是不可预知的，这是开发中的一个变数。为了以后的可扩展性，下面是部分设计图：
<p><a href="http://www.blogjava.net/images/blogjava_net/hankchen/WindowsLiveWriter/TemplateMethod_FB6D/image_6.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="391" alt="image" src="http://www.blogjava.net/images/blogjava_net/hankchen/WindowsLiveWriter/TemplateMethod_FB6D/image_thumb_2.png" width="571" border="0" /></a> </p>
<p>（注意：版权所有<a href='http://www.blogjava.net/hankchen'>hankchen</a>）
<p>在接口ISitePost中定义了每个站点类必须具备群发帖、群回复的功能。</p>
<p>群发帖的接口：
<p>public boolean postAll(List&lt;Siteboards&gt; childboard, List&lt;Siteusers&gt; users, List&lt;Postinfos&gt; postinfos);
<p>群回复的接口：
<p>public boolean replyAll(List&lt;Articleinfos&gt;articles, List&lt;Siteusers&gt; users, List&lt;Postinfos&gt; postinfos, );
<p>现在以群发帖的接口为例，在抽象类AbstractSitePost中采用Template Method模式实现了这个接口。<br />
<br />
之所以，采用这个模板方法，是因为每个站点群发帖的过程，或者说步骤，是一样的：
<p>1. 首先的群登录（随机取代理IP）
<p>2. 然后是，针对站点的每个版面，随机用一个账号和一个帖子来提交。
<p>这些过程是相同的，不同的是：每个站点的发帖细节不同（即post方法不同）。
<p>具体发帖的post方法定义如下：
<p>Protected abstract String post(Siteusers userinfo,Siteboards sb,Postinfos postinfo);
<p>这样，具体到AAA站点（AAASitePost类），只需要实现自己的post方法即可。</p>
友情提示：本博文章欢迎转载，但请注明出处：<a href='http://www.blogjava.net/hankchen' >陈新汉</a><img src ="http://www.blogjava.net/hankchen/aggbug/295586.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hankchen/" target="_blank">陈新汉</a> 2009-09-18 16:22 <a href="http://www.blogjava.net/hankchen/archive/2009/09/18/295586.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>