适配器模式:将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
应用场景
假设已有一个软件系统,你希望它能和一个新的厂商类库搭配使用,但是这个新厂商所设计出来的接口不同于旧厂商的接口:
你不想改变现有的代码,解决这个问题(而且你也不能改变厂商的代码)。所以该怎么做?你可以写一个类,将新厂商接口转接成你所期望的接口。
这个适配器工作起来就如同一个中间人,它将客户所发出的请求转换成厂商类能理解的请求。
适配器模式解析
适配器模式中各个角色的关系:
客户使用适配器的过程:
1) 客户通过目标接口调用适配器的方法对适配器发出请求。
2) 适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口。
3) 客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用。
对象适配器模式和类适配器模式
对象适配器模式——组合实现。
类适配器模式——继承实现。
对象适配器模式
类图
代码实现
目标接口:
package com.huey.pattern.adapter; /** * the target * @author huey * @version 1.0 * @created 2015-11-30 */ public interface DuplexOutlet { public void useTwoHoles(); }
被适配者:
package com.huey.pattern.adapter; /** * the adaptee * @author huey * @version 1.0 * @created 2015-11-30 */ public class TriplexOutlet { public void useThressHoles() { System.out.println("现在使用的是三孔插座。"); } }
客户:
package com.huey.pattern.adapter; /** * the client * @author huey * @version 1.0 * @created 2015-11-30 */ public class DuplexPlug { public void insert(DuplexOutlet duplexOutlet) { System.out.println("这是一个双孔的插头,它需要一个双孔的插座。"); duplexOutlet.useTwoHoles(); } }
对象适配器:
package com.huey.pattern.adapter.object; import com.huey.pattern.adapter.DuplexOutlet; import com.huey.pattern.adapter.TriplexOutlet; /** * the adapter * @author huey * @version 1.0 * @created 2015-11-30 */ public class OutletAdapter implements DuplexOutlet { private TriplexOutlet triplexOutlet; public OutletAdapter(TriplexOutlet triplexOutlet) { this.triplexOutlet = triplexOutlet; } @Override public void useTwoHoles() { System.out.println("这是个插槽适配器,能够将双孔的转换成三孔的。"); triplexOutlet.useThressHoles(); } }
单元测试:
package com.huey.pattern.adapter; import com.huey.pattern.adapter.object.OutletAdapter; /** * test the object adapter pattern * @author huey * @version 1.0 * @created 2015-12-1 */ public class ObjectAdapterTest { public static void main(String[] args) { TriplexOutlet triplexOutlet = new TriplexOutlet(); DuplexOutlet duplexOutlet = new OutletAdapter(triplexOutlet); DuplexPlug duplexPlug = new DuplexPlug(); duplexPlug.insert(duplexOutlet); } }
类适配器模式
类图
代码实现
类适配器:
package com.huey.pattern.adapter.clazz; import com.huey.pattern.adapter.DuplexOutlet; import com.huey.pattern.adapter.TriplexOutlet; /** * the adapter * @author huey * @version 1.0 * @created 2015-12-1 */ public class OutletAdapter extends TriplexOutlet implements DuplexOutlet { @Override public void useTwoHoles() { System.out.println("这是个插槽适配器,能够将双孔的转换成三孔的。"); this.useThressHoles(); } }
单元测试:
package com.huey.pattern.adapter; import com.huey.pattern.adapter.clazz.OutletAdapter; /** * test the class adapter pattern * @author huey * @version 1.0 * @created 2015-12-1 */ public class ClassAdapterTest { public static void main(String[] args) { DuplexOutlet duplexOutlet = new OutletAdapter(); DuplexPlug duplexPlug = new DuplexPlug(); duplexPlug.insert(duplexOutlet); } }
适配器模式的适用场合
1) 软件系统结构需要升级或扩展,又不想影响原有系统的稳定运行的时候;
2) 转换类之间差别不是太大的时候;
3) 想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作的时候。