赞
踩
不同国家的插座不同,出国旅游充电器不能直接使用,可以通过使用多功能转换插头
来辅助使用
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)
适配器模式属于结构型模式(没有产生什么新对象,只是结构的一些调整,让类与类之间可以协调工作)
很多时候,我们加入项目组的时候,项目已经有一定的代码量了,或者部分代码已经在生产环境上面使用了,这些方法已经经过测试,在我们开发新的项目时,可以将这些类作为组件重复利用,但是可能没办法直接调用,需要我们使用适配器模式来让这些方法适配我们的现有项目。
疑问:直接修改之前的类不就可以了吗,为啥要使用适配器模式?答:之前的类都比较完善了,如果在上面改乱了,出了bug不好调试,但是如果使用了适配器模式,那出了bug就知道是适配器的问题。此外,在Adapter模式中,并非一定需要现成的代码。只要知道现有类的功能,就可以编写出新的类。
适配器模式还能用于做新旧版本的兼容,可以让新版本扮演Adaptee 角色,旧版本扮演Target角色。接着编写一个扮演Adapter 角色的类,让它使用新版本的类来实现旧版本的类中的方法。如下图
【被适配的类】
package com.atguigu.adapter.classadapter; /** * 被适配的类 */ public class Voltage220V { /** * 输出220V的电压 * @return */ public int output220V() { int src = 220; System.out.println("电压=" + src + "伏"); return src; } }
【适配接口】
package com.atguigu.adapter.classadapter;
/**
* 适配接口
*/
public interface IVoltage5V {
public int output5V();
}
【适配器】
package com.atguigu.adapter.classadapter; /** * 适配器类 将220V转化为5V */ public class VoltageAdapter extends Voltage220V implements IVoltage5V { @Override public int output5V() { //获取到220V电压 int srcV = output220V(); //转成 5v(降压) int dstV = srcV / 44 ; return dstV; } }
【手机类】
package com.atguigu.adapter.classadapter; public class Phone { /** * 手机充电方法 * @param iVoltage5V */ public void charging(IVoltage5V iVoltage5V) { if(iVoltage5V.output5V() == 5) { System.out.println("电压为5V, 可以充电~~"); } else if (iVoltage5V.output5V() > 5) { System.out.println("电压过高, 不能充电~~"); } } }
【客户端:用户给手机充电】
package com.atguigu.adapter.classadapter;
public class Client {
public static void main(String[] args) {
System.out.println(" === 类适配器模式 ====");
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}
【运行】
=== 类适配器模式 ====
电压=220伏
电压为5V, 可以充电~~
Process finished with exit code 0
【优点】
【缺点】
【src】
package com.atguigu.adapter.Sample1; public class Banner { private String string; public Banner(String string) { this.string = string; } public void showWithParen() { System.out.println("(" + string + ")"); } public void showWithAster() { System.out.println("*" + string + "*"); } }
【dst】
package com.atguigu.adapter.Sample1;
public interface Print {
public abstract void printWeak();
public abstract void printStrong();
}
【适配器】
package com.atguigu.adapter.Sample1;
public class PrintBanner extends Banner implements Print {
public PrintBanner(String string) {
super(string);
}
public void printWeak() {
showWithParen();
}
public void printStrong() {
showWithAster();
}
}
【客户端】
package com.atguigu.adapter.Sample1;
public class Main {
public static void main(String[] args) {
Print p = new PrintBanner("Hello");
p.printWeak();
p.printStrong();
}
}
【运行】
(Hello)
*Hello*
Process finished with exit code 0
【分析】
对Main类的代码而言,Banner类、showWithParen方法和showWithAster 方法被完全隐藏起来了。这就好像笔记本电脑只要在直流12伏特电压下就能正常工作,但它并不知道这12伏特的电压是由适配器将100伏特交流电压转换而成的。Main类并不知道PrintBanner类是如何实现的,这样就可以在不用对Main类进行修改的情况下改变PrintBanner类的具体实现。
【适配器类】
package com.atguigu.adapter.objectadapter; /** * 适配器类 */ public class VoltageAdapter implements IVoltage5V { /** * 关联关系-聚合 */ private Voltage220V voltage220V; /** * 通过构造器,传入一个 Voltage220V 实例 * * @param voltage220v */ public VoltageAdapter(Voltage220V voltage220v) { this.voltage220V = voltage220v; } @Override public int output5V() { int dst = 0; if (null != voltage220V) { //获取220V 电压 int src = voltage220V.output220V(); System.out.println("使用对象适配器,进行适配~~"); dst = src / 44; System.out.println("适配完成,输出的电压为=" + dst); } return dst; } }
【客户端:用户给手机充电】
package com.atguigu.adapter.objectadapter;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(" === 对象适配器模式 ====");
Phone phone = new Phone();
phone.charging(new VoltageAdapter(new Voltage220V()));
}
}
其他类和类适配器模式的一致
【优点】
【dst】
package com.atguigu.adapter.Sample2;
public abstract class Print {
public abstract void printWeak();
public abstract void printStrong();
}
【适配器】
package com.atguigu.adapter.Sample2;
public class PrintBanner extends Print {
private Banner banner;
public PrintBanner(String string) {
this.banner = new Banner(string);
}
public void printWeak() {
banner.showWithParen();
}
public void printStrong() {
banner.showWithAster();
}
}
其他两个类的和类适配器模式的例2的代码一致
默认实现(空方法)
,那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求
【接口】
package com.atguigu.adapter.interfaceadapter;
public interface Interface4 {
public void m1();
public void m2();
public void m3();
public void m4();
}
【抽象类:适配器】
package com.atguigu.adapter.interfaceadapter; /** * 在AbsAdapter 我们将 Interface4 的方法进行默认实现(空实现) */ public abstract class AbsAdapter implements Interface4 { @Override public void m1() { } @Override public void m2() { } @Override public void m3() { } @Override public void m4() { } }
【客户端:重写抽象类的方法】
package com.atguigu.adapter.interfaceadapter; public class Client { public static void main(String[] args) { AbsAdapter absAdapter = new AbsAdapter() { /** * 只需要去覆盖我们 需要使用 接口方法 */ @Override public void m1() { System.out.println("使用了m1的方法"); } }; absAdapter.m1(); } }
HandlerAdapter
使用了适配器模式【Controller】
package com.atguigu.spring.springmvc; /** * 多种Controller实现 */ public interface Controller { } //-----------------针对不同的请求,有多种不同的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.atguigu.spring.springmvc; /** * 定义一个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(); } /** * 判断是否支持该handler * @param handler * @return */ 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); } }
【servlet】
package com.atguigu.spring.springmvc; 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); } /** * 根据controller返回对应的适配器 * @param controller * @return */ 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... } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。