策略设计模式

示例

package com.ebao.java.interfaces9;

public class Processor {
 public String name(){
  return this.getClass().getSimpleName();
 }
 Object process(Object input){
  return input;
 }
}

 

public class Upcase extends Processor {
 String process(Object input){
  return ((String)input).toUpperCase();
 }
}

 

public class Downcase extends Processor {
 String process(Object input){
  return ((String)input).toLowerCase();
 }
}

 

public class Splitter extends Processor {
 String process(Object input){
  return Arrays.toString(((String)input).split(" "));
 }
}

 

public class Apply {
 public static void process(Processor p, Object s){
  System.out.println("Using Processor "+p.name());
  System.out.println(p.process(s));
 }
 public static String s = "Disagreement with beliefs is by definition incorrect";
 public static void main(String[] args){
  process(new Upcase(),s);
  process(new Downcase(),s);
  process(new Splitter(),s);
 }
}

运行结果:

Using Processor Upcase
DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRECT
Using Processor Downcase
disagreement with beliefs is by definition incorrect
Using Processor Splitter
[Disagreement, with, beliefs, is, by, definition, incorrect]

Apply.process()方法可以接受任何类型的Process,并将其应用到一个Object对象上,然后打印结果。像上例这样,创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,被称为策略设计模式。这类方法包含所要执行的算法中固定不变的部分,而“策略”包含变化的部分。策略就是传递进去的参数对象,它包含要执行的代码。这里,Processor对象就是一个策略,在main()中可以看到有三种不同类型的策略应用到了String类型的s对象上。

 

示例二:

package com.ebao.java.interfaces9;

public class Waveform {
private static long counter;
private final long id = counter++;
public String toString(){
 return "Waveform "+id;
}
}

 

public class Filter{
 public String name(){
  return this.getClass().getSimpleName();
 }
}

 

public class LowerPass extends Filter {
 double cutoff;
 public LowerPass(double cutoff){
  this.cutoff = cutoff;
 }
 public Waveform process(Waveform input){
  return input;
 }
}

 

public class HighPass extends Filter {
 double cutoff;
 public HighPass(double cutoff){
  this.cutoff = cutoff;
 }
 public Waveform process(Waveform input){
  return input;
 }
}

 

public class BandPass extends Filter {
 double lowCutoff,hightCutoff;
 public BandPass(double lowCutoff,double hightCutoff){
  this.lowCutoff = lowCutoff;
  this.hightCutoff = hightCutoff;
 }
 public Waveform process(Waveform input){
  return input;
 }
}

Filter与Processor具有相同的接口元素,但是因为它并非继承自Processor——因为Filter类的创建者压根不清楚你想要将它用作Processor——因此你不能将Filter用于Apply.process()方法。这里主要是因为Apply.process方法和Processor之前的耦合过紧,已经超出了所需要的程序,这就使得应该利用Apply.process()的代码时,利用却被禁止了。另外还有它们的输入和输出都是Waveform。

但是,如果Processor是个接口,那么这些限制就会变得松动,使得你可以复用结构该接口的Apply.process()。下面是Processor和Apply的修改版本:

package com.ebao.java.interfaces9;

public interface Processor02 {
 String name();
 Object process(Object input);
}

 

public class Apply02 {
 public static void process(Processor02 p, Object s){
  System.out.println("Using Processor "+p.name());
  System.out.println(p.process(s));
 }
}

 

public abstract class StringProcessor implements Processor02 {

 public String name() {
  return this.getClass().getSimpleName();
 }

 public abstract String process(Object input);
 public static String s = "Disagreement with beliefs is by definition incorrect";
 public static void main(String[] args){
  Apply02.process(new Upcase02(),s);
  Apply02.process(new Downcase02(),s);
  Apply02.process(new Splitter02(),s);
 }
}

 

public class Upcase02 extends StringProcessor {

 public String process(Object input) {
  return ((String)input).toUpperCase();
 }
}

 

public class Downcase02 extends StringProcessor {

 public String process(Object input) {
  return ((String)input).toLowerCase();
 }
}

 

public class Splitter02 extends StringProcessor {

 public String process(Object input) {
  return Arrays.toString(((String)input).split(" "));
 }
}

抽象类继承接口时可以不用继承接口方法。

 

但是,经常会碰到的情况是你无法修改你想要使用的类。例如,在电子滤波器的例子啊,类库是被发现而非被修建。在这些情况下,可以使用适配器设计模式。适配器中的代码将接受你所拥有的接口,并产生你所需要的接口,就像下面这样:

package com.ebao.java.interfaces9;

public class FilterAdapter implements Processor02 {
 Filter filter;
 public FilterAdapter(Filter filter){
  this.filter = filter;
 }

 public String name() {
  return filter.name();
 }

 public Waveform process(Object input) {
  return filter.process((Waveform)input);
 }
}

 

public class FilterProcessor {
 public static void main(String[] args){
  Waveform w = new Waveform();
  Apply02.process(new FilterAdapter(new LowerPass(1.0)), w);
  Apply02.process(new FilterAdapter(new HighPass(2.0)), w);
  Apply02.process(new FilterAdapter(new BandPass(3.0,4.0)), w);
 }
}

在使用这种适配器的方式中,FilterAdapter的构造器接受你所拥有的接口Filter,然后生成具有你所需要的Processor接口对象。你可能还注意到了,在FilterAdapter类中用到了代理。将接口从具体实现中解耦使得接口可以适用于多种不同的实现,因此代码就更具有可利用性。

 

例如再写个Example类,有一个方法,对其进行适配

package com.ebao.java.interfaces9;

public class Example {
 public String exchange(String s){
  return "Example: "+s;
 }
}

 

public class ExampleAdapter implements Processor02 {
 private Example ep;
 public ExampleAdapter(Example ep){
  this.ep = ep;
 }

 public String name() {
  return ep.getClass().getSimpleName();
 }

 public String process(Object input) {
  return ep.exchange((String)input);
 }
}

 

public class ExampleProcessor {
 public static void main(String[] args){
  Apply02.process(new ExampleAdapter(new Example()), "fengying");
 }
}

运行结果:

Using Processor Example
Example: fengying

posted on 2015-08-31 16:53  幸运叶  阅读(721)  评论(0编辑  收藏  举报