Definition
将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个雷能够在一起工作。
Roles
Target目标角色:该角色定义把其他类转换为何种接口,也就是我们所期望的接口。
Adaptee源角色:想把谁转换为目标角色,这个谁就是源角色,它是已经存在的、运行良好的类或对象,经过适配器角色的包装,它会成为一个崭新、靓丽的角色,
Adapter适配器角色:适配器模式的核心角色,其他两个角色都是已经存在的角色,而适配器角色是需要新建的,它的职责非常简单:把源角色转换为目标角色,怎么转换?通过继承类或者是类关联的方式。
1 package com.pattern; 2 /** 3 * 目标角色 4 * ClassName: Target 5 * @Description: TODO 6 * @author liping.sang 7 * @date 2018-12-4 8 */ 9 public interface Target { 10 /** 11 * 目标角色自己的方法 12 * @Description: TODO 13 * @param 14 * @return void 15 * @throws 16 * @author liping.sang 17 * @date 2018-12-4 18 */ 19 public void request(); 20 }
目标角色是一个已经正式运行的角色,不可以去修改角色中的方法,能做的就是如何去实现接口中的方法,而且通常情况下,目标角色是一个接口或者抽象类,一般不会是一个实现类。
1 package com.pattern; 2 3 /** 4 * 目标角色的实现类 5 * ClassName: ConcreteTarget 6 * @Description: TODO 7 * @author liping.sang 8 * @date 2018-12-4 9 */ 10 public class ConcreteTarget implements Target { 11 12 @Override 13 public void request() { 14 System.out.println("if you need any help,pls call me !"); 15 16 } 17 18 }
源角色也是已经在服役状态,它是一个正常的类,
1 package com.pattern; 2 /** 3 * 源角色 4 * ClassName: Adaptee 5 * @Description: TODO 6 * @author liping.sang 7 * @date 2018-12-4 8 */ 9 public class Adaptee { 10 11 public void doSomething(){ 12 /** 13 * 原有的业务逻辑 14 */ 15 System.out.println("I'm kind of busy,leave me alone,pls"); 16 } 17 }
核心适配器角色:
package com.pattern; /** * 适配器角色 * ClassName: Adapter * @Description: TODO * @author liping.sang * @date 2018-12-4 */ public class Adapter extends Adaptee implements Target { @Override public void request() { super.doSomething(); } }
客户端使用:
1 package com.pattern; 2 3 public class Client { 4 5 /** 6 * @Description: TODO 7 * @param @param args 8 * @return void 9 * @throws 10 * @author liping.sang 11 * @date 2018-12-4 12 */ 13 public static void main(String[] args) { 14 Target target = new ConcreteTarget(); 15 target.request(); 16 Target target2 = new Adapter(); 17 target2.request(); 18 19 } 20 21 }
优点:
1)适配器模式可以让两个没有任何关系的类在一起运行,只要适配器这个角色能够搞定他们就成。
2)增加了类的透明性。
想想看,我们访问的Target目标角色,但是具体的实现都委托给看源角色,而这些对高层次模块是透明的,也是它不需要关心的。
3)提高了类的复用度
源角色在原有的系统中还是可以使用,而在目标角色中也可以充当新的演员
4)灵活性非常好
如果不想要的话,删掉就好了。
使用场景:
如果要修改一个已经投产中的接口时,适配器模式可能是最适合你的模式,比如,系统扩展了,需要使用一个已有或新建立的类,但这个类又不符合系统的接口,怎么办?使用适配器模式。
分类:
类适配器:
类适配器是类间集成。
对象适配器:
对象适配器是通过类间的关联关系进行耦合。
1 // 适配器类,直接关联被适配类,同时实现标准接口 2 class Adapter implements Target{ 3 // 直接关联被适配类 4 private Adaptee adaptee; 5 6 // 可以通过构造函数传入具体需要适配的被适配类对象 7 public Adapter (Adaptee adaptee) { 8 this.adaptee = adaptee; 9 } 10 11 public void request() { 12 // 这里是使用委托的方式完成特殊功能 13 this.adaptee.specificRequest(); 14 } 15 }