??xml version="1.0" encoding="utf-8" standalone="yes"?>久久免费偷拍视频,亚洲综合色网站,超碰精品在线http://www.aygfsteel.com/applupus/category/30784.html专注于javazh-cnSun, 13 Apr 2008 12:25:59 GMTSun, 13 Apr 2008 12:25:59 GMT60设计模式Q?2Q-Strategy PatternQJava版{译)http://www.aygfsteel.com/applupus/articles/192589.htmlapplupusapplupusSun, 13 Apr 2008 10:06:00 GMThttp://www.aygfsteel.com/applupus/articles/192589.htmlhttp://www.aygfsteel.com/applupus/comments/192589.htmlhttp://www.aygfsteel.com/applupus/articles/192589.html#Feedback0http://www.aygfsteel.com/applupus/comments/commentRss/192589.htmlhttp://www.aygfsteel.com/applupus/services/trackbacks/192589.html 原作者:吕震?br /> PSQ原作是C#版的Q本人将其译成JavaQ有许改动?br />
一?{略QStrategyQ模?/strong>

{略模式的用意是针对一l算法,每一个算法封装到h共同接口的独立的cMQ从而得它们可以相互替换。策略模式得算法可以在不媄响到客户端的情况下发生变化?br />
假设现在要设计一个贩卖各cMc的电子商务|站的购物RQShopping CatQ系l。一个最单的情况是把所有货品的单h乘上数量Q但是实际情况肯定比q要复杂。比如,本网站可能对所有的教材cd书实行每本一元的折扣Q对q环ȝ图书提供每本7Q的促销折扣Q而对非教材类的计机图书?Q的折扣Q对其余的图书没有折扣。由于有q样复杂的折扣算法,使得h计算问题需要系l地解决?br />
使用{略模式可以把行为和环境分割开来。环境类负责l持和查询行为类Q各U算法则在具体策略类QConcreteStrategyQ中提供。由于算法和环境独立开来,法的增减、修攚w不会影响环境和客L。当出现新的促销折扣或现有的折扣政策出现变化Ӟ只需要实现新的策略类Qƈ在客L登记卛_。策略模式相当于"可插入式QPluggableQ的法"?br />
二?{略模式的结?/strong>

{略模式是对法的包装,是把使用法的责d法本n分割开Q委z不同的对象管理。策略模式通常把一个系列的法包装Cpd的策略类里面Q作Z个抽象策略类的子cR用一句话来说Q就是:"准备一l算法,q将每一个算法封装v来,使得它们可以互换?

{略又称做政{(PolicyQ模式【GOF95】。下面是一个示意性的{略模式l构图:

 

q个模式涉及C个角Ԍ

    * 环境QContextQ角Ԍ持有一个Strategycȝ引用?br />     * 抽象{略QStrategyQ角Ԍq是一个抽象角Ԍ通常׃个接口或抽象cd现。此角色l出所有的具体{略cL需的接口?br />     * 具体{略QConcreteStrategyQ角Ԍ包装了相关的法或行为?br />

三?C意性源代码
//抽象{略
abstract class Strategy {
    
public abstract void AlgorithmInterface();
}

//具体的策略算法A
class ConcreteStrategyA extends Strategy{
    @Override 
public void AlgorithmInterface(){
        System.out.println (
"使用{略A");
    }
}

//具体的策略算法B
class ConcreteStrategyB extends Strategy{
    @Override 
public void AlgorithmInterface(){
        System.out.println (
"使用{略B");
    }
}

//环境
class Context{
    Strategy strategy;
    
public Context(Strategy strategy){
        
this.strategy = strategy;
    }
    
public void contextInterface(){
        strategy.AlgorithmInterface();
    }
    
//改变{略
    public void setStratery(Strategy strategy){
        
this.strategy = strategy;
    }
}

//
public class Client{
    
public static void main (String[] args) {
        Context c 
= new Context(new ConcreteStrategyA());
        c.contextInterface();
        
//可以很方便地改变{略Q而不必修改原来的代码
        c.setStratery(new ConcreteStrategyB());
        c.contextInterface();
    }
}
/*输出Q?br /> 使用{略A
使用{略B
*/


四?何时使用何种具体{略角色

在学习策略模式时Q学员常问的一个问题是Qؓ什么不能从{略模式中看出哪一个具体策略适用于哪一U情况呢Q?br />
{案非常单,{略模式q不负责做这个决定。换a之,应当由客L自己军_在什么情况下使用什么具体策略角艌Ӏ策略模式仅仅封装算法,提供新算法插入到已有pȝ中,以及老算法从pȝ?退?的方便,{略模式q不军_在何时用何U算法?br />
五?一个实际应用策略模式的例子

下面的例子利用策略模式在排序对象中封装了不同的排序算法,q样以便允许客户端动态的替换排序{略Q包括Quicksort、Shellsort和MergesortQ?br />
import java.util.ArrayList;

//抽排序象{略
abstract class SortStrategy{
    
abstract public void sort(ArrayList list);
}

//快排{略
class QuickSort extends SortStrategy{
    @Override 
public void sort(ArrayList list){
        System.out.println (
"QuickSorted list");
    }
}

//希尔排序{略
class ShellSort extends SortStrategy{
    @Override 
public void sort(ArrayList list){
        System.out.println (
"ShellSorted list");
    }
}

//归ƈ排序{略
class MergeSort extends SortStrategy{
    @Override 
public void sort(ArrayList list){
        System.out.println (
"MergeSort list");
    }
}

//环境
class SortedList{
    
private ArrayList list = new ArrayList();
    
private SortStrategy sortStrategy;
    
    
public SortedList(SortStrategy sortStrategy){
        
this.sortStrategy = sortStrategy;
    }
    
    
public void sort(){
        sortStrategy.sort(list);
    }
    
//改变{略
    public void setStrategy(SortStrategy sortStrategy){
        
this.sortStrategy = sortStrategy;
    }
}

//
public class StrategyApp {
    
public static void main (String[] args) {
        SortedList studentRecords  
= new SortedList(new QuickSort());
        studentRecords.sort();
        
//改用希尔排序
        studentRecords.setStrategy(new ShellSort());
        studentRecords.sort();
    }
}
/*输出Q?br /> QuickSorted list
ShellSorted list
*/


六?在什么情况下应当使用{略模式

在下面的情况下应当考虑使用{略模式Q?br />
1. 如果在一个系l里面有许多c,它们之间的区别仅在于它们的行为,那么使用{略模式可以动态地让一个对象在许多行ؓ中选择一U行为?br />
2.  一个系l需要动态地在几U算法中选择一U。那么这些算法可以包装到一个个的具体算法类里面Q而这些具体算法类都是一个抽象算法类的子cR换a之,q些具体法cd有统一的接口,׃多态性原则,客户端可以选择使用M一个具体算法类Qƈ只持有一个数据类型是抽象法cȝ对象?br />
3. 一个系l的法使用的数据不可以让客L知道。策略模式可以避免让客户端涉及到不必要接触到的复杂的和只与算法有关的数据?br />
4. 如果一个对象有很多的行为,如果不用恰当的模式,q些行ؓ只好用多重的条g选择语句来实现。此Ӟ使用{略模式Q把q些行ؓ转移到相应的具体{略c里面,可以避免用难以维护的多重条g选择语句Qƈ体现面向对象设计的概c?br />
七?{略模式的优点和~点


{略模式有很多优点和~点。它的优ҎQ?br />
1. {略模式提供了管理相关的法族的办法。策略类的等U结构定义了一个算法或行ؓ族。恰当用承可以把公共的代码移到父c里面,从而避免重复的代码?br />
2.  {略模式提供了可以替换承关pȝ办法。承可以处理多U算法或行ؓ。如果不是用{略模式Q那么用算法或行ؓ的环境类可能会有一些子c,每一个子cL供一个不同的法或行为。但是,q样一来算法或行ؓ的用者就和算法或行ؓ本n混在一赗决定用哪一U算法或采取哪一U行为的逻辑和法或行为的逻辑混合在一P从而不可能再独立演化。承得动态改变算法或行ؓ变得不可能?br />
3. 使用{略模式可以避免使用多重条g转移语句。多重{U语句不易维护,它把采取哪一U算法或采取哪一U行为的逻辑与算法或行ؓ的逻辑混合在一Pl统列在一个多重{U语句里面,比用承的办法q要原始和落后?br />
{略模式的缺ҎQ?br />
1. 客户端必ȝ道所有的{略c,q自行决定用哪一个策略类。这意味着客户端必ȝ解这些算法的区别Q以侉K时选择恰当的算法类。换a之,{略模式只适用于客L知道所有的法或行为的情况?br />
2. {略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将{略c设计成可共享的Q这L略类实例可以被不同客L使用。换a之,可以使用享元模式来减对象的数量?br />
八?其它

{略模式与很多其它的模式都有着q泛的联pRStrategy很容易和Bridge模式相؜淆。虽然它们结构很怼Q但它们却是决不同的问题而设计的?Strategy模式注重于算法的装Q而Bridge模式注重于分L象和实现Qؓ一个抽象体pL供不同的实现。Bridge模式与Strategy模式都很好的体现?Favor composite over inheritance"的观炏V?br />
推荐大家M诅RIoC 容器和Dependency Injection 模式》,作者Martin Fowler。网上可以找C文版的PDF文g。ؓ{略模式的实施提供了一个非常好的方案?br />
参考文献:
阎宏Q《Java与模式》,电子工业出版C?br /> []James W. CooperQ《C#设计模式》,电子工业出版C?br /> []Alan Shalloway  James R. TrottQ《Design Patterns Explained》,中国电力出版C?br /> []Robert C. MartinQ《敏捯Y件开发-原则、模式与实践》,清华大学出版C?br /> []Don Box, Chris SellsQ?NET本质?W?P公共语言q行库》,中国电力出版C?br />

applupus 2008-04-13 18:06 发表评论
]]>
վ֩ģ壺 | Ǩ| е| Ȫ| Ԫ| | | | | Ӽ| ˮ| | ƶ| ̩| ͨ| Ԫ| | Ž| | | | | | | | ̨| Ϫ| γ| ɽ| | ٳ| | ɽ| ϳ| ʵ| | ʡ| | | ŷ| |