Design Pattern: Strategy 模式

考虑您要设计一个更换各种符号的工具类TextCharChange,您是否会采用这样的方式:

public void replace() {
   switch(getChangeType()) {
      case RN_TYPE:   replaceRN();
                          break;
      case N_TYPE: replaceN();
                          break;
      case OTHER_TYPE: replaceOTHER():
                          break;
      ...
   }
}

 
这么作的缺点是,日后您要增加更换符号的策略时,会有几个地方需要修改:增加TYPE常数、增加TextCharChange中的 replaceXXX()方法、增加 replace()方法中的switch case判断。

像这种策略采用的情况,可以将策略加以封装为一个物件,而不是将策略写死在某个类中,如此一来,策略可以独立于客户端,随时增加变化、增加或减少策略,即使是修改每个策略的内容,也不会对客户端程式造成影响。

来举个最简单的例子,首先要知道Windows与Linux的文字档案换行符号是不同的,Windows是 /r/n ,而Linux是 /n,今天您要设计一个文字编辑器,在适当的时候,您必须要能随时转换这两种符号,如果不采用上面的策略采用流程的话,要如何设计:

  • TextStrategy.java
public abstract class TextStrategy { 
    protected String text;

    public TextStrategy(String text) { 
        this.text = text; 
    }

    public abstract String replace(); 
}  

 

  • LinuxStrategy.java
public class LinuxStrategy extends TextStrategy { 
    public LinuxStrategy(String text) { 
        super(text); 
    }

    public String replace() { 
        preOperation(); 
        System.out.println(
               text = text.replaceAll("@r@n", "@n")); 
        postOperation(); 

        return text; 
    }

    private void preOperation() { 
        System.out.println("LinuxStrategy preOperation"); 
    }

    private void postOperation() { 
        System.out.println("LinuxStrategy postOperation"); 
    } 
}  

 

  • WindowsStrategy.java
public class WindowsStrategy extends TextStrategy { 
    public WindowsStrategy(String text) { 
        super(text); 
    }

    public String replace() { 
        startOperation(); 
        System.out.println(
                     text = text.replaceAll("@n", "@r@n")); 
        endOperation(); 

        return text; 
    }

    private void startOperation() { 
        System.out.println("WindowsStrategy startOperation"); 
    } 

    private void endOperation() { 
        System.out.println("WindowsStrategy endOperation"); 
    } 
} 

 

  • TextCharChange.java
public class TextCharChange { 
    public static void replace(TextStrategy strategy) { 
        strategy.replace(); 
    } 
} 

 

  • Main.java
public class Main { 
    public static void main(String[] args) { 
        String linuxText = 
            "This is a test text!!@n Oh! Line Return!!@n"; 
        String windowsText = 
            "This is a test text!!@r@n Oh! Line Return@r@n"; 

        // load file, suppose it's Linux's text file 
        // take the WindowsStrategy 
        // I want to change it to Windows' text file 
        TextCharChange.replace(
              new WindowsStrategy(linuxText)); 

        // such-and-such operation..... 
        System.out.println(); 

        // load file, suppose it's Windows' text file 
        // take the LinuxStrategy 
        // I want to change it to Linux's text file 
        TextCharChange.replace(
            new LinuxStrategy(windowsText)); 
    } 
} 


为了明显的秀出结果,我们使用@n来表示 '/n' , @r 表示 '/r' 符号,Main中的流程是个假设的情况,何时采用何种策略是随机的。

在Strategy模式中,使用一个公开的介面replace(),让客户端请求,而在实作replace()时,可以任意的组合演算策略,程式中的 preOperation()、postOperation()就是用以示意演算的组合概念,Strategy模式封装了这些演算过程,使它们易于组合、修改、替换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值