策略模式与适配器模式

策略模式:把会变化的内容取出并封装起来,以便以后可以轻易地改动或扩充部分,而不影响不需要变化的其他部分;先看一个下面的例子

采用继承的方式实现不同的行为

 1 import java.util.Arrays;
 2 class Processor {
 3   public String name() {
 4     return getClass().getSimpleName();
 5   }
 6   Object process(Object input) { return input; }
 7 }
 8 
 9 class Upcase extends Processor {
10   String process(Object input) { // Covariant return
11     return ((String)input).toUpperCase();
12   }
13 }
14 
15 class Downcase extends Processor {
16   String process(Object input) {
17     return ((String)input).toLowerCase();
18   }
19 }
20 
21 public class Apply {
22   public static void process(Processor p, Object s) {
23     System.out.println("Using Processor " + p.name());
24     System.out.println(p.process(s));
25   }
26   public static String s = "Disagreement with beliefs is by definition incorrect";
27   public static void main(String[] args) {
28     process(new Upcase(), s);
29     process(new Downcase(), s);
30   }
31 } /* Output:
32 Using Processor Upcase
33 DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRECT
34 Using Processor Downcase
35 disagreement with beliefs is by definition incorrect
36 *///:~

例子中:Upcase和Downcase是变化的内容,而Apply是不变的部分。如果在项目发展过程中,需要加入一个新的行为Splitter,那么我们只需要创建一个继承Processor的

子类Splitter即可,那么Apply的process方法不需要做任何更改即可正常运行。

class Splitter extends Processor {
  String process(Object input) {
  // The split() argument divides a String into pieces:
    return Arrays.toString(((String)input).split(" "));
  }
}

上面的这种继承的方式有缺点,因为Apply的process只适用于Processor的子类,即目前Apply只能处理3种行为:Upcase、Downcase、Splitter. 下面我们采用接口的方式

来提升Apply的能力。先重写上面的例子:

public interface Processor {
  String name();
  Object process(Object input);
}
public class Apply {
  public static void process(Processor p, Object s) {
    System.out.println("Using Processor " + p.name());
    System.out.println(p.process(s));//委托给 p处理。
  }
}

 

import java.util.*;

abstract class StringProcessor implements Processor{ public String name() { return getClass().getSimpleName(); } public abstract String process(Object input); public static String s = "If she weighs the same as a duck, she’s made of wood"; public static void main(String[] args) { Apply.process(new Upcase(), s); Apply.process(new Downcase(), s); Apply.process(new Splitter(), s); } } class Upcase extends StringProcessor { public String process(Object input) { // Covariant return return ((String)input).toUpperCase(); } } class Downcase extends StringProcessor { public String process(Object input) { return ((String)input).toLowerCase(); } } class Splitter extends StringProcessor { public String process(Object input) { return Arrays.toString(((String)input).split(" ")); } }

然后:我们希望Apply能处理Wash(洗衣服):

public abstract class WashProcessor implements Processor{
  public String name() {
    return getClass().getSimpleName();
}

public abstract String process(Object input);
public static void main(String[] args) {
Clothes shirt = new Clothes("shirt"); Apply.process(
new DryClean(), shirt); Apply.process(new Wash(), shirt); } } class DryClean extends WashProcessor { public String process(Object input) { return "dry-clean " + ((Clothes)input).toString(); } } class Wash extends WashProcessor { public String process(Object input) { return "wash " ((Clothes)input).toString(); } }

class Clothes {
String type;
Clothes (String type) {
this.type = type;
}
public String toString(){return type;}
}

那么现在,Apply可以处理5种行为了,而且Apply可以处理更多的实现了Processor接口的行为。相比将Processor设计成基类,Processor接口的方式更具扩展性。

适配器模式:

 上面的两个例子StringProcessor和WashProcessor是我们自己写的类库;但是,你有时候会遇到你无法修改的类库,例如我们有这样一个类库:

public abstract class WashBehavior {
public abstract String process(Object input); } class DryClean extends WashBehavior { public String process(Object input) { return "dry-clean " + (Clothes)input;//自动调用Clothes的toString()然后拼接"dry-clean"返回 } } class Wash extends WashBehavior { public String process(Object input) { return "wash " + (Clothes)input; } }

很明显,Apply不能直接处理DryClean、Wash;但是我们不能修改WashBehavior,让它实现Processor(那是别人的类库)。那么我们现在就需要采用适配

器模式的思想,写一个适配器(感觉就是一中介):

class WashAdapter implements Processor {
  WashBehavior washBehavior;
  public WashAdapter(WashBehavior washBehavior) {
    this.washBehavior = washBehavior;
  }
  public String name() {return washBehavior.getClass().getSimpleName();}
  public String process(Object input) {
     return washBehavior.process((Clothes) input);//委托washBehavior处理
  }
}

public class WashProcessor {
  public static void main(String[] args) {
     Clothes shirt = new Clothes("shirt");
     Apply.process(new WashAdapter(new DryClean()), shirt);
     Apply.process(new WashAdapter(new Wash()), shirt);
  }
}

 那么有了上面的适配器WashAdapter,我们就能让Apply处理我们不能修改的类库了。

可能你已经注意到,Apply的process方法和WashAdapter的process方法都采用委托的方式,即他们不自己实现处理的细节,这就有利于程序的扩展和维护。

WashAdapter又用到了java的一个很重要的代码重用方式--组合。WashAdapter通过WashBehavior引用可以重用WashBehavior里的接口,同理,WashAdapter

还可以声明更多的Behavior,然后对每个Behavior创建重载的process方法,那么通过WashAdapter,Apply的能力将更加强大。而WashAdapter的这种持有各种

Behavior引用,并通过Behavior引用使用其接口的方式就是组合。相比继承的重用(静态重用),组合这种动态重用更加利于代码的扩展和维护;但是继承作为java三大

基本特征之一,自然有其强悍之处,这里不再细述。

注:上面部分代码未经过调试,可能会存在一些错误,如果有兴趣的看官可参照上面的代码自行调试。另:本人是一java菜鸟,此文是我学习java时做的学习笔记,以防止

遗忘。如有错误之处,欢迎各位看官指正,还望各位看官勿喷。

 

 1 import java.util.Arrays;
 2 class Processor {
 3   public String name() {
 4     return getClass().getSimpleName();
 5   }
 6   Object process(Object input) { return input; }
 7 }
 8 
 9 class Upcase extends Processor {
10   String process(Object input) { // Covariant return
11     return ((String)input).toUpperCase();
12   }
13 }
14 
15 class Downcase extends Processor {
16   String process(Object input) {
17     return ((String)input).toLowerCase();
18   }
19 }
20 
21 class Splitter extends Processor {
22   String process(Object input) {
23   // The split() argument divides a String into pieces:
24     return Arrays.toString(((String)input).split(" "));
25   }
26 }
27 
28 public class Apply {
29   public static void process(Processor p, Object s) {
30     System.out.println("Using Processor " + p.name());
31     System.out.println(p.process(s));
32   }
33   public static String s = "Disagreement with beliefs is by definition incorrect";
34   public static void main(String[] args) {
35     process(new Upcase(), s);
36     process(new Downcase(), s);
37     process(new Splitter(), s);
38   }
39 } /* Output:
40 Using Processor Upcase
41 DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRECT
42 Using Processor Downcase
43 disagreement with beliefs is by definition incorrect
44 Using Processor Splitter
45 [Disagreement, with, beliefs, is, by, definition, incorrect]
46 *///:~

转载于:https://www.cnblogs.com/ljobandroid/archive/2012/09/03/2668279.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值