Adapter Pattern总的划分有两种实现方式,分别是Class Adapter以及Object Adapter。根据黄金法则“多用组合,少用继承”,Object Adapter应用范围一般比Class Adapter要广。下面就我自己写的代码来理解理解。
例子:Adapter所承担的责任就是适配的作用,如显卡适合配,电源适配器,乃至我们现实生活中的翻译。它使得两个不能兼容的类可以一起工作,提高复用性。 假如有一美国人与中国人,彼此语言不通。现在通过采用Adapter Pattern模拟翻译所起的作用。
package AdapterPattern;
import java.math.*;
import java.util.Random;
/*
* Adaptee
* 通过随机数模拟美国佬随机讲英语
* 其实这里没必要用Singleton pattern
* 无妨,想用就用吧。
*/
public class American{
private static Random ran=new Random();
private static American instance=null;
private static int i;
static{
i=ran.nextInt();
System.err.println("The random number is "+i);
}
public static American getInstance(){
if(instance==null)
return new American();
else
return instance;
}
public String SpeakEnglish(){
if(i%3==0)
return ("Excuse me, how can I get to the BIRD-NEST?");
else if(i%3==1)
return "HELLO";
else
return "MY GOD!";
}
}
package AdapterPattern;
/*
* Target
*/
public interface Chinese{
public String SpeakChinese(String s);
//{
//return ("Chinese speaks Chines");
//}
}
package AdapterPattern;
import AdapterPattern.American;
import AdapterPattern.Chinese;
public class ChinesSpeakEnglish implements Chinese{
private American a;
public ChinesSpeakEnglish(American a){
this.a=a;
}
public String SpeakChinese(String s){
if (s=="Excuse me, how can I get to the BIRD-NEST?")
return "坐车去吧";
else if(s=="HELLO")
return "你好";
else if(s=="MY GOD!")
return "怎么啦,同志";
return "关我×事,我出来打酱油的";
}
}
package AdapterPattern;
import AdapterPattern.American;
import AdapterPattern.ChinesSpeakEnglish;
public class Main{
public static void main(String[] args){
American a=American.getInstance();
System.err.println(a.SpeakEnglish());
Chinese c=new ChinesSpeakEnglish(a);
System.err.println(c.SpeakChinese(a.SpeakEnglish()));
//System.err.println(c.SpeakChinese());
}
}
运行结果:
The random number is 497436522
Excuse me, how can I get to the BIRD-NEST?
坐车去吧
----------------------------------------------
The random number is -1014694547 MY GOD! 怎么啦,同志
上面的例子,其实就是Object Adapter,适配器实现了Target的接口,通过构造函数把被适配的对象(Adaptee)作为其字段保存。其实,同样作为Object Adapter,Target可以以类的形式存在,并不一定要是接口。一句话,不要拘泥于教科形式。下面把上面的例子改一改,用Class Adapter的方式来实现。American.java文件没有改动。这也是适配器模式的一个目的。假如还需要改动Adaptee,那还要适配器模式干什么呢?Target还是以接口的形式存在。变动的是适配器,由于java不支持多继承,所以采用了继承与实现共存的方式。
package AdapterPattern; import AdapterPattern.American; import AdapterPattern.Chinese; public class ChinesSpeakEnglish extends American implements Chinese{ //private American a; public ChinesSpeakEnglish(){ super(); } //ChinesSpeakEnglish ce=(ChinesSpeakEnglish)American.getInstance(); public String SpeakChinese(String s){ if (s=="Excuse me, how can I get to the BIRD-NEST?") return "坐车去吧"; else if(s=="HELLO") return "你好"; else if(s=="MY GOD!") return "怎么啦,同志"; return "关我×事,我出来打酱油的"; } }
Client main函数也没有改变。运行结果还是没有问题的。The random number is -1705553774MY GOD!怎么啦,同志The random number is 562988175Excuse me, how can I get to the BIRD-NEST ?坐车去吧The random number is 2017189702HELLO你好