﻿<?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-少年阿宾-随笔分类-PatternDesigns</title><link>http://blogjava.net/stevenjohn/category/51131.html</link><description>那些青春的岁月</description><language>zh-cn</language><lastBuildDate>Fri, 08 May 2015 16:28:40 GMT</lastBuildDate><pubDate>Fri, 08 May 2015 16:28:40 GMT</pubDate><ttl>60</ttl><item><title>设计模式--应用场景</title><link>http://www.blogjava.net/stevenjohn/archive/2015/05/08/424950.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Fri, 08 May 2015 09:32:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/05/08/424950.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/424950.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/05/08/424950.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/424950.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/424950.html</trackback:ping><description><![CDATA[<div><div>各种设计模式--应用场景：<br />装饰器模式：</div>1、类继承会导致类的膨胀，这时候装饰器就派上用场了<br /><div>责任链模式：</div><div>1、ifelse 用责任链来实现</div><div></div>状态模式：<br />1、ifelse<br />适配器模式：目的是在原来代码的基础上面，增加一些修饰的东西。<br />1、订单信息，比如增加了活动了之后，返回结果中要包含活动信息，在原来代码的基础上面给返回的Bean里面增加一些活动信息。<br />代理模式：<br /><div>&nbsp;比如吧，我有一个业务，同时要调用外部系统的http实现的接口和webservice实现的接口，可以做一个代理类， 代理webservice接口和http接口， 代理类帮我判断该用哪个， 我直接调用代理类就行了。代理类专门屏蔽后面的接口或者协议。</div><div></div><div></div><div></div><div></div>模板方法模式：<br />1、比如订单的下单还有退款操作，都需要同时判断使用的金额和红包。<br />2、支付的时候，调用不同的支付方式，都需要去做判断。<br />策略模式：<br /><br /><br /><br /><br /><br /><div></div><div>策略模式和装饰器模式区别：<br />策略模式偏向于对实现方法或策略的封装，调用者不需要考虑具体实现，只要指定使用的策略即可。  <br />装饰器模式一般用于需要对功能进行扩展的场合，每一种装饰都是一种扩展或增强。  <br /><br />看起来两个模式好像没有必然的联系，但是在实际使用过程中,发现了一个让我困惑的地方。 <br />先看一个典型的场景： <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  商场对客户打折，老客户8折，新客户9折，新客户购物满3000，打8.5折  <br />对这个基本场景，一般给的经典模式是策略模式，很多书也以这个作为策略模式的的经典案例。  <br />但是，如果我把每一种折扣看作是一种对原有价格的装饰，这个场景也是可以用装饰器模式实现的。  <br />两个模式都需要花费一些代码去判断策略或装饰器的类型，而且实现难度也旗鼓相当。  <br /><br />我用两种模式都实现了相同的功能，但是却没有发现明显的区别，不知道大家对这两个模式怎么看， <br />欢迎讨论。<br /><br /><br /><div>策略模式更倾向是N选1的模式，也即根据条件选择相应的算法，但各种算法是互斥的，比如：团体客户和个人客户的优惠政策必然是非此即彼的；  <br /><br />装饰模式是在主体逻辑的基础上的附加逻辑，比如，个人客户有的属于同城客户，支持送货上门。</div><br /><div>谢谢您的回复，如果按照策略模式，每一种打折方案是一种策略，而且只能选择一个，这是没有问题的。  <br />按照装饰模式，每一种折扣都是在购买金额上的附加，在没有折上折或者送货上门这些附加值的时候，我感觉装饰模式也是实用的，当然，当折上折和送货这种附加体现的时候，装饰起的模式就体现去来了。  <br /><br />所以，我感觉在当前描述的问题中，这两个模式应该都可以很恰当的实现需求，但是没感觉到本质的区别。  <br />于是就有些困惑了，看了您的总结，我感觉自己有点钻牛角了。 <br />如果这个场景新增附加需求，比如新增vip客户，那么策略模式就比较合适了。  <br />但是如果进行折上折或者送货上门这类附加需求，很明显装饰模式会更好一些了。 <br />看来具体的模式还得根据实际需求确定，不能死搬硬套。</div></div>尽管楼主可以使用两种模式实现自己说的场景，但是两者还是有本质的区别。<br /><br />策略模式，已经说的很清楚，  就不多说了。<br /><br />装饰模式是主题逻辑的基础上的加强。可以看看JAVA IO的设计。<br />就像楼上说的， 如果客户购买满5000，  不只可以享受7折优惠， 还可以送货上门。<br />这里有两项功能： 1） 7折优惠， 2）送货上门<br />如果使用策略模式，  我们势必把两项功能都写在一个策略的实现类里面。<br />假使现在有新的场景出现，就是老客户购买满3000，  也享受送货上门。（或者说这里面的还蕴藏一些其他的优惠，比如说返券等等）<br />难道我们又把这些功能添加到我们的策略里面，  这样代码就很生硬而且不容易修改。<br /><br />但是使用装饰模式就不一样，装饰模式能动态的给对象增加特有的功能。 比如说IO里面可以添加Buffer的功能。  同样在我们的场景里面，我们也可以将送货上门、返券等也动态的增强， new 送货上门（new 返券（））...., 这样子就很灵活了。<br /><br />策略实现可能类似： <br />do7折()； <br />do送货上门（)； <br />do返券（） <br /><br />装饰的实现可能了类似： <br />new 7折（  new 送货上门（new 返券（）））， 能随意组合； <br /><br />所有的优惠都享受上了， 看上去还是爽一点。&nbsp;<br /><br /><div>其实装饰模式， 还是更符合设计的一条原则： 少继承， 多组合&nbsp;</div></div><img src ="http://www.blogjava.net/stevenjohn/aggbug/424950.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-05-08 17:32 <a href="http://www.blogjava.net/stevenjohn/archive/2015/05/08/424950.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>状态模式和策略模式的比较 </title><link>http://www.blogjava.net/stevenjohn/archive/2015/04/21/424559.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Mon, 20 Apr 2015 18:43:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/04/21/424559.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/424559.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/04/21/424559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/424559.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/424559.html</trackback:ping><description><![CDATA[<div>状态模式(state pattern)和策略模式(strategy pattern)的实现方法非常类似，都是利用多态把一些操作分配到一组相关的简单的类中，因此很多人认为这两种模式实际上是相同的。然而</div><div></div><div>&#8226;在现实世界中，策略（如促销一种商品的策略）和状态（如同一个按钮来控制一个电梯的状态，又如手机界面中一个按钮来控制手机）是两种完全不同的思想。当我们对状态和策略进行建模时，这种差异会导致完全不同的问题。例如，对状态进行建模时，状态迁移是一个核心内容；然而，在选择策略时，迁移与此毫无关系。另外，策略模式允许一个客户选择或提供一种策略，而这种思想在状态模式中完全没有。&nbsp;</div><div>&#8226;一个策略是一个计划或方案，通过执行这个计划或方案，我们可以在给定的输入条件下达到一个特定的目标。策略是一组方案，他们可以相互替换；选择一个策略，获得策略的输出。策略模式用于随不同外部环境采取不同行为的场合。我们可以参考微软企业库底层Object Builder的创建对象的strategy实现方式。&nbsp;</div><div>&#8226;而状态模式不同，对一个状态特别重要的对象，通过状态机来建模一个对象的状态；状态模式处理的核心问题是状态的迁移，因为在对象存在很多状态情况下，对各个business flow，各个状态之间跳转和迁移过程都是及其复杂的。例如一个工作流，审批一个文件，存在新建、提交、已修改、HR部门审批中、老板审批中、HR审批失败、老板审批失败等状态，涉及多个角色交互，涉及很多事件，这种情况下用状态模式(状态机)来建模更加合适；把各个状态和相应的实现步骤封装成一组简单的继承自一个接口或抽象类的类，通过另外的一个Context来操作他们之间的自动状态变换，通过event来自动实现各个状态之间的跳转。在整个生命周期中存在一个状态的迁移曲线，这个迁移曲线对客户是透明的。我们可以参考微软最新的WWF 状态机工作流实现思想。&nbsp;</div><div>&#8226;在状态模式中，状态的变迁是由对象的内部条件决定，外界只需关心其接口，不必关心其状态对象的创建和转化；而策略模式里，采取何种策略由外部条件(C)决定。&nbsp;</div><div></div><img src ="http://www.blogjava.net/stevenjohn/aggbug/424559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-04-21 02:43 <a href="http://www.blogjava.net/stevenjohn/archive/2015/04/21/424559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>命令模式应用场景</title><link>http://www.blogjava.net/stevenjohn/archive/2015/03/30/423968.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Mon, 30 Mar 2015 13:23:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/03/30/423968.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/423968.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/03/30/423968.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/423968.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/423968.html</trackback:ping><description><![CDATA[基本概念：<br />&nbsp; &nbsp; &nbsp; 在软件系统中，&#8220;<strong jquery18009907489287714276="307">行为请求者</strong>&#8221;与&#8220;<strong jquery18009907489287714276="308">行为实现者</strong>&#8221;通常呈现一种&#8220;<strong jquery18009907489287714276="309">紧耦合</strong>&#8221;。但在<a href="http://baike.baidu.com/view/1222277.htm" target="_blank" jquery18009907489287714276="310">某些</a>场合，比如要对行为进行&#8220;记录、撤销/重做、事务&#8221;等处理，这种无法抵御变化的紧耦合是不合适的。在这种情况下，如何将&#8220;行为请求者&#8221;与&#8220;行为实现者&#8221;解耦？将<strong jquery18009907489287714276="311">一组行为抽象为对象</strong>，<strong jquery18009907489287714276="312">实现二者之间的松耦合</strong>。这就是<strong jquery18009907489287714276="313">命令模式（Command Pattern）。<br /></strong><br /><p>　 &nbsp; &nbsp;将来自客户端的请求传入一个对象，从而使你可用不同的请求对客户进行参数化。用于&#8220;行为请求者&#8221;与&#8220;行为实现者&#8221;解耦，可实现二者之间的松耦合，以便适应变化。分离变化与不变的因素。</p> <p>&nbsp;　　在面向对象的程序设计中，一个对象调用另一个对象，一般情况下的调用过程是：创建目标对象实例；设置调用参数；调用目标对象的方法。</p> <p>但在有些情况下有必要使用一个专门的类对这种调用过程加以封装，我们把这种专门的类称作command类。</p><br />特点<br />1)、command模式将调用操作的对象和实现该操作的对象解耦<br />2)、可以将多个命令装配成一个复合命令，复合命令是Composite模式的一个实例<br />3)、增加新的command很容易，无需改变已有的类<br /><br />应用场景：<br /><p>我们来分析下命令模式的使用场景吧，一般情况下如下几类场景中使用命令模式会达到很好的效果：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、当一个应用程序调用者与多个目标对象之间存在调用关系时，并且目标对象之间的操作很类似的时候。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、例如当一个目标对象内部的方法调用太复杂，或者内部的方法需要协作才能完成对象的某个特点操作时。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、有时候调用者调用目标对象后，需要回调一些方法。<br /><br /></p><div>&nbsp; &nbsp; &nbsp;命令模式是将行为请求者和行为实现者解耦合的方式。对命令进行封装，将命令和执行命令分隔开。请求的一方发出命令，要求执行某些操作，接受一方收到命令，执行这些操作的真正实现。请求的一方不必知道接受方的接口，以及如何被操作。&nbsp;</div><p><br /><span style="font-family: 'Courier New';">&nbsp; &nbsp; 命令模式可以应用到很多场景，比如实现do/undo功能、实现导航功能。</span><br /></p><div></div><img src ="http://www.blogjava.net/stevenjohn/aggbug/423968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-03-30 21:23 <a href="http://www.blogjava.net/stevenjohn/archive/2015/03/30/423968.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>装饰器模式 应用场景</title><link>http://www.blogjava.net/stevenjohn/archive/2015/03/27/423874.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Thu, 26 Mar 2015 16:11:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/03/27/423874.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/423874.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/03/27/423874.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/423874.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/423874.html</trackback:ping><description><![CDATA[<pre id="best-content-960868908"  mb-10"="" accuse="aContent" jquery110209564238208075206="86">装饰者模式（Decorator Pattern），是在不必改变原类文件和使用继承的情况下，动态的扩展一个对象的功能。它是通过创建一个包装对象，也就是装饰来包裹真实的对象。<br />使用装饰者模式的时候需要注意一下几点内容：<br />（1）装饰对象和真实对象有相同的接口。这样客户端对象就可以以和真实对象相同的方式和装饰对象交互。<br />（2）装饰对象包含一个真实对象的引用。<br />（3）装饰对象接受所有的来自客户端的请求，它把这些请求转发给真实的对象。<br />（4）装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时，不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中，通常是通过继承来实现对给定类的功能扩展。然而，装饰者模式，不需要子类可以在应用程序运行时，动态扩展功能，更加方便、灵活。<br /><br />适用装饰者模式场合：<br />1．当我们需要为某个现有的对象，动态的增加一个新的功能或职责时，可以考虑使用装饰模式。<br />2．当某个对象的职责经常发生变化或者经常需要动态的增加职责，避免为了适应这样的变化，而增加继承子类扩展的方式，因为这种方式会造成子类膨胀的速度过快，难以控制。<br /><br />推荐你一本设计模式方面的优秀书籍：郑阿奇 主编的《软件秘笈-设计模式那点事》。里面讲解很到位，实例通俗易懂，看了收获很大！<br /><br /></pre><img src ="http://www.blogjava.net/stevenjohn/aggbug/423874.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-03-27 00:11 <a href="http://www.blogjava.net/stevenjohn/archive/2015/03/27/423874.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式+抽象工厂模式)</title><link>http://www.blogjava.net/stevenjohn/archive/2015/03/22/423721.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sun, 22 Mar 2015 07:16:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/03/22/423721.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/423721.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/03/22/423721.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/423721.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/423721.html</trackback:ping><description><![CDATA[<p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;">在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 在这些情况,新对象的建立就是一个 &#8220;过程&#8221;，不仅是一个操作，像一部大机器中的一个齿轮传动。</p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;"><strong>模式的问题</strong>：你如何能轻松方便地构造对象实例，而不必关心构造对象实例的细节和复杂过程呢？</p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="color: #333333;"><strong>解决方案</strong>：建立一个工厂来创建对象</span></p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;"><strong>实现：</strong></p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 16px;"><strong>一、引言<br /></strong></span>&nbsp; &nbsp;&nbsp;1）还没有工厂时代：假如还没有工业革命，如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车，然后拿来用。<br />&nbsp;&nbsp;&nbsp; 2）简单工厂模式：后来出现工业革命。用户不用去创建宝马车。因为客户有一个工厂来帮他创建宝马.想要什么车，这个工厂就可以建。比如想要320i系列车。工厂就创建这个系列的车。即工厂可以创建产品。<br />&nbsp; &nbsp; 3）工厂方法模式时代：为了满足客户，宝马车系列越来越多，如320i，523i,30li等系列一个工厂无法创建所有的宝马系列。于是由单独分出来多个具体的工厂。每个具体工厂创建一种系列。即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象。你需要指定某个具体的工厂才能生产车出来。</p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;&nbsp; 4）抽象工厂模式时代：随着客户的要求越来越高，宝马车必须配置空调。于是这个工厂开始生产宝马车和需要的空调。</p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;最终是客户只要对宝马的销售员说：我要523i空调车，销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车.</p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;这就是工厂模式。</p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="color: #333333;"><strong>二、分类</strong>&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;工厂模式主要是为创建对象提供过渡接口，以便将创建对象的具体过程屏蔽隔离起来，达到提高灵活性的目的。&nbsp;<br />工厂模式可以分为三类：&nbsp;</span></p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="color: #333333;">1）简单工厂模式（Simple Factory）&nbsp;<br />2）工厂方法模式（Factory Method）&nbsp;<br />3）抽象工厂模式（Abstract Factory）&nbsp;</span></p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="color: #333333;">&nbsp;这三种模式从上到下逐步抽象，并且更具一般性。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GOF在《设计模式》一书中将工厂模式分为两类：工厂方法模式（Factory Method）与抽象工厂模式（Abstract Factory）。</span></p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="color: #333333;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将简单工厂模式（Simple Factory）看为工厂方法模式的一种特例，两者归为一类。&nbsp;</span></p><p style="color: #362e2b; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="color: #333333;"><span style="font-size: 16px;"><strong>三、区别&nbsp;<br /></strong></span>工厂方法模式：<br />一个抽象产品类，可以派生出多个具体产品类。 &nbsp;&nbsp;<br />一个抽象工厂类，可以派生出多个具体工厂类。 &nbsp;&nbsp;<br />每个具体工厂类只能创建一个具体产品类的实例。<br />抽象工厂模式：<br />多个抽象产品类，每个抽象产品类可以派生出多个具体产品类。 &nbsp;&nbsp;<br />一个抽象工厂类，可以派生出多个具体工厂类。 &nbsp;&nbsp;<br />每个具体工厂类可以创建多个具体产品类的实例。 &nbsp;&nbsp;<br />区别：<br />工厂方法模式只有一个抽象产品类，而抽象工厂模式有多个。 &nbsp;&nbsp;<br />工厂方法模式的具体工厂类只能创建一个具体产品类的实例，而抽象工厂模式可以创建多个。<br />两者皆可。&nbsp;<br /><br /><br /><br /></span></p><div>http://blog.csdn.net/jason0539/article/details/23020989</div><img src ="http://www.blogjava.net/stevenjohn/aggbug/423721.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-03-22 15:16 <a href="http://www.blogjava.net/stevenjohn/archive/2015/03/22/423721.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>适配器模式应用场景</title><link>http://www.blogjava.net/stevenjohn/archive/2015/03/18/423572.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Wed, 18 Mar 2015 05:59:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/03/18/423572.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/423572.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/03/18/423572.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/423572.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/423572.html</trackback:ping><description><![CDATA[1.希望复用一些现存的类，但是接口又与复用环境要求不一致。

<br />2.其实适配器模式有点无奈之举，在前期设计的时候，我们就不应该考虑适配器模式，而应该考虑通过重构统一接口。

<br /><br />想使用一个已存在的类，但是该类不符合接口需求；或者需要创建一个可重用的类，适配没有提供合适接口的其它类。
<br />
适配器模式主要解决的问题就是我们要调用的接口类型，无法满足我们新系统的使用需求，这时候，我们需要将旧系统的接口，通过适配器进行转配，达到支持新接口调用的目的。<br /><br />对于这样的要求，我们通过适配器就可以完成，当然如果有多个接口需要转配，那么我们就需要为每一个接口提供一个适配器去完成转换的工作。当然具体的调用过程，我们可以进行相应的封装。达到比较通用的方式去调用适配器，完成适配服务。<br />我们来看看适配的过程。

 我们根据上面的适配器的特点的介绍中，我们来分析下适配器模式的几类比较适用的使用场景：
<br />
       1、我们在使用第三方的类库，或者说第三方的API的时候，我们通过适配器转换来满足现有系统的使用需求。<br />

       2、我们的旧系统与新系统进行集成的时候，我们发现旧系统的数据无法满足新系统的需求，那么这个时候，我们可能需要适配器，完成调用需求。<br />

       3、我们在使用不同数据库之间进行数据同步。(我这里只是分析的是通过程序来说实现的时候的情况。还有其他的很多种方式[数据库同步])。


我们本节给出适配器模式的经典实现代码，我们这里结合项目中的查询服务来进行说明，旧系统中提供一个查询服务方法Query();但是我新系统定义底层的数据访问服务层

的时候，却是使用的GetList()方法，并且将之前的返回结果集合进行包装成泛型的形式来进行。<img src ="http://www.blogjava.net/stevenjohn/aggbug/423572.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-03-18 13:59 <a href="http://www.blogjava.net/stevenjohn/archive/2015/03/18/423572.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA 单例模式</title><link>http://www.blogjava.net/stevenjohn/archive/2015/03/17/423533.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Tue, 17 Mar 2015 07:15:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/03/17/423533.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/423533.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/03/17/423533.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/423533.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/423533.html</trackback:ping><description><![CDATA[<span style="color: #333333; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, STHeiti, sans-serif; line-height: 22.3999996185303px; background-color: #ffffff;">枚举单例模式：<br />关于单例模式的实现有很多种，网上也分析了如今实现单利模式最好用枚举，好处不外乎三点：</span><strong style="box-sizing: border-box; background-color: #ffffff;"><font color="#333333" face="Open Sans, Helvetica Neue, Helvetica, Arial, STHeiti, sans-serif"><span style="line-height: 22.3999996185303px;">1.线程安全 2.不会因为序列化而产生新实例 3.防止反射攻击</span></font><br /><strong style="color: #333333; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, STHeiti, sans-serif; line-height: 22.3999996185303px; box-sizing: border-box;">1.线程安全&nbsp;</strong><br /><span style="font-family: 'Microsoft YaHei', 宋体, 'Myriad Pro', Lato, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-weight: normal;">下面这段代码就是声明枚举实例的通常做法，它可能还包含实例变量和实例方法，但是为了简单起见，我并没有使用这些东西，仅仅需要小心的是如果你正在使用实例方法，那么你需要确保线程安全（如果它影响到其他对象的状态的话）。默认枚举实例的创建是线程安全的，但是在枚举中的其他任何方法由程序员自己负责。<br /></span><div>关于线程安全的保证，其实是通过类加载机制来保证的，我们看看INSTANCE的实例化时机，是在static块中，JVM加载类的过程显然是线程安全的。<br /><div>static {};</div><div>&nbsp; Code:</div><div>&nbsp; &nbsp;0: &nbsp; new &nbsp; &nbsp; #12; //class com/abin/lee/spring/util/Singleton$1</div><div>&nbsp; &nbsp;3: &nbsp; dup</div><div>&nbsp; &nbsp;4: &nbsp; ldc &nbsp; &nbsp; #14; //String INSTANCE</div><div>&nbsp; &nbsp;6: &nbsp; iconst_0</div><div>&nbsp; &nbsp;7: &nbsp; invokespecial &nbsp; #15; //Method com/abin/lee/spring/util/Singleton$1."&lt;init&gt;":(Ljava/lang/String;I)V</div><div>&nbsp; &nbsp;10: &nbsp;putstatic &nbsp; &nbsp; &nbsp; #19; //Field INSTANCE:Lcom/abin/lee/spring/util/Singleton;</div><div>&nbsp; &nbsp;13: &nbsp;iconst_1</div><div>&nbsp; &nbsp;14: &nbsp;anewarray &nbsp; &nbsp; &nbsp; #1; //class com/abin/lee/spring/util/Singleton</div><div>&nbsp; &nbsp;17: &nbsp;dup</div><div>&nbsp; &nbsp;18: &nbsp;iconst_0</div><div>&nbsp; &nbsp;19: &nbsp;getstatic &nbsp; &nbsp; &nbsp; #19; //Field INSTANCE:Lcom/abin/lee/spring/util/Singleton;</div><div>&nbsp; &nbsp;22: &nbsp;aastore</div><div>&nbsp; &nbsp;23: &nbsp;putstatic &nbsp; &nbsp; &nbsp; #21; //Field ENUM$VALUES:[Lcom/abin/lee/spring/util/Singleton;</div><div>&nbsp; &nbsp;26: &nbsp;return</div></div><div>线程安全，从反编译后的类源码中可以看出也是通过类加载机制保证的，应该是这样吧<br /><br /></div><strong style="color: #333333; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, STHeiti, sans-serif; line-height: 22.3999996185303px; box-sizing: border-box;">2.不会因为序列化而产生新实例<br /></strong><div style="color: #333333; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, STHeiti, sans-serif; line-height: 22.3999996185303px;">枚举自己处理序列化</div><span style="color: #000000; font-family: 'Microsoft YaHei', 宋体, 'Myriad Pro', Lato, 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 21px; font-weight: normal;">传统单例存在的另外一个问题是一旦你实现了序列化接口，那么它们不再保持单例了，因为readObject()方法一直返回一个新的对象就像java的构造方法一样，你可以通过使用readResolve()方法来避免此事发生，看下面的例子：</span><br /><div><span style="line-height: 22.399999618530273px;">//readResolve to prevent another instance of Singleton</span></div><div><span style="line-height: 22.399999618530273px;">&nbsp; &nbsp; private Object readResolve(){</span></div><div><span style="line-height: 22.399999618530273px;">&nbsp; &nbsp; &nbsp; &nbsp; return INSTANCE;</span></div><div><span style="line-height: 22.399999618530273px;">&nbsp; &nbsp; }</span></div><span style="font-family: 'Microsoft YaHei', 宋体, 'Myriad Pro', Lato, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-weight: normal;">这样甚至还可以更复杂，如果你的单例类维持了其他对象的状态的话，因此你需要使他们成为transient的对象。但是枚举单例，JVM对序列化有保证。<br /></span><div>优点：不仅能避免多线程同步问题，而且还能防止反序列化重新创建新的对象</div><div><br /><br /></div><strong style="color: #333333; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, STHeiti, sans-serif; line-height: 22.3999996185303px; box-sizing: border-box;">3.防止反射攻击<br />反射攻击，我有自己试着反射攻击了以下，不过报错了...看了下方的反编译类源码，明白了，因为单例类的修饰是abstract的，所以没法实例化。（<strong>解决</strong>）<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /></strong><br /><br /></strong>静态内部类：<br /><div>// Correct lazy initialization in Java&nbsp;</div><div>@ThreadSafe</div><div>class Foo {</div><div>&nbsp; &nbsp; private static class HelperHolder {</div><div>&nbsp; &nbsp; &nbsp; &nbsp;public static Helper helper = new Helper();</div><div>&nbsp; &nbsp; }</div><div>&nbsp;</div><div>&nbsp; &nbsp; public static Helper getHelper() {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return HelperHolder.helper;</div><div>&nbsp; &nbsp; }</div><div>}</div><div></div><p style="margin: 0in; font-family: 微软雅黑; font-size: 11.5pt;">它利用了内部静态类只有在被引用的时候才会被加载的规律。</p><p style="margin: 0in; font-size: 11.5pt;"><span style="font-family: 微软雅黑;">这样一来，一旦内部的</span><span style="font-family: Calibri;">HelperHolder</span><span style="font-family: 微软雅黑;">被引用了，它就会首先被</span><span style="font-family: Calibri;">JVM</span><span style="font-family: 微软雅黑;">加载，进行该类的静态域的初始化，从而使得</span><span style="font-family: Calibri;">Helper</span><span style="font-family: 微软雅黑;">这一单例类被初始化。它之所以是线程安全的，也是托了</span><span style="font-family: Calibri;">JVM</span><span style="font-family: 微软雅黑;">的福，因为</span><span style="font-family: Calibri;">JVM</span><span style="font-family: 微软雅黑;">对于类的加载这一过程是线程安全的。</span></p><img src ="http://www.blogjava.net/stevenjohn/aggbug/423533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-03-17 15:15 <a href="http://www.blogjava.net/stevenjohn/archive/2015/03/17/423533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>工厂方法模式与抽象工厂模式的区别</title><link>http://www.blogjava.net/stevenjohn/archive/2014/12/28/421902.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sun, 28 Dec 2014 14:06:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2014/12/28/421902.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/421902.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2014/12/28/421902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/421902.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/421902.html</trackback:ping><description><![CDATA[<pre id="best-content-192663341" accuse="aContent"  mb-10"="" style="margin-top: 0px; margin-bottom: 10px; padding: 0px; font-family: arial, 'courier new', courier, 宋体, monospace; white-space: pre-wrap; word-wrap: break-word; color: #333333; line-height: 24px; background-color: #f1fedd;">工厂方法模式：<br />一个抽象产品类，可以派生出多个具体产品类。   <br />一个抽象工厂类，可以派生出多个具体工厂类。   <br />每个具体工厂类只能创建一个具体产品类的实例。<br /><br />抽象工厂模式：<br />多个抽象产品类，每个抽象产品类可以派生出多个具体产品类。   <br />一个抽象工厂类，可以派生出多个具体工厂类。   <br />每个具体工厂类可以创建多个具体产品类的实例。   <br />    <br />区别：<br />工厂方法模式只有一个抽象产品类，而抽象工厂模式有多个。   <br />工厂方法模式的具体工厂类只能创建一个具体产品类的实例，而抽象工厂模式可以创建多个。<br /><br /><br /><br /><div>工厂方法模式： 一个抽象产品类，可以派生出多个具体产品类。 一个抽象工厂类，可以派生出多个具体工厂类。 每个具体工厂类只能创建一个具体产品类的实例。 抽象工厂模式： 多个抽象产品类，每个抽象产品类可以派生出多个具体产品类。 一个抽象工厂类，可以派生出多个具体工厂类。 每个具体工厂类可以创建多个具体产品类的实例。 区别： 工厂方法模式只有一个抽象产品类，而抽象工厂模式有多个。 工厂方法模式的具体工厂类只能创建一个具体产品类的实例，而抽象工厂模式可以创建多个。<br /><br /><br /><div>GOF《设计模式》写的很清楚，工厂方法是由子类自行决定实例化那个类，而抽象工厂是自己决定实例化哪个类。至于是组合还是继承还是实现接口都无所谓。根本区别在于是自己实例化还是子类实例化。</div></div></pre><img src ="http://www.blogjava.net/stevenjohn/aggbug/421902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2014-12-28 22:06 <a href="http://www.blogjava.net/stevenjohn/archive/2014/12/28/421902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java  单例模式</title><link>http://www.blogjava.net/stevenjohn/archive/2012/03/15/371964.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Thu, 15 Mar 2012 10:21:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/03/15/371964.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/371964.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/03/15/371964.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/371964.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/371964.html</trackback:ping><description><![CDATA[1、饿汉模式：<br />
<p>package com.abin.info.service;</p>
<p>public class Singleton {<br />&nbsp;private static Singleton singleton=new Singleton();<br />&nbsp;<br />&nbsp;private Singleton(){<br />&nbsp;&nbsp;<br />&nbsp;}<br />&nbsp;<br />&nbsp;public static Singleton getInstance(){<br />&nbsp;&nbsp;return singleton;<br />&nbsp;}</p>
<p>}<br /></p><br /><div><div>private static LazyMode lazyMode=null;</div><div><span style="white-space:pre">	</span>public static synchronized LazyMode getInstance(){</div><div><span style="white-space:pre">		</span>if(null==lazyMode){</div><div><span style="white-space:pre">			</span>lazyMode=new LazyMode();</div><div><span style="white-space:pre">		</span>}</div><div><span style="white-space:pre">		</span>return lazyMode;</div><div><span style="white-space:pre">	</span>}&nbsp;</div></div><br /><br />2、懒汉模式：<br />
<p>package com.abin.inter.she;</p>
<p>public class Singleton {<br />&nbsp;private static Singleton singleton=null;<br />&nbsp;private Singleton(){<br />&nbsp;&nbsp;<br />&nbsp;}<br />&nbsp;public static Singleton getInstance(){<br />&nbsp;&nbsp;if(null==singleton){<br />&nbsp;&nbsp;&nbsp;return new Singleton();<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;return singleton;<br />&nbsp;}</p>
<p>}<br /><br />懒汉模式的线程安全版本：<br /></p><div><div></div></div><div><div>package com.abin.lee.template.pattern;</div><div></div><div>public class LazyMode {</div><div><span style="white-space:pre">	</span>private static LazyMode lazyMode=null;</div><div><span style="white-space:pre">	</span>public static synchronized LazyMode getInstance(){</div><div><span style="white-space:pre">		</span>if(null==lazyMode){</div><div><span style="white-space:pre">			</span>lazyMode=new LazyMode();</div><div><span style="white-space:pre">		</span>}</div><div><span style="white-space:pre">		</span>return lazyMode;</div><div><span style="white-space:pre">	</span>}&nbsp;</div><div></div><div>}</div></div><div></div><br /><br /><br />3、双重检测：<br /><p>&nbsp;</p>
<p>package com.east.abin.impl;</p>
<p>public class Singleton {<br />&nbsp;private static Singleton instance=null;<br />&nbsp;private Singleton(){<br />&nbsp;&nbsp;<br />&nbsp;}<br />&nbsp;<br />&nbsp;public static Singleton getInstance(){<br />&nbsp;&nbsp;if(null==instance){<br />&nbsp;&nbsp;&nbsp;synchronized(Singleton.class){<br />&nbsp;&nbsp;&nbsp;&nbsp;if(null==instance){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance=new Singleton();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return instance;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;return instance;<br />&nbsp;}</p>
<p>}<br /></p>
<p>&nbsp;</p><br /><br /><br /><br /><br /><br />4.静态内部类：<br /><div><div>单例模式创新！google的ioc作者写的。只有在调用的时候才会初始化！而且线程安全 &nbsp;&nbsp;</div><div>超级牛！</div></div>
<p>package com.east.abin.bin;</p>
<p>public class Singleton {<br />&nbsp;private Singleton(){<br />&nbsp;&nbsp;<br />&nbsp;}<br />&nbsp;<br />&nbsp;private static class SingletonHelp{<br />&nbsp;&nbsp;private static Singleton instance=new Singleton();<br />&nbsp;}<br />&nbsp;<br />&nbsp;public static Singleton getInstance(){<br />&nbsp;&nbsp;return SingletonHelp.instance;<br />&nbsp;}<br />&nbsp;</p>
<p>}<br /><br /><br /><br /><br /></p>
<p>5、enum类型的(这个是针对jdk 1.5以及1.5版本以上的) </p>
<p>package com.abin.peng.service;</p>
<p>public enum Singleton {<br />&nbsp;Singleton;<br />&nbsp;private Singleton(){}<br />&nbsp;public static Singleton getInstance(){<br />&nbsp;&nbsp;return Singleton;<br />&nbsp;}<br />}<br /></p>
<p>&nbsp;</p><img src ="http://www.blogjava.net/stevenjohn/aggbug/371964.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-03-15 18:21 <a href="http://www.blogjava.net/stevenjohn/archive/2012/03/15/371964.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 设计模式之六 --- 抽象工厂模式(Abstract Factory)</title><link>http://www.blogjava.net/stevenjohn/archive/2012/03/15/371913.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Thu, 15 Mar 2012 03:08:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/03/15/371913.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/371913.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/03/15/371913.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/371913.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/371913.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每个模式都是针对一定问题的解决方案。抽象工厂模式面对的问题是多产品等级结构的系统设计。&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;在学习抽象工厂具体实例之前，应该明白两个重要的概念：产品族和产品等级。&nbsp; &nbsp; &nbsp; &nbsp; &nbs...&nbsp;&nbsp;<a href='http://www.blogjava.net/stevenjohn/archive/2012/03/15/371913.html'>阅读全文</a><img src ="http://www.blogjava.net/stevenjohn/aggbug/371913.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-03-15 11:08 <a href="http://www.blogjava.net/stevenjohn/archive/2012/03/15/371913.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>