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

关于适配器模式,我遗漏了什么

近期有些tasks需要 重构or适配 老的代码。

与其向上面堆💩,不如优雅的去解决。

首先我的问题在于,错误的把 堆屎的操作 ,当作了适配器模式的操作。

比如原函数入参,需要更改某个属性,把这种操作外包一层套进去,就是堆屎。

适配器模式的重点在于:适配器实现目标接口,并且持有适配者的实例

做法是:转换一个接口到另一个接口。(这个经常和外观模式搞混)

实际工作中尝试使用虚方法去实现,让前端的调用为被转换过的接口。

虚方法:

1、virtual方法表示此方法可以被重写, 也就是说这个方法具有多态.父类中的方法是通用方法,可以在子类中重写以重新规定方法逻辑.

2、virtual方法可以直接使用,和普通方法一样

3、不是必须重写的. 子类可以使用base.方法 的方式调用, 无论有没有在子类使用override去重写

virtual关键字只是明确标示此方法可以被重写, 其实它和一般的方法没有什么区别

适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。

但是我偏要用类适配器!

类适配器

类适配器:适配器继承适配对象,并实现适配目标的所有方法

public interface EuropeSocket {/** 欧式三叉 通电 接通电 插座*/String useEuropesocket();
}// 欧式三叉实现类
public class EuropeSocketImpl implements EuropeSocket {@Overridepublic String useEuropesocket() {String msg ="使用欧式三叉充电";return msg;}
}
public interface ChineseSocket {/*** 使用中国双叉充电* @return*/String useChineseSocket();
}// 中国插头的实现类
public class ChineseSocketImpl implements ChineseSocket {@Overridepublic String useChineseSocket() {String msg="使用中国双叉充电";return msg;}
}
/*** 定义适配器类 中国双叉转为欧洲三叉**/
public class ChineseAdapterEurope extends EuropeSocketImpl implements ChineseSocket {@Overridepublic String useChineseSocket() {System.out.println("使用转换器转换完成");return useEuropesocket();}
}

开始使用测试!

public class Computer {public String useChineseSocket(ChineseSocket chineseSocket) {if(chineseSocket == null) {throw new NullPointerException("sd card null");}return chineseSocket.useChineseSocket();}
}

提前注:父类声明子类实例化产生的对象使用的是子类从父类继承的方法和属性。 

父类声明子类实例化对象详解_扶公瑾以苏的博客-CSDN博客_c父类对象由子类实例化

public class Client {public static void main(String[] args) {Computer computer = new Computer();ChineseSocket chineseSocket = new ChineseSocketImpl();System.out.println(computer.useChineseSocket(chineseSocket));System.out.println("------------");ChineseAdapterEurope adapter = new ChineseAdapterEurope();System.out.println(computer.useChineseSocket(adapter));/*** 输出:* 使用中国双叉充电* ------------* 使用转换器转换完成* 使用欧式三叉充电*/}
}

对象适配器

实现方式:对象适配器模式可釆用将现有组件库中已经实现的组件引入适配器类中,该类同时实现当前系统的业务接口

题目还是和上面一样的哈。代码其实差异很小

目标(Target)接口:即图中的欧式三叉

public interface EuropeSocket {/** 欧式三叉 通电 接通电 插座*/String useEuropesocket();
}// 欧式三叉实现类
public class EuropeSocketImpl implements EuropeSocket {@Overridepublic String useEuropesocket() {String msg ="使用欧式三叉充电";return msg;}
}
复制代码

适配者(Adaptee):即中国双叉

public interface ChineseSocket {/*** 使用中国双叉充电* @return*/String useChineseSocket();
}// 中国插头的实现类
public class ChineseSocketImpl implements ChineseSocket {@Overridepublic String useChineseSocket() {String msg="使用中国双叉充电";return msg;}
}
复制代码

适配器(Adapter)类: 就是这个适配器内做了一些更改 从继承改为了成员变量的方式

public class ChineseAdapterEurope implements ChineseSocket {private EuropeSocket europeSocket;public ChineseAdapterEurope(EuropeSocket europeSocket) {this.europeSocket = europeSocket;}@Overridepublic String useChineseSocket() {System.out.println("使用转换器转换完成");return europeSocket.useEuropesocket();}
}
复制代码

电脑类

public class Computer {public String useChineseSocket(ChineseSocket chineseSocket) {if(chineseSocket == null) {throw new NullPointerException("sd card null");}return chineseSocket.useChineseSocket();}
}
复制代码

测试:

public class Client {public static void main(String[] args) {Computer computer = new Computer();ChineseSocket chineseSocket = new ChineseSocketImpl();System.out.println(computer.useChineseSocket(chineseSocket));System.out.println("------------");//这里做了更改EuropeSocket europeSocket=new EuropeSocketImpl();ChineseAdapterEurope adapter = new ChineseAdapterEurope(europeSocket);System.out.println(computer.useChineseSocket(adapter));/*** 输出:* 使用中国双叉充电* ------------* 使用转换器转换完成* 使用欧式三叉充电*/}
}

适合于解决问题常见:

  •  需要的东西有,但不能用,且短时间无法改造。即,使得一个功能适合不同的环境。
  •   在开发中,系统的数据、行为都匹配,但接口不符时,可以考虑适配器。
  •   希望复用一些现存的类,但是接口又与复用环境的要求不一致,应该考虑用适配器模式。(使用一个已经存在的类,但它的接口(即,方法),与需要的不相同时)

2023/2/12

划重点:希望复用一些现存的类,但是接口又与复用环境的要求不一致,应该考虑用适配器模式。(使用一个已经存在的类,但它的接口(即,方法),与需要的不相同时)

这个正是我现在面临的问题。

总之,时间足够我就优雅的,完美的去建立一个可扩展性强的适配层。

如果催我。那我就堆堆乐 💩💩💩

references:

Java设计模式-适配器模式 理论代码相结合 - 掘金

http://www.lryc.cn/news/4149.html

相关文章:

  • SQL Serve 日志体系结构
  • 【C++1】函数重载,类和对象,引用,string类,vector容器,类继承和多态,/socket,进程信号,public,ooci
  • asio网络编程 tcp、udp、rpc
  • 双目测距------双目相机V1.0,将双目相机采集到任意一点的深度数据进行串口传输(带源码)
  • jetson nano(ubuntu)安装Cmake
  • 图的基本介绍和表示方式
  • 本周大新闻|传微软解散工业元宇宙团队,MIT研发垂直堆叠全彩Micro LED
  • SpringMVC:拦截器(12)
  • 计算机网络3:HTTP1.0和HTTP1.1的区别
  • Urho3D 编辑器说明
  • C++类基础(十一)
  • Windows安装系列:SVN Server服务
  • 快速傅里叶算法(FFT)快在哪里?
  • 利用Markdown写学术论文资料汇总贴
  • MySQL 高级查询
  • JavaSE学习day4_01 循环for,while,do...while
  • C/C++中的static关键字
  • 67 自注意力【动手学深度学习v2】
  • 电子学会2022年12月青少年软件编程(图形化)等级考试试卷(二级)答案解析
  • 关于链表中插入结点的操作……
  • 【项目精选】百货中心供应链管理系统
  • Qt优秀开源项目之十六:SQLite数据库管理系统—SQLiteStudio
  • Python __doc__属性:查看文档
  • 电子科技大学操作系统期末复习笔记(一):操作系统概述
  • [实践篇]13.20 Qnx进程管理slm学习笔记(三)
  • 冰冰学习笔记:多线程
  • 补充一些前端面试题
  • 七大设计原则之单一职责原则应用
  • [USACO23JAN] Leaders B
  • C++模板初阶