1.适配器模式(Adapter Pattern)
1.1 概述
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。
- 适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另-一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起 工作的两个类可以协同工作。其别名为包装器(Wrapper)
- 适配器模式属于结构型模式
- 主要分为三类: 类适配器模式、对象适配器模式、接口适配器模式
1.2 意图
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
1.3 主要解决
主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。
1.4 何时使用
1、系统需要使用现有的类,而此类的接口不符合系统的需要。
2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。
3、通过接口转换,将一个类插入另一个类系中。(比如老虎和飞禽,现在多了一个飞虎,在不增加实体的需求下,增加一个适配器,在里面包容一个虎对象,实现飞的接口。)
1.5 如何解决
继承或依赖(推荐)。
1.6 关键代码
适配器继承或依赖已有的对象,实现想要的目标接口。
1.7 应用实例
- 美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V。
- JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的 Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式。
- 在 LINUX 上运行 WINDOWS 程序。
- JAVA 中的 jdbc。
1.8 优点
- 1、可以让任何两个没有关联的类一起运行。
- 2、提高了类的复用。
- 3、增加了类的透明度。
- 4、灵活性好。
1.9 缺点
1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
1.10 使用场景
有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。
1.11 注意事项
适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
1.12 代码示例
1.12.1 类适配器模式
package com.xql.designpattern.controller.adapter.classadapter;
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}
package com.xql.designpattern.controller.adapter.classadapter;
public interface IVoltage5V {
public int output5V();
}
package com.xql.designpattern.controller.adapter.classadapter;
public class Phone {
public void charging(IVoltage5V iVoltage5V) {
if(iVoltage5V.output5V() == 5) {
System.out.println("我是5V");
} else if (iVoltage5V.output5V() > 5) {
System.out.println("我是大于5V");
}
}
}
package com.xql.designpattern.controller.adapter.classadapter;
public class Voltage220V {
public int output220V() {
int src = 220;
return src;
}
}
package com.xql.designpattern.controller.adapter.classadapter;
public class VoltageAdapter extends Voltage220V implements IVoltage5V {
@Override
public int output5V() {
int srcV = output220V();
int dstV = srcV / 44 ;
return dstV;
}
}
1.12.2 对象适配器模式
package com.xql.designpattern.controller.adapter.objectadapter;
import org.springframework.web.servlet.HandlerAdapter;
public class Client {
public static void main(String[] args) {
HandlerAdapter handlerAdapter = null;
Phone phone = new Phone();
phone.charging(new VoltageAdapter(new Voltage220V()));
}
}
package com.xql.designpattern.controller.adapter.objectadapter;
public interface IVoltage5V {
public int output5V();
}
package com.xql.designpattern.controller.adapter.objectadapter;
public class Phone {
public void charging(IVoltage5V iVoltage5V) {
if(iVoltage5V.output5V() == 5) {
System.out.println("5V==============");
} else if (iVoltage5V.output5V() > 5) {
System.out.println("大于5V");
}
}
}
package com.xql.designpattern.controller.adapter.objectadapter;
public class Voltage220V {
public int output220V() {
int src = 220;
System.out.println("====" + src + "====");
return src;
}
}
package com.xql.designpattern.controller.adapter.objectadapter;
public class VoltageAdapter implements IVoltage5V {
private Voltage220V voltage220V;
public VoltageAdapter(Voltage220V voltage220v) {
this.voltage220V = voltage220v;
}
@Override
public int output5V() {
int dst = 0;
if(null != voltage220V) {
int src = voltage220V.output220V();
dst = src / 44;
System.out.println("===========" + dst);
}
return dst;
}
}
1.12.3 接口适配器模式
package com.xql.designpattern.controller.adapter.interfaceadapter;
public class Client {
public static void main(String[] args) {
AbsAdapter absAdapter = new AbsAdapter() {
@Override
public void aa() {
System.out.println("start");
}
@Override
public void dd() {
System.out.println("end");
}
};
absAdapter.aa();
absAdapter.dd();
}
}
package com.xql.designpattern.controller.adapter.interfaceadapter;
public abstract class AbsAdapter implements Interface4 {
@Override
public void aa() {
System.out.println("cccc");
}
@Override
public void bb() {
}
@Override
public void cc() {
}
}
package com.xql.designpattern.controller.adapter.interfaceadapter;
public interface Interface4 {
public void aa();
public void bb();
public void cc();
public void dd();
}
1.13 源码分析–SpringMVC
package com.xql.designpattern.controller.adapter.springadapter;
import java.util.ArrayList;
import java.util.List;
public class DispatchServlet {
public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();
public DispatchServlet() {
handlerAdapters.add(new AnnotationHandlerAdapter());
handlerAdapters.add(new HttpHandlerAdapter());
handlerAdapters.add(new SimpleHandlerAdapter());
}
public void doDispatch() {
// 此处模拟SpringMVC从request取handler的对象,
// 适配器可以获取到希望的Controller
HttpController controller = new HttpController();
// AnnotationController controller = new AnnotationController();
//SimpleController controller = new SimpleController();
// 得到对应适配器
HandlerAdapter adapter = getHandler(controller);
// 通过适配器执行对应的controller对应方法
adapter.handle(controller);
}
public HandlerAdapter getHandler(Controller controller) {
//遍历:根据得到的controller(handler), 返回对应适配器
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(controller)) {
return adapter;
}
}
return null;
}
public static void main(String[] args) {
new DispatchServlet().doDispatch(); // http...
}
}
package com.xql.designpattern.controller.adapter.springadapter;
//多种Controller实现
public interface Controller {
}
class HttpController implements Controller {
public void doHttpHandler() {
System.out.println("http...");
}
}
class SimpleController implements Controller {
public void doSimplerHandler() {
System.out.println("simple...");
}
}
class AnnotationController implements Controller {
public void doAnnotationHandler() {
System.out.println("annotation...");
}
}
package com.xql.designpattern.controller.adapter.springadapter;
///定义一个Adapter接口
public interface HandlerAdapter {
public boolean supports(Object handler);
public void handle(Object handler);
}
// 多种适配器类
class SimpleHandlerAdapter implements HandlerAdapter {
public void handle(Object handler) {
((SimpleController) handler).doSimplerHandler();
}
public boolean supports(Object handler) {
return (handler instanceof SimpleController);
}
}
class HttpHandlerAdapter implements HandlerAdapter {
public void handle(Object handler) {
((HttpController) handler).doHttpHandler();
}
public boolean supports(Object handler) {
return (handler instanceof HttpController);
}
}
class AnnotationHandlerAdapter implements HandlerAdapter {
public void handle(Object handler) {
((AnnotationController) handler).doAnnotationHandler();
}
public boolean supports(Object handler) {
return (handler instanceof AnnotationController);
}
}