一.概念
适配器模式将一个接口转换成客户希望的另外一个接口。它使得原来由于接口不兼容而不能在一起工作的那些类可以一起工作。
二.UML
三.更加生动的例子
四.实例分析
去年买了一个本本,另外给本本配了罗技G1光电套。坑爹的是,光电套的鼠标是USB接口,键盘是PS2接口,可我的本本却没有PS2接口啊。于是跑到市场,淘了一个转接器。
于是乎,我抽象了这么几个类。
- PS2Port(PS2接口)。
- USBPort(USB接口)。
- PS2ToUSB(对象适配器),将PS2接口装换成USB接口。
- TestAdapter(测试类),客户端。
PS2Port
Java代码
- package com.zzy.adapter;
-
- /**
- * PS2接口,圆口
- * @author eason
- *
- */
- public interface PS2Port {
- public void workWithPS2();
- }
USBPort
Java代码
- package com.zzy.adapter;
-
- /**
- * USB接口,U口
- * @author eason
- *
- */
- public interface USBPort {
- public void workWithUSB();
- }
PS2ToUSB
Java代码
- package com.zzy.adapter;
-
- /**
- * 对象适配器
- * 将PS2接口装换成USB接口
- * 所以此类类型是USB接口(implements USBPort) + 成员变量ps2Port
- * @author eason
- *
- */
- public class PS2ToUSB implements USBPort{
-
- private PS2Port ps2Port;
-
- public PS2ToUSB(PS2Port ps2Port) {
- this.ps2Port = ps2Port;
- }
-
- @Override
- public void workWithUSB() {
- System.out.println("转换的关键在这里,本来是");
- ps2Port.workWithPS2();
- System.out.println("经过你的转换,现在是USB工作中");
- }
-
- }
TestAdapter
Java代码
- package com.zzy.adapter;
-
- /**
- * 测试类
- * client
- * @author eason
- *
- */
- public class TestAdapter {
-
- public static void main(String[] args) {
- //1.我现在有一个PS2接口
- PS2Port ps2Port = new PS2Port() {
- @Override
- public void workWithPS2() {
- System.out.println("PS2工作中");
- }
- };
-
- //2.但是我需要的是一个USB接口啊,对我(client)来说,我只认识USB接口
- //3.经过PS2ToUSB的转换,PS2接口变成了USB接口
- USBPort ps2ToUsbPort = new PS2ToUSB(ps2Port);
-
- ps2ToUsbPort.workWithUSB();
-
- }
-
- }
五.对象的适配器和类的适配器
上述的适配器就是对象适配器。再看看类适配器。
PS2ToUSB,只是简单模拟一下。因为java不允许多继承,所以java中没有类模式的代码,只有思想。
Java代码
- package com.zzy.adapter;
-
- /**
- * 类适配器
- * @author eason
- *
- */
- public class PS2ToUSB implements USBPort, PS2Port{
-
- //重写workWithUSB,把工作交给workWithPS2
- @Override
- public void workWithUSB() {
- workWithPS2();
- }
-
- }
差别就是:对象适配器实现了客户端想要的接口(USB),在内部有一个被适配对象(PS2)的引用,通过组合实现适配功能。类适配器实现了客户端想要的接口(USB)和被适配对象接口(PS2),通过继承来实现适配功能。
六.使用场景及使用感受
- 希望复用一些现存的类,但是接口又与复用环境要求不一致。
- 其实适配器模式有点无奈之举,在前期设计的时候,我们就不应该考虑适配器模式,而应该考虑通过重构统一接口。
七.适配器模式与装饰者模式
它们都可以用来包装对象,本质区别在于
- 适配器模式:将一个接口转换成另外一个接口。
- 装饰者模式:不改变接口,只加入职责。