【从零开始学设计模式】第七章_适配器模式

第七章_适配器模式

  • 参考文章连接:https://blog.csdn.net/weixin_45433817/article/details/131153032
  • 作者:橡 皮 人

1.介绍

1.1定义

适配器模式:将不兼容的对象转换成可兼容的接口,创建一个==中间转换的适配器==来将一个对象转换成我们所需要的接口

1.2使用场景

1.2.1生活场景

  • 电压转换器:不同国家的电压规格各异,同样功率的电器在不同的地方工作时需要不同的电压,电压转换器作为适配器,将不同电压转换成电器使用标准电压。
  • 耳机转接头:有些手机没有耳机插口,需要使用转接头适配器,将耳机转换为手机支持的接口,实现对不同的耳机兼容。

1.2.2java场景

  • JDBC驱动程序:不同的数据库提供商实现了不同的JDBC驱动接口,使用适配器模式可以将这些不同的接口适配为标准的JDBC接口,提高应用程序的可移植性。
  • 日志框架:Java中有多个常用的日志框架,如Log4j、SLF4J等,不同的日志框架提供的API不同,使用适配器模式可以将这些不同的API适配为一个统一的接口,方便再程序中进行日志记录和管理。
  • 第三方库或SDK:在使用第三方库或 SDK 时,可能由于它们实现的 API 不同而导致应用程序复杂,使用适配器模式可以将不同的 API 适配为统一的接口,简化应用程序的调用。

1.3角色

  • 目标接口(target):需要适配的标准接口。
  • 源对象(source):需要被适配的不兼容对象。
  • 适配器对象(adapter):充当中间转换角色,该对象将源对象转换成目标接口,有多个!

2.举例

三个角色其中,适配器对象有三种,分别为类适配器、接口适配器、对象适配器

  • 类适配器:使用继承的方式,将需要适配的类转换为目标接口的子类,实现目标接口的所有方法,同时继承适配类的实现,用以完成一些适配逻辑。
  • 接口适配器
  • 对象适配器

假设我们有一个圆形接口和一个正方形接口,但是客户端代码需要使用一个统一的接口来计算==不同形状的面积==

2.1共同代码

2.1.1圆形接口和正方形接口—目标接口

即目标接口,需要适配的标准接口,含求面积方法

/**
* 	圆形接口
*/
public interface Circle {
   
    //获取半径
    double getRadius();
}

/**
* 	正方形接口
*/
public interface Square {
   
    //获取边长
    double getSideLength();
}

2.1.2具体的圆形和正方形类

public class CircleImpl implements Circle {
   
    private double radius;

    public CircleImpl(double radius) {
   
        this.radius = radius;
    }

    @Override
    public double getRadius() {
   
        return radius;
    }
}

public class SquareImpl implements Square {
   
    private double sideLength;

    public SquareImpl(double sideLength) {
   
        this.sideLength = sideLength;
    }

    @Override
    public double getSideLength() {
   
        return sideLength;
    }
}

2.2类适配器

定义一个类适配器,实现目标接口并继承被适配类,并在目标接口方法中调用被适配类的方法,从而将目标接口转换为被适配类的方法调用

/**
*	将圆形适配成正方形
*/
public class ShapeAdapter extends CircleImpl implements Square {
   
    public ShapeAdapter(double radius) {
   
        super(radius);
    }

    /**
    * 实现目标接口方法,并调用被适配类的方法,
    * 根据圆形的半径来计算一个等价面积的正方形的边长,返回可以代表相同面积的正方形的边长
    */
   	@Override
	public double getSideLength() {
   
    	return getRadius() * 2 / Math.sqrt(2);
	}
}

2.2.1测试

public class Client {
   
    public static void main(String[] args) {
   
        Circle circle = new CircleImpl(5);			//实例半径为5的圆的对象
        Square square = new ShapeAdapter(5);		//

        double circleArea = Math.PI * Math.pow(circle.getRadius(), 2);	//计算半径为5的圆的面积:7.85
        double squareArea = Math.pow(square.getSideLength(), 2);		//将圆适配成正方形,

        System.out.println("Circle area: " + circleArea); // 输出:Circle area: 78.53981633974483
        System.out.println("Square area: " + squareArea); // 输出:Square area: 50.0
    }
}

2.3接口适配器

定义一个接口适配器,将适配对象与目标接口组合并在适配类中调用需要适配对象的方法。

public class CircleAdapter implements Square {
   
    private Circle circle;

    public CircleAdapter(Circle circle) {
   
        this.circle = circle;
    }

    @Override
    public double getSideLength() {
   
        return circle.getRadius() * 2 / Math.sqrt(2);
    }
}

2.3.1测试

public class Client {
   
    public static void main(String[] args) {
   
        Circle circle = new CircleImpl(5);
        Square square = new CircleAdapter(circle);

        double circleArea = Math.PI * Math.pow(circle.getRadius(), 2);
        double squareArea = Math.pow(square.getSideLength(), 2);

        System.out.println("Circle area: " + circleArea); // 输出:Circle area: 78.53981633974483
        System.out.println("Square area: " + squareArea); // 输出:Square area: 50.0
    }
}

2.4对象适配器

主要适用于需要被适配的接口中,只有用到个别接口,也就是说不需要实现它的全部接口。通过一个中间抽象类或接口实现。

2.4.1抽象适配器类

定义一个抽象适配器类,它实现了目标接口并提供了默认实现

public abstract class ShapeAdapter implements Square {
   
    @Override
    public double getSideLength() {
   
        return 0;
    }
}

2.4.2具体适配器类

定义一个具体的适配器类,它继承了抽象适配器类并实现了需要的目标接口方法,并调用被适配器的方法

public class CircleAdapter extends ShapeAdapter {
   
    private Circle circle;

    public CircleAdapter(Circle circle) {
   
        this.circle = circle;
    }

    @Override
    public double getSideLength() {
   
        return circle.getRadius() * 2 / Math.sqrt(2);
    }
}

3.优缺点

优点:

  • 安全可靠:封装了旧接口,对客户端透明,客户端代码无需修改。
  • 提高复用性:可以复用不兼容的类;可以对不同的类无需修改,就可以进行组合。
  • 扩展性好:在应用程序开发过程中,可以增加新的适配器和被适配对象。

缺点

  • 过多的适配器会导致系统结构复杂。
  • 如果适配器没有实现好,可能会拖慢整个系统的性能。
  • 滥用适配器模式会导致系统设计紊乱。

相关推荐

  1. 开始设计模式_适配器模式

    2024-02-09 07:38:02       32 阅读
  2. 开始设计模式_工厂模式

    2024-02-09 07:38:02       32 阅读
  3. 开始设计模式】第一_设计模式简介

    2024-02-09 07:38:02       36 阅读
  4. 开始设计模式】第二_单例模式

    2024-02-09 07:38:02       28 阅读
  5. 设计模式浅析() ·适配器模式

    2024-02-09 07:38:02       31 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-09 07:38:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-09 07:38:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-09 07:38:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-09 07:38:02       18 阅读

热门阅读

  1. 算法典题 ---- 持续更新中

    2024-02-09 07:38:02       39 阅读
  2. go单元测试之benchmark基准测试详解

    2024-02-09 07:38:02       30 阅读
  3. C语言中的字符串

    2024-02-09 07:38:02       28 阅读
  4. flutter 国内源

    2024-02-09 07:38:02       28 阅读
  5. 深度学习的进展

    2024-02-09 07:38:02       27 阅读
  6. 记录关于 LLVM C/C++ 适用 libc++ 的一些注意事项

    2024-02-09 07:38:02       36 阅读
  7. Vue中的 v-if 与 v-show 的区别

    2024-02-09 07:38:02       29 阅读