• Java学习 --- 设计模式的适配器模式


    目录

    一、适配器模式

    二、适配器模式工作原理

     三、三种适配器模式的实现

    3.1、类适配器模式

    3.2、对象适配器模式

    3.3、接口适配器模式

    四、适配器模式在springMVC中的使用

     五、适配器的注意实现


    一、适配器模式

    1、适配器模式(Adapeter Pattern)将某个类的接口转换成客户端期待的另一个接口表示,主要目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作,又称包装器。

    2、适配器模式属于结构型模式

    3、主要有三种:类适配器模式、对象适配器模式、接口适配器模式。

    二、适配器模式工作原理

    1、将一个类的接口转换成另一个接口,让原本接口不兼容的类可以兼容

    2、从用户的角度看不到被适配者,是解耦的。

    3、用户调用适配器转化出来的目标接口方法,适配器再被适配者的相关接口方法。

    4、用户收到反馈结果,只是觉得和目标结果交互。

     三、三种适配器模式的实现

    3.1、类适配器模式

    Adapter类通过继承src类,实现dst类接口,完成适配。

    问题需求:220v的交流电需要是充电器适配给需要5v交流电的手机。

    示例参考代码:

    1. //被适配类
    2. public class Voltage {
    3. public int output220(){
    4. int src = 220;
    5. return src;
    6. }
    7. }
    1. //适配接口
    2. public interface IVoltage {
    3. public int output5();
    4. }
    1. public class VoltageAdapter extends Voltage implements IVoltage {
    2. @Override
    3. public int output5() {
    4. //获取220v
    5. int srcV = super.output220();
    6. int dstV = srcV / 44; //转换为5v电压
    7. return dstV;
    8. }
    9. }
    1. public class Phone {
    2. //充电
    3. public void charging(IVoltage iVoltage){
    4. int src = iVoltage.output5();
    5. if (src == 5){
    6. System.out.println("可以正常充电");
    7. }else {
    8. System.out.println("不可以正常充电");
    9. }
    10. }
    11. }
    1. public class Client {
    2. public static void main(String[] args) {
    3. Phone phone = new Phone();
    4. phone.charging(new VoltageAdapter());
    5. }
    6. }

    代码分析:

    1、Java是单继承机制,所以类适配器需要继承Voltage类是一个缺点,因为IVoltage必须是接口,有一定局限性。

    2、Voltage类的方法会在VoltageAdapter类暴露出来,增加了使用成本。

    3、因为继承了Voltage类,所以可以根据需要重写Voltage类的方法,使VoltageAdapter类更加灵活

    3.2、对象适配器模式

    1、将VoltageAdapter做修改,不再继承Voltage类,而是持有Voltage类,解决兼容性的问题。

    2、根据“合成复用原则”,尽量使用关联关系替代继承关系。

    3、对象适配器模式是适配器模式常用一种

    示例参考代码:

    其他代码不变,只需要修改这两个类:

    1. public class VoltageAdapter implements IVoltage {
    2. private Voltage voltage;
    3. //通过构造器传入Voltage实例
    4. public VoltageAdapter(Voltage voltage) {
    5. this.voltage = voltage;
    6. }
    7. @Override
    8. public int output5() {
    9. int dst = 0;
    10. if (voltage != null){
    11. int src = voltage.output220();
    12. dst = src / 44;
    13. }
    14. return dst;
    15. }
    16. }
    1. public class Client {
    2. public static void main(String[] args) {
    3. Phone phone = new Phone();
    4. phone.charging(new VoltageAdapter(new Voltage()));
    5. }
    6. }

    代码分析:

    1、对象适配器与类适配器思想相同,只是实现方式不同。根据合成复用原则,使用组合替代继承,解决了类适配器必须继承的局限性问题,不再要求IVoltage为接口。

    2、使用成本更低,更灵活。

    3.3、接口适配器模式

    1、当不需要全部实现接口提供的方法时,设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。

    2、适合使用于一个接口不想使用其所有的方法的情况。

    示例参考代码:

    1. public interface Interface1 {
    2. public void m1();
    3. public void m2();
    4. public void m3();
    5. }
    1. //对Interface1的方法进行默认实现
    2. public abstract class AbsAdepter implements Interface1 {
    3. @Override
    4. public void m1() {
    5. }
    6. @Override
    7. public void m2() {
    8. }
    9. @Override
    10. public void m3() {
    11. }
    12. }
    1. public class Client {
    2. public static void main(String[] args) {
    3. AbsAdepter absAdepter = new AbsAdepter(){
    4. @Override
    5. public void m1() {
    6. super.m1();
    7. System.out.println("m1方法使用");
    8. }
    9. };
    10. absAdepter.m1();
    11. }
    12. }

    四、适配器模式在springMVC中的使用

    1、springMVC中的HandlerAdapter中使用

     当请求过来时会在DispatcherServlet调用doDispatch方法

     mappedHandler相当于控制器,通过mappedHandler调用getHandler方法返回一个适配器

     在这里会返回一个适配器

     通过得到的适配器调用handle方法。

    模拟springmvc通过适配器获取对应controller的源码

    参考代码实现:

    1. //多种Controller实现
    2. public interface Controller {
    3. }
    4. class HttpController implements Controller{
    5. public void doHttpHandler(){
    6. System.out.println("http...");
    7. }
    8. }
    9. class SimpleController implements Controller{
    10. public void doSimplerHandler(){
    11. System.out.println("simple...");
    12. }
    13. }
    14. class AnnotationController implements Controller{
    15. public void doAnnotationHandler(){
    16. System.out.println("annotation...");
    17. }
    18. }
    1. //定义一个Adepter接口
    2. public interface HandlerAdepter {
    3. public boolean supports(Object handler);
    4. public void handler(Object handler);
    5. }
    6. //多种适配器类
    7. class SimpleHandlerAdepter implements HandlerAdepter{
    8. @Override
    9. public boolean supports(Object handler) {
    10. return (handler instanceof SimpleController);
    11. }
    12. @Override
    13. public void handler(Object handler) {
    14. ((SimpleController) handler).doSimplerHandler();
    15. }
    16. }
    17. class AnnotationHandlerAdepter implements HandlerAdepter{
    18. @Override
    19. public boolean supports(Object handler) {
    20. return (handler instanceof AnnotationController);
    21. }
    22. @Override
    23. public void handler(Object handler) {
    24. ((AnnotationController) handler).doAnnotationHandler();
    25. }
    26. }
    27. class HttpHandlerAdepter implements HandlerAdepter{
    28. @Override
    29. public boolean supports(Object handler) {
    30. return (handler instanceof HttpController);
    31. }
    32. @Override
    33. public void handler(Object handler) {
    34. ((HttpController) handler).doHttpHandler();
    35. }
    36. }
    1. public class DispatchServlet {
    2. public static void main(String[] args) {
    3. new DispatchServlet().doDispatch();
    4. }
    5. public static List handlerAdepters = new ArrayList<>();
    6. public DispatchServlet() {
    7. handlerAdepters.add(new AnnotationHandlerAdepter());
    8. handlerAdepters.add(new HttpHandlerAdepter());
    9. handlerAdepters.add(new SimpleHandlerAdepter());
    10. }
    11. public void doDispatch(){
    12. //模拟SpringMVC从request取handler的对象
    13. //适配器可以获取到希望的controller
    14. AnnotationController annotationController = new AnnotationController();
    15. //得到对应的适配器
    16. HandlerAdepter handler = getHandler(annotationController);
    17. //通过适配器执行对应的controller代码
    18. handler.handler(annotationController);
    19. }
    20. public HandlerAdepter getHandler(Controller controller){
    21. for (HandlerAdepter adepter: this.handlerAdepters) {
    22. if (adepter.supports(controller)){
    23. return adepter;
    24. }
    25. }
    26. return null;
    27. }
    28. }

    1、springMVC定义一个适配器接口,使得每一种Controller有一种对应的适配器实现类适配器代替controller执行相应的方法。

    2、在扩展Controller时,只需要增加一个适配器类就完成了springMVC的扩展。

     五、适配器的注意实现

    1、三种命名方式,是根据src是以怎样的形式给到Adapter来命令。

    2、类适配器:以类给到,在Adapter里,就是将src当做类,继承。

          对象适配器:以对像给到,在Adapter里 ,将src作为一个对象,持有。

          接口适配器:以接口给到。在Adapter里,将src作为一个接口,实现。

    3、Adapter模式最大的作用还是将原本不兼容的接口融合在一起工作。

  • 相关阅读:
    8Manage:电子寻源采购管理指南
    MinGW——检查版本的命令
    Vue 的生命周期之间到底做了什么事清?(源码详解)
    SQL查询语句之查询数据
    1.1.2开发基础-硬件-逻辑分析仪
    不理解路径问题的大坑记录
    css如何给盒子底部加阴影,CSS3 --添加阴影(盒子阴影、文本阴影的使用)
    sobel边缘检测算法
    23种设计模式之享元模式
    x.ai还是OpenAI?埃隆·马斯克的AI帝国【2】
  • 原文地址:https://blog.csdn.net/qq_46093575/article/details/126169680