适配器设计模式的概念
适配器模式是把一个类的接口变成用户所期待的另一个接口,从而使得原本因为接口不匹配无法一起工作的两个类一起工作!
适配器的用途
比如我们的笔记本的插头通常是三相的,除了阴极,阳极外还有地极。而有些地方的插座只有两级,没有地极。电源插座与笔记本的电源插头因为不匹配而无法使用。
一个三相到两相的转换器(适配器)就能解决问题。这正是适配器模式所要解决的问题。
适配器模式的结构
适配器模式有类适配器模式和对象适配器模式两种
类适配模式
类适配模式是把适配类的api适配成目标类的api。
从上图可以看得出来,Adaptee没有simpleOperation2()方法,而用户需要有这个方法。了使用户能够使用Adaptee类就需要一个中间环节,即利用Adapter把
Target的api与Adaptee的api连接起来。由于Adapter继承Adaptee,所以决定了这个模式是类适配模式。
模式所涉及的角色:
目标角色(Target):这就是所带得到的接口。注意因为这里是讨论适配器模式,所以只能是接口,不能是类。
源角色(adaptee):现在需要适配的接口(或类);
适配器角色(adapter):把源接口转变成目标接口的具体类。
源码 :
目标角色:
public interface Target {
//源类也有的方法
public void simpleOperation1();
//源类没有的方法
public void simpleOperation2();
}
源角色:
public class Adaptee {
public void simpleOperation1(){
System.out.println("adaptee simpleOperation1");
}
}
适配器角色:
public class Adapter extends Adaptee implements Target{
//补充源类相对目标类没有的方法
@Override
public void simpleOperation2() {
System.out.println("adapter simpeOperation2");
}
}
public class Client {
public void run(Target target){
target.simpleOperation1();
target.simpleOperation2();
}
}
测试代码:
public class TestAdapter {
public static void main(String[] args) {
Target target=new Adapter();
new Client().run(target);
}
}
测试结果:
adaptee simpleOperation1
adapter simpeOperation2
对象适配模式与类适配模式一样,也是将适配类的api转换成目标类的api,不同于类适配模式的是,对象适配模式不是通过继承的方式连接到Adaptee,而是通过将任务
委派的关系连接到Adaptee。
从上图可以看出,adaptee中并没有缺少sampleOperation2()方法。为了使用Adaptee需要一个包装(wrapper)类,这个包装类包含一个Adaptee的实例。从
而将Adaptee与target联系起来。正因为这层关系,所以这个模式为对象适配模式。
源码:
目标角色:
public interface Target {
//源类也有的方法
public void simpleOperation1();
//源类没有的方法
public void simpleOperation2();
}
源角色:
public class Adaptee {
public void simpleOperation1(){
System.out.println("adaptee simpleOperation1");
}
}
适配器角色
public class Adapter implements Target{
Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee=adaptee;
}
@Override
public void simpleOperation1() {
adaptee.simpleOperation1();
}
@Override
public void simpleOperation2() {
System.out.println("adapter simpeOperation2");
}
}
客户端角色:
public class Client {
public void run(Target target){
target.simpleOperation1();
target.simpleOperation2();
}
}
测试代码:
public class TestAdapter {
public static void main(String[] args) {
Target target=new Adapter(new Adaptee());
new Client().run(target);
}
}
测是结果:
adaptee simpleOperation1
adapter simpeOperation2
缺省适配(default adapter)模式
缺省适配模式:定义一个类为目标接口所有的方法提供缺省实现,这样子类就可以从这个缺省类进行扩展。不必从目标接口进行扩展。
源码:
目标角色:
public interface Target {
//源类也有的方法
public void simpleOperation1();
//源类没有的方法
public void simpleOperation2();
}
缺省适配器:
public class Adapter1 implements Target{
@Override
public void simpleOperation1() {
// TODO Auto-generated method stub
}
@Override
public void simpleOperation2() {
// TODO Auto-generated method stub
}
}
public class Adaptee1 extends Adapter1{
@Override
public void simpleOperation1() {
// TODO Auto-generated method stub
super.simpleOperation1();
System.out.println("adaptee simpleOperation1");
}
}
测试代码
public class TestAdapter {
public static void main(String[] args) {
Target target=new Adaptee1();
new Client().run(target);
}
}
测试结果:
adaptee simpleOperation1
适配模式的优缺点:
1,更好的复用性:
系统需要使用现有的类,而现有的类不符合系统接口的要求,通过适配可以使现有类得到很好的复用。
2,更好的扩展功能:
在适配功能时,可以调用自己开发的功能,从而扩展系统的功能。
3,过多的使用适配器,会使得系统非常混乱,不易整体把握。(试想一下,明明看到的是A接口,实现的却是B接口)