策略设计模式
示例
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