适配器模式,简单来说就是将一个类的接口转换为客户想要的接口,适配器模式可以将原本不兼容的类一起工作,
就好比下图
话不多说,先来个简单的demo,服务端写一个计算类
class Calc {
public int add(int a, int b) {
return a + b;
}
}
//=============================================
public class Test {
public static void main(String[] args) {
CalcAdapter ca = new CalcAdapter();
int r = ca.add(1, 2);
System.out.println(r);
}
}
现在客户端想要计算三个数的和,这时可以用到适配器模式,将Calc类组合进适配器类(牢记组合大于继承,继承很脆弱!)
class CalcAdapter {
private Calc c = new Calc();
public int add(int x, int y, int z) {
return c.add(c.add(x,y), z);
}
}
想必大家对适配器模式有了一点认识,下面我们来看看Java编程思想中的一个非常“精彩”的例子。
首先我们来写一个Proccessor类
class Proccessor {
public String name(){
return getClass().getSimpleName();
}
public Object proccess(Object input){
return input;// 虚假处理
}
}
再写一些方法类
class Upcase extends Proccessor {
public String proccess(Object obj) {// 协变
return ((String)obj).toUpperCase();
}
}
class Downcase extends Proccessor {
public String proccess(Object obj) {
return ((String)obj).toLowerCase();
}
}
class Splitter extends Proccessor {
public String proccess(Object obj) {
return Arrays.toString(((String)obj).split(" "));
}
}
调用如下
public class Test {
public static void main(String[] args) {
String str = "How are you! What's this? This is a desk!";
Proccessor p = new Upcase();
System.out.println(p.name());
System.out.println(p.proccess(str));
Proccessor p2 = new Downcase();
System.out.println(p2.name());
System.out.println(p2.proccess(str));
Proccessor p3 = new Splitter();
System.out.println(p3.name());
System.out.println(p3.proccess(str));
}
}
很明显,代码重用性低,有一些“坏味道”,我们来改良一下,抽象出一层处理类进行封装
class Apply {
public static void proccess(Proccessor p, Object s) {
System.out.println(p.name());
System.out.println(p.proccess(s));
}
}
此时
public class Test {
public static void main(String[] args) {
String str = "How are you! What's this? This is a desk!";
Apply.proccess(new Upcase(), str);
Apply.proccess(new Downcase(), str);
Apply.proccess(new Splitter(), str);
}
}
此时我们思考一个问题,因为使用的是Proccessor类,如果一个方法传入的是类,那么这个方法就只能作用于此类的体系中,扩展性大大降低,这里先把类改为接口,方便后续适配器模式的讲解,进一步改良后代码
interface Proccessor {
String name();
// 为了当子类向上转型以后,还能调用这个proccess方法,所以才在父类这里定义出这个proccess方法
Object proccess(Object input) ;
}
// 提出共性,减少代码冗余
abstract class StringProccessor implements Proccessor {
@Override
public String name() {
return this.getClass().getSimpleName();
}
}
class Upcase extends StringProccessor {
public String proccess(Object obj) {
return ((String)obj).toUpperCase();
}
}
class Downcase extends StringProccessor {
public String proccess(Object obj) {
return ((String)obj).toLowerCase();
}
}
class Splitter extends StringProccessor {
public String proccess(Object obj) {
return Arrays.toString(((String)obj).split(" "));
}
}
class Apply {
public static void proccess(Proccessor p, Object s) {
System.out.println(p.name());
System.out.println(p.proccess(s));
}
}
public class Test {
public static void main(String[] args) {
String str = "How are you! What's this? This is a desk!";
Apply.proccess(new Upcase(), str);
Apply.proccess(new Downcase(), str);
Apply.proccess(new Splitter(), str);
}
}
准备工作到此就完毕了,现在发现一组滤波器,似乎也可以使用Proccessor方法,简单来说,这组滤波器因为机缘巧合,也拥有和我们写的Proccessor有同样的实现方法,代码如下
public class WaveForm {
private static long counter;
private final long id = counter++;
public String toString() {
return "Waveform " + id;
}
}
class Filter {
public String name() {
return this.getClass().getSimpleName();
}
public WaveForm proccess(WaveForm input) {
return input;
}
}
class LowPass extends Filter{
double cutoff;
public LowPass(double cutoff) {
super();
this.cutoff = cutoff;
}
@Override
public WaveForm proccess(WaveForm input) {
return input; // 虚拟处理
}
}
class HighPass extends Filter{
double cutoff;
public HighPass(double cutoff) {
super();
this.cutoff = cutoff;
}
@Override
public WaveForm proccess(WaveForm input) {
return input; // 虚拟处理
}
}
class BandPass extends Filter{
double lowCutoff;
double highCutoff;
public BandPass(double lowCutoff, double highCutoff) {
super();
this.lowCutoff = lowCutoff;
this.highCutoff = highCutoff;
}
@Override
public WaveForm proccess(WaveForm input) {
return input; // 虚拟处理
}
}
此时我们调用滤波器
public class Test {
public static void main(String[] args) {
String str = "How are you! What's this? This is a desk!";
WaveForm wf = new WaveForm();
Filter f = new LowPass(1);
System.out.println(p.name());
System.out.println(p.proccess(wf));
Filter f2 = new HighPass(1);
System.out.println(p2.name());
System.out.println(p2.proccess(wf));
Filter f3 = new BandPass(1,2);
System.out.println(p3.name());
System.out.println(p3.proccess(wf));
}
}
这段代码是不是很熟悉,这时,如果可以使用之前的接口岂不是美滋滋,但Filter没有实现我们Proccess接口,美梦由此破灭。此时就轮到了适配器模式等场了。
创建一个适配器
class FilterAdapter implements Proccessor {
private Filter filter;
// 注入Filter
public FilterAdapter(Filter filter) {
this.filter = filter;
}
@Override
public String name() {
return filter.name();
}
@Override
public WaveForm proccess(Object input) {
return filter.proccess((WaveForm)input);
}
}
调用之
public class Test {
public static void main(String[] args) {
String str = "How are you! What's this? This is a desk!";
Apply.proccess(new Upcase(), str);
Apply.proccess(new Downcase(), str);
Apply.proccess(new Splitter(), str);
WaveForm wf = new WaveForm();
Apply.proccess(new FilterAdapter(new LowPass(10)), wf);
Apply.proccess(new FilterAdapter(new HighPass(10)), wf);
Apply.proccess(new FilterAdapter(new BandPass(10,20)), wf);
}
}
实现了完美适配~
本例中使用适配器模式提高了proccess方法的重用性,适配器模式就介绍到这里,希望有帮助到大家~