比如我们可以定义以下类,我们仅仅需要实现我们想实现的方法就可以了:
public class FileMonitor extends FileAlterationListenerAdaptor { public void onFileCreate(final File file) { // 文件创建 doSomething(); } public void onFileDelete(final File file) { // 文件删除 doSomething(); } }当然,上面说的只是适配器模式的其中一种,也是最简单的一种,无需多言。下面,再介绍“正统的”适配器模式。
对象适配器模式来看一个《Head First 设计模式》中的一个例子,我稍微修改了一下,看看怎么将鸡适配成鸭,这样鸡也能当鸭来用。因为,现在鸭这个接口,我们没有合适的实现类可以用,所以需要适配器。
public interface Duck { public void quack(); // 鸭的呱呱叫 public void fly(); // 飞 } public interface Cock { public void gobble(); // 鸡的咕咕叫 public void fly(); // 飞 } public class WildCock implements Cock { public void gobble() { System.out.println("咕咕叫"); } public void fly() { System.out.println("鸡也会飞哦"); } }鸭接口有 fly() 和 quare() 两个方法,鸡 Cock 如果要冒充鸭,fly() 方法是现成的,但是鸡不会鸭的呱呱叫,没有 quack() 方法。这个时候就需要适配了:
// 毫无疑问,首先,这个适配器肯定需要 implements Duck,这样才能当做鸭来用 public class CockAdapter implements Duck { Cock cock; // 构造方法中需要一个鸡的实例,此类就是将这只鸡适配成鸭来用 public CockAdapter(Cock cock) { this.cock = cock; } // 实现鸭的呱呱叫方法 @Override public void quack() { // 内部其实是一只鸡的咕咕叫 cock.gobble(); } @Override public void fly() { cock.fly(); } }客户端调用很简单了:
public static void main(String[] args) { // 有一只野鸡 Cock wildCock = new WildCock(); // 成功将野鸡适配成鸭 Duck duck = new CockAdapter(wildCock); ... }到这里,大家也就知道了适配器模式是怎么回事了。无非是我们需要一只鸭,但是我们只有一只鸡,这个时候就需要定义一个适配器,由这个适配器来充当鸭,但是适配器里面的方法还是由鸡来实现的。
我们用一个图来简单说明下:
上图应该还是很容易理解的,我就不做更多的解释了。下面,我们看看类适配模式怎么样的。
类适配器模式废话少说,直接上图:
看到这个图,大家应该很容易理解的吧,通过继承的方法,适配器自动获得了所需要的大部分方法。这个时候,客户端使用更加简单,直接 Target t = new SomeAdapter(); 就可以了。
适配器模式总结类适配和对象适配的异同
一个采用继承,一个采用组合;
类适配属于静态实现,对象适配属于组合的动态实现,对象适配需要多实例化一个对象。
总体来说,对象适配用得比较多。
适配器模式和代理模式的异同
比较这两种模式,其实是比较对象适配器模式和代理模式,在代码结构上,它们很相似,都需要一个具体的实现类的实例。但是它们的目的不一样,代理模式做的是增强原方法的活;适配器做的是适配的活,为的是提供“把鸡包装成鸭,然后当做鸭来使用”,而鸡和鸭它们之间原本没有继承关系。
桥梁模式理解桥梁模式,其实就是理解代码抽象和解耦。
我们首先需要一个桥梁,它是一个接口,定义提供的接口方法。
public interface DrawAPI { public void draw(int radius, int x, int y); }然后是一系列实现类:
public class RedPen implements DrawAPI { @Override public void draw(int radius, int x, int y) { System.out.println("用红色笔画图,radius:" + radius + ", x:" + x + ", y:" + y); } } public class GreenPen implements DrawAPI { @Override public void draw(int radius, int x, int y) { System.out.println("用绿色笔画图,radius:" + radius + ", x:" + x + ", y:" + y); } } public class BluePen implements DrawAPI { @Override public void draw(int radius, int x, int y) { System.out.println("用蓝色笔画图,radius:" + radius + ", x:" + x + ", y:" + y); } }