在软件开发中,有时候咱们需求将一个已有的类或接口适配成另一个类或接口,以满意客户端的需求。这时候,适配器形式就能够派上用场了。适配器形式是一种常用的规划形式,它能够将一个类的接口转化成另一个客户端期望的接口,以便让两个不兼容的接口能够协同作业。适配器形式广泛运用于第三方API适配、代码重构、跨渠道开发等场景。本文将介绍适配器形式的界说、结构、完成办法和运用场景,期望可认为读者带来启示和帮助。
什么是适配器形式
官方界说
适配器形式(Adapter Pattern)是一种将一个类的接口转化成客户期望的别的一个接口,使得本来由于接口不兼容而不能一起作业的那些类能够在一起作业的规划形式。
——《规划形式:可复用面向方针软件的根底》
简略来说
适配器形式就是将一个类的接口转化成另一个接口,以满意客户端的需求。适配器形式一般运用一个适配器来完成这种转化,适配器完成了方针接口,并包装了一个适配者方针,客户端经过调用适配器的接口来直接调用适配者方针的接口。
日子中的例子
适配器形式的一个常见例子是运用墙面插座适配器来充电。在不同的国家和地区,电源插头和电压标准或许不同,因此在旅行或移居时,人们或许需求运用适配器来使自己的电子设备能够刺进当地的插座并充电。
适配器形式的结构
适配器形式的结构一般包含三个首要部分:适配器(Adapter)、适配者(Adaptee)和方针(Target)。
-
Target(方针):方针是客户端所期望的接口,它界说了客户端运用的办法和行为。
-
Adaptee(适配者):适配者是客户端本来无法直接运用的接口,它需求被适配器适配为方针接口。
-
Adapter(适配器):适配器是将适配者转化为方针接口的中间件,它完成了方针接口,并包装了一个适配者方针,在客户端调用方针接口时,适配器会直接调用适配者方针的办法,然后完成适配。
完成适配器形式
适配器有两种完成办法:
类适配器和方针适配器两种完成办法
确认这三个组成部分一般以下这几个步骤:
-
确认方针接口:首要需求确认客户端所期望的方针接口,该接口应该界说客户端需求运用的办法和行为。(Target)
-
确认适配者:需求确认需求适配的适配者方针,即客户端无法直接运用的接口。(Adaptee)
-
完成适配器:适配器的完成是适配器形式的要害,它需求完成方针接口,并包装一个适配者方针,将适配者的接口转化为方针接口的接口。适配器一般选用承继或组合的办法完成,即承继适配者类或将适配者方针作为适配器的成员变量。(Adapter)
类适配器
比如要把110V的电压适配成220V的电压
Target(方针) : 界说客户端运用的办法
// 方针接口
public interface Target {
int getVoltage();
}
Adaptee(适配者):客户端本来无法直接运用的接口即110V的电压
// 适配者类
public class Adaptee {
public int getVoltage110() {
return 110;
}
}
Adapter(适配器): 完成了方针接口,承继适配类
public class Adapter extends Adaptee implements Target{
@Override
public int getVoltage() {
// 将110V电压转化为220V电压
return super.getVoltage110()*2;
}
}
最终客户端调用
public class Client {
public static void main(String[] args) {
Adapter adapter = new Adapter();
System.out.println(adapter.getVoltage()); //成果:220
}
}
这样就运用适配器将110V转为220V了
类适配器是经过承继来完成适配器和适配者之间的联系,适配器类同时承继了适配者类和方针接口。因此,类适配器只能适配一个适配者类,并且需求注意适配者类的办法不应该和方针接口的办法冲突。此外,类适配器能够重写适配者类的办法来完成适配。
方针适配器
Target(方针) : 界说客户端运用的办法
// 方针接口
public interface Target {
int getVoltage();
}
Adaptee(适配者):客户端本来无法直接运用的接口即110V的电压
// 适配者类
public class Adaptee {
public int getVoltage110() {
return 110;
}
}
方针适配器的Adapter与类适配器不同
Adapter(适配器):完成Target,把适配者组合进Adapter
// 适配器类 (方针适配器)
public class Adapter implements Target{
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public int getVoltage() {
// 将110V电压转化为220V电压
return adaptee.getVoltage110()*2;
}
}
客户端:
public class Client {
public static void main(String[] args) {
// 创建适配者方针
Adaptee adaptee = new Adaptee();
// 创建适配器方针
Adapter adapter = new Adapter(adaptee);
// 测试适配器方针
System.out.println(adapter.getVoltage()); //成果:220
}
}
方针适配器是经过组合来完成适配器和适配者之间的联系,适配器类包含一个适配者类的实例,并完成了方针接口。由于适配器类和适配者类之间是托付联系,因此一个适配器类能够适配多个适配者类。此外,方针适配器无法重写适配者类的办法,可是能够经过调用适配者类的办法来完成适配。
总的来说,类适配器和方针适配器都有各自的优缺点,需求根据具体的场景来挑选运用哪一种。假如适配者类比较稳定,且只需求适配一个适配者类,那么能够挑选类适配器。假如适配者类比较多,或者需求动态适配适配者类,那么能够挑选方针适配器。
实践运用场景
-
第三方API适配:在运用第三方API时,有或许第三方API的接口与咱们需求的接口不一致,这时能够运用适配器形式将第三方API的接口适配为咱们需求的接口。
-
代码重构:在对已有代码进行重构时,有或许发现接口已经改变,可是为了兼容旧的代码,需求保持旧接口不变。这时能够运用适配器形式,将新接口适配为旧接口。
-
跨渠道开发:在进行跨渠道开发时,不同的渠道之间或许存在接口不兼容的情况,这时能够运用适配器形式,将不同渠道的接口适配为相同的接口,以便在不同渠道上复用代码。
-
数据库连接池适配:在运用不同的数据库连接池时,由于接口不同,需求对不同的数据库连接池进行适配,以便在不同的数据库连接池之间切换时不需求修正大量的代码。
-
设备驱动程序适配:在编写设备驱动程序时,有或许需求对不同的设备进行适配,以便在不同的设备之间切换时不需求修正大量的代码。
举一个springmvc的例子
RequestMappingHandlerAdapter类是适配器类,它完成了 HandlerAdapter 接口,将 HttpRequest 转化为 ModelAndView:
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements InitializingBean {
// 完成 HandlerAdapter 接口的办法
@Override
public boolean supports(Object handler) {
return handler instanceof HandlerMethod;
}
@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 将恳求转化为 HandlerMethod
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 执行 HandlerMethod 并回来 ModelAndView
return handleInternal(request, response, handlerMethod);
}
// ...
}
HandlerAdapter 接口是方针接口,它是 Spring MVC 结构中用于适配各种类型的处理器办法的接口:
public interface HandlerAdapter {
boolean supports(Object handler);
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
// ...
}
HandlerMethod 是适配者类,它是 Spring MVC 结构中的一个处理器办法的封装类:
public class HandlerMethod implements HandlerMethod {
// 完成 HandlerMethod 接口的办法
@Override
public Object invoke(Object... args) throws Exception {
// 调用实践的处理器办法
return method.invoke(bean, args);
}
// ...
}
总结
适配器形式的优点包含:
-
提高了体系的灵活性和扩展性,能够在不修正原有代码的情况下引入新的适配器类,契合开闭准则。
-
能够让客户端运用统一的接口来调用不同类型的适配者,减少了客户端与各种适配者的耦合。
-
能够让适配者的接口与方针接口分离,契合单一职责准则和接口阻隔准则。
适配器形式的缺点包含:
-
适配器过多会添加体系的复杂度和维护本钱。
-
类适配器形式在适配者类的办法发生变化时或许会影响到方针接口,由于适配器类和适配者类是经过承继联系关联的。
-
方针适配器形式需求额定的适配器方针,添加了内存开支。