适配器模式类型:
- 类适配器模式:适配类的API转换成目标类的API
- 对象适配器模式:对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用关联关系连接到Adaptee类替代。
- 缺省适配器模式(接口适配器模式):
角色:
1.待适配类(Adaptee):需要适配的类或适配者类。
2.目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
3. 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。
生活例子: 笔记本电脑的插头一般都是三厢的,即除了阳极、阴极外,还有一个地极。而有些地方的电源插座却只有两极,没有地极。电源插座与笔记本电脑的电源插头不匹配使得笔记本电脑无法使用。这时候一个三厢到两厢的转换器(适配器)就能解决此问题,而这正像是本模式所做的事情。
类适配器模式:
1.待适配类(Adaptee):
public class Adaptee { //取得插座 假设插座最基本的都是两厢的 public void twoHoleSocket() { System.out.println("两厢插座"); } }
2.目标接口(Target):
public interface Target { //两厢插座 public void twoHoleSocket(); //三厢插座 public void threeHoleSocket(); }
3.适配器(Adapter):
/** * 让Adapter拥有两厢插座,同时扩展了功能(三厢插座) */ public class Adapter extends Adaptee implements Target { @Override public void threeHoleSocket() { System.out.println("三厢插座"); } }
测试与结果:
public class Test { public static void main(String[] args) { Adapter adapter = new Adapter(); adapter.twoHoleSocket();//两厢插座 adapter.threeHoleSocket();//三厢插座 //这个功能就是适配器扩展的功能 } }
对象适配器模式:
1.待适配类(Adaptee):
public class Adaptee { //取得插座 假设插座最基本的都是两厢的 public void twoHoleSocket() { System.out.println("两厢插座"); } }
2.目标接口(Target):
public interface Target { //两厢插座 public void twoHoleSocket(); //三厢插座 public void threeHoleSocket(); }
3.适配器(Adapter):
/** * 让Adapter拥有两厢插座,同时扩展了功能(三厢插座) */ public class Adapter implements Target { private Adaptee adaptee = null; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } /** * 待适配方法 */ @Override public void twoHoleSocket() { this.adaptee.twoHoleSocket(); } /** * 适配器扩展方法 */ @Override public void threeHoleSocket() { System.out.println("三厢插座"); } }
测试与结果:
public class Test { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); Adapter adapter = new Adapter(adaptee); adapter.twoHoleSocket();//两厢插座 adapter.threeHoleSocket();//三厢插座 //这个功能就是适配器扩展的功能 } }
缺省适配器模式:
定义一个 年轻的 类:4个方法
public interface Young { public void eat();//吃饭 public void sleep();//睡觉 public void dou();//打痘痘 public void talk();//聊天 }
定义一个本人的类:实现了 年轻的 类,问题是我没长痘啊,为毛要打痘痘? 没实现dou()方法编译都过不去
public class Liang implements Young { @Override public void eat(){} @Override public void sleep(){} @Override public void talk(){} }
我还是个 年轻的 人
public abstract class People implements Young { @Override public void eat(){} @Override public void sleep(){} @Override public void dou(){} @Override public void talk(){} }
不用打痘痘了吧,由于继承,也拥有people.dou()方法
public class Liang extends People { @Override public void eat() { System.out.println("吃饭"); } @Override public void sleep() { System.out.println("睡觉"); } @Override public void talk() { System.out.println("没实现打痘痘的方法dou()"); } }
在很多情况下,必须让一个具体类实现某一个接口,但是这个类又用不到接口所规定的所有的方法。通常的处理方法是,这个具体类要实现所有的方法,那些有用的方法要有实现,那些没有用的方法也要有空的、平庸的实现。
这些空的方法是一种浪费,有时也是一种混乱。除非看过这些空方法的代码,程序员可能会以为这些方法不是空的。即便他知道其中有一些方法是空的,也不一定知道哪些方法是空的,哪些方法不是空的,除非看过这些方法的源代码或是文档。
缺省适配模式可以很好的处理这一情况。可以设计一个抽象的适配器类实现接口,此抽象类要给接口所要求的每一种方法都提供一个空的方法。