当前位置: 首页 > news >正文

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

文章目录

  • 第七章_适配器模式
  • 1.介绍
    • 1.1定义
    • 1.2使用场景
      • 1.2.1生活场景
      • 1.2.2java场景
    • 1.3角色
  • 2.举例
    • 2.1共同代码
      • 2.1.1圆形接口和正方形接口—目标接口
      • 2.1.2具体的圆形和正方形类
    • 2.2类适配器
      • 2.2.1测试
    • 2.3接口适配器
      • 2.3.1测试
    • 2.4对象适配器
      • 2.4.1抽象适配器类
      • 2.4.2具体适配器类
    • 3.优缺点

第七章_适配器模式

  • 参考文章连接: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;}@Overridepublic double getRadius() {return radius;}
}public class SquareImpl implements Square {private double sideLength;public SquareImpl(double sideLength) {this.sideLength = sideLength;}@Overridepublic double getSideLength() {return sideLength;}
}

2.2类适配器

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

/**
*	将圆形适配成正方形
*/
public class ShapeAdapter extends CircleImpl implements Square {public ShapeAdapter(double radius) {super(radius);}/*** 实现目标接口方法,并调用被适配类的方法,* 根据圆形的半径来计算一个等价面积的正方形的边长,返回可以代表相同面积的正方形的边长*/@Overridepublic 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.85double squareArea = Math.pow(square.getSideLength(), 2);		//将圆适配成正方形,System.out.println("Circle area: " + circleArea); // 输出:Circle area: 78.53981633974483System.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;}@Overridepublic 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.53981633974483System.out.println("Square area: " + squareArea); // 输出:Square area: 50.0}
}

2.4对象适配器

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

2.4.1抽象适配器类

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

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

2.4.2具体适配器类

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

public class CircleAdapter extends ShapeAdapter {private Circle circle;public CircleAdapter(Circle circle) {this.circle = circle;}@Overridepublic double getSideLength() {return circle.getRadius() * 2 / Math.sqrt(2);}
}

3.优缺点

优点:

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

缺点

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

相关文章:

  • 《剑指offer》
  • 基于HTML5实现动态烟花秀效果(含音效和文字)实战
  • Netty应用(一) 之 NIO概念 基本编程
  • 2.15题目
  • 抽象的前端
  • 初识webpack(二)解析resolve、插件plugins、dev-server
  • 【AI视野·今日NLP 自然语言处理论文速览 第七十九期】Thu, 18 Jan 2024
  • java.lang.NoClassDefFoundError: org/springframework/core/GenericTypeResolver
  • mongodb 导出数据
  • 【并发编程】AQS原理
  • LCP 30. 魔塔游戏
  • Bean 的六种作用域
  • Flink理论—容错之状态
  • 【报错解决】-bash: export: `-8‘: not a valid identifier 不是有效的标识符
  • 【算法题】93. 复原 IP 地址
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • C++11: atomic 头文件
  • Java应用性能调优
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • JS基础之数据类型、对象、原型、原型链、继承
  • js正则,这点儿就够用了
  • nginx 配置多 域名 + 多 https
  • Promise面试题2实现异步串行执行
  • Python中eval与exec的使用及区别
  • Sublime text 3 3103 注册码
  • vue-router的history模式发布配置
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 飞驰在Mesos的涡轮引擎上
  • 嵌入式文件系统
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • # 透过事物看本质的能力怎么培养?
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #vue3 实现前端下载excel文件模板功能
  • #大学#套接字
  • (C语言)球球大作战
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (第一天)包装对象、作用域、创建对象
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .net core Swagger 过滤部分Api
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .net framework 4.0中如何 输出 form 的name属性。
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .netcore如何运行环境安装到Linux服务器
  • .net反编译工具
  • .net和jar包windows服务部署
  • [20190113]四校联考
  • [22]. 括号生成
  • [Android]使用Retrofit进行网络请求
  • [AutoSar]工程中的cpuload陷阱(三)测试
  • [BZOJ1178][Apio2009]CONVENTION会议中心