经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
Java设计模式中的适配器模式
来源:jb51  时间:2022/7/19 11:03:02  对本文有异议

基本介绍

  • 适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)
  • 适配器模式属于结构型模式
  • 主要分为三类:类适配器模式、对象适配器模式、接口适配器模式

工作原理

  • 适配器模式:将一个类的接口转换成另一种接口.让原本接口不兼容的类可以兼容。
  • 从用户 的角度看不到被适配者,是解耦的。
  • 用户 调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法。
  • 用户收到反馈结果, 感觉只是和目标接口交互。

类适配器模式

背景介绍:在中国电源大都是220伏的,而日常生活中手机的充电确是5伏1安(苹果),通过类适配器模拟电源适配器实现手机充电功能

Voltage220V(被适配电源)

  1. public class Voltage220V {
  2.  
  3. public int output220V() {
  4. int src = 220;
  5. System.out.println("电压 = " + src + "伏");
  6. return src;
  7. }
  8. }

Voltage5V(目标输出)

  1. public interface Voltage5V {
  2. int output5V();
  3. }

VoltageAdapter(电源适配器)

  1. public class VoltageAdapter extends Voltage220V implements Voltage5V {
  2. @Override
  3. public int output5V() {
  4. int src = output220V();
  5. int dst = src / 44;
  6. System.out.printf("适配器将%d伏====>%d伏\n", src, dst);
  7. return dst;
  8. }
  9. }

Phone(手机充电)

  1. public class Phone {
  2. public void charging(Voltage5V v) {
  3. int src = v.output5V();
  4. if (src <= 5 && src > 0) {
  5. System.out.println("电压 = " + src + "伏,可以充电...");
  6. } else if (src > 5) {
  7. System.out.println("电压过高");
  8. } else {
  9. System.out.println("没有充电...");
  10. }
  11. }
  12. }

Client

  1. public class Client {
  2. public static void main(String[] args) {
  3. System.out.println("====类适配器模式====");
  4. Phone phone = new Phone();
  5. phone.charging(new VoltageAdapter());
  6. }
  7. }

实现结果:

类适配器模式注意事项和细节

  • Java是单继承机制,所以类适配器需要继承src类这一点算是- -一个缺点,因为这要求dst必须是接口,有一定局限性;
  • src类的方法在Adapter中都会暴露出来,也增加了使用的成本。

对象适配器模式

优点:

  • 基本思路和类的适配器模式相同,只是将Adapter类作修改,不是继承src类,而是持有src类的实例,以解决兼容性的问题。即: 持有sre类,实现dst类接口,完成src->dst的适配
  • 根据“合成复用原则”,在系统中尽量使用关联关系(聚合)来替代继承关系。
  • 对象适配器模式是适配器模式常用的一种

UML类图:

其他代码与上一致,修改电源适配器即可:

  1. public class VoltageAdapter implements Voltage5V {
  2. private Voltage220V voltage220V = null;
  3. public VoltageAdapter(Voltage220V voltage220V) {
  4. this.voltage220V = voltage220V;
  5. }
  6. @Override
  7. public int output5V() {
  8. int src = 0;
  9. if (voltage220V != null) {
  10. src = voltage220V.output220V();
  11. }
  12. int dst = src / 44;
  13. System.out.printf("适配器将%d伏====>%d伏\n",src,dst);
  14. return dst;
  15. }
  16. }

Client(测试)

  1. public class Client {
  2. public static void main(String[] args) {
  3. System.out.println("====对象适配器模式====");
  4. Phone phone = new Phone();
  5. phone.charging(new VoltageAdapter(new Voltage220V()));
  6. System.out.println("--------------------");
  7. phone.charging(new VoltageAdapter(null));
  8. }
  9. }

实现结果:

接口适配器模式

简介:

  • 一些书籍称为:适配器模式(Default Adapter Pattermn)或缺省适配器模式。
  • 核心思路:当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
  • 适用于一个接口不想使用其所有的方法的情况。

UML类图

背景介绍:模拟springMVC源码展示接口设计模式

接口适配器和实现类

  1. ///定义一个Adapter接口
  2. public interface HandlerAdapter {
  3. public boolean support(Controller handler);
  4. public void handle(Controller handler);
  5. }
  6. // 多种适配器类
  7. class SimpleHandlerAdapter implements HandlerAdapter {
  8. public void handle(Controller handler) {
  9. handler.doHandler();
  10. }
  11. public boolean support(Controller handler) {
  12. return (handler instanceof SimpleController);
  13. }
  14. }
  15. class HttpHandlerAdapter implements HandlerAdapter {
  16. public void handle(Controller handler) {
  17. handler.doHandler();
  18. }
  19. public boolean support(Controller handler) {
  20. return (handler instanceof HttpController);
  21. }
  22.  
  23. }
  24. class AnnotationHandlerAdapter implements HandlerAdapter {
  25. public void handle(Controller handler) {
  26. handler.doHandler();
  27. }
  28.  
  29. public boolean support(Controller handler) {
  30.  
  31. return (handler instanceof AnnotationController);
  32. }
  33. }

模拟Controller

  1. //多种Controller实现
  2. public interface Controller {
  3. void doHandler();
  4. }
  5. class HttpController implements Controller {
  6. @Override
  7. public void doHandler() {
  8. System.out.println("http...");
  9. }
  10. }
  11. class SimpleController implements Controller {
  12. @Override
  13. public void doHandler() {
  14. System.out.println("simple...");
  15. }
  16. }
  17. class AnnotationController implements Controller {
  18. @Override
  19. public void doHandler() {
  20. System.out.println("annotation...");
  21. }
  22. }

模拟DispatchServlet

  1. public class DispatchServlet {
  2. public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();
  3. public DispatchServlet() {
  4. handlerAdapters.add(new AnnotationHandlerAdapter());
  5. handlerAdapters.add(new HttpHandlerAdapter());
  6. handlerAdapters.add(new SimpleHandlerAdapter());
  7. }
  8. public void doDispatch(Controller controller) {
  9. // 得到对应适配器
  10. HandlerAdapter adapter = getHandler(controller);
  11. // 通过适配器执行对应的controller对应方法
  12. if (adapter != null) {
  13. adapter.handle(controller);
  14. } else {
  15. System.out.println("没有该适配器...");
  16. }
  17.  
  18. }
  19. public HandlerAdapter getHandler(Controller controller) {
  20. //遍历:根据得到的controller(handler), 返回对应适配器
  21. for (HandlerAdapter adapter : this.handlerAdapters) {
  22. if (adapter.support(controller)) {
  23. return adapter;
  24. }
  25. }
  26. return null;
  27. }
  28.  
  29. public static void main(String[] args) {
  30. new DispatchServlet().doDispatch(new SimpleController() );
  31. new DispatchServlet().doDispatch(new HttpController() );
  32. new DispatchServlet().doDispatch(new AnnotationController());
  33. }
  34.  
  35. }

实现结果:

适配器模式的注意事项和细节

  • 三种命名方式,是根据sre 是以怎样的形式给到Adapter (在Adapter里的形式)来命名的。
  • 类适配器:以类给到,在Adapter里,就是将src当做类,继承
  • 对象适配器:以对象给到,在Adapter里,将sre作为一个对象,持有
  • 接口适配器:以接口给到,在Adapter里,将src作为一个接口,实现Adapter模式最大的作用还是将原本不兼容的接口融合在一起工作。

到此这篇关于Java设计模式中的适配器模式的文章就介绍到这了,更多相关Java适配器模式内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号