适配器模式

一.什么是适配器模式🍓

适配器模式 ‌是一种结构型 设计模式,它将一个类的接口转换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够协同工作。这种模式的主要目的是提高代码的可重用性和可维护性。‌

适配器模式的工作原理是通过创建一个适配器类,该类包含一个‌源接口和一个目标接口。适配器类将客户端请求转换为源接口可以理解的命令,并执行相应的操作。这样,客户端只需要与适配器交互,而不需要直接与源接口交互,从而实现了接口的转换和适配。

适配器模式的应用场景通常包括已经存在的类,其方法和需求不匹配的情况。通过适配器模式,可以将不同的接口统一起来,使得原本无法协同工作的类能够一起工作。例如,‌电源适配器和‌USB转接头都是适配器模式的实际应用例子。‌

适配器模式主要分为三类:类适配器模式、对象适配器模式和接口适配器模式。类适配器模式通过继承源类和实现目标接口来实现适配,而对象适配器模式则通过组合源对象和实现目标接口来达到适配的目的

一.类适配器🌺:

Adpter是具体的适配器既实现了目标接口Target,又继承了目前要适配的类Adaptee。

例子一:

一个接口:官方输出方式

两个类:我的输出方式和输出适配器。

目的:将我的输出方式通过适配器转换成三种官方输出,分别是大写,小写,ASCII码。

UML图如下:

PrintAdapter.java

java 复制代码
package 二十三种设计模式之适配器模式;

public class PrintAdapter extends MyPrint implements OfficialPrint{

	PrintAdapter(String words) {
		super(words);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void ToUpperChar() {
		// TODO Auto-generated method stub
		for(int i=0;i<getWords().length();i++) {
		char word=getWords().charAt(i);
		System.out.print(Character.toUpperCase(word));
		}
	
	}

	@Override
	public void ToLowerChar() {
		// TODO Auto-generated method stub
		for(int i=0;i<getWords().length();i++) {
			char word=getWords().charAt(i);
			System.out.print(Character.toLowerCase(word));
			}
	}

	@Override
	public void ToASCII() {
		// TODO Auto-generated method stub
		for(int i=0;i<getWords().length();i++) {
			char word=getWords().charAt(i);
			System.out.print(Character.getNumericValue(word));
			}
	}

}

OfficialPrint.java

java 复制代码
package 二十三种设计模式之适配器模式;

public interface OfficialPrint {
void ToUpperChar();
void ToLowerChar();
void ToASCII();
}

MyPrint.java

java 复制代码
package 二十三种设计模式之适配器模式;

public class MyPrint {
private String Words;
MyPrint(String words){
	Words=words;
}
String getWords() {
	return Words;
}
}

user.java

java 复制代码
package 二十三种设计模式之适配器模式;

public class user {
	public static void main(String []args) {
		OfficialPrint printadapter=new PrintAdapter("HEllo Word!");
		printadapter.ToLowerChar();
		System.out.println("\n");
		printadapter.ToUpperChar();
		System.out.println("\n");
		printadapter.ToASCII();
	}
}

输出结果:

这里思考一个小问题:为啥,User类中

**OfficialPrint printadapter=new PrintAdapter("HEllo Word!");**不写成

**PrintAdapter printadapter=new PrintAdapter("HEllo Word!");**呢?

参考答案:

这是想强调"只使用OfficialPrint接口"的方法。OfficialPrint和PrintAdapter接口对外提供的方法是相同的。但在有些情况下,PrintAdapter类中的方法比OfficialPrint类中的方法多。通过将对象保存在OfficialPrint中并使用该变量,可以明确地表明程序的意图,即并不是使用PrintAdapter中的方法,而是OfficialPrint中的方法**。**

看完下面的例子二,你就会更加理解这个问题的答案了。🙂

例子二:

在上面的结构中增加一个encryptionPrint类,要求通过PrintAdapter加密输出。

UML图如下:

PrintAdapter.java

java 复制代码
package 二十三种设计模式之适配器模式;
 
public class PrintAdapter extends MyPrint implements OfficialPrint,encryptionPrint{
 
	PrintAdapter(String words) {
		super(words);
		// TODO Auto-generated constructor stub
	}
 
	@Override
	public void ToUpperChar() {
		// TODO Auto-generated method stub
		for(int i=0;i<getWords().length();i++) {
		char word=getWords().charAt(i);
		System.out.print(Character.toUpperCase(word));
		}
	
	}
 
	@Override
	public void ToLowerChar() {
		// TODO Auto-generated method stub
		for(int i=0;i<getWords().length();i++) {
			char word=getWords().charAt(i);
			System.out.print(Character.toLowerCase(word));
			}
	}
 
	@Override
	public void ToASCII() {
		// TODO Auto-generated method stub
		for(int i=0;i<getWords().length();i++) {
			char word=getWords().charAt(i);
			System.out.print(Character.getNumericValue(word));
			}
	}

	@Override
	public void Encrypt() {
		// TODO Auto-generated method stub
		String originalString=getWords();
		String replaceString=originalString.replace(originalString,"**********");
		System.out.println(replaceString);

			}
	}
 

user.java

java 复制代码
package 二十三种设计模式之适配器模式;

public class user {
	public static void main(String []args) {
		encryptionPrint encryptionprint=new PrintAdapter("HEllo Word!");
		encryptionprint.Encrypt();
	}
}

输出结果:

二.对象适配器🍉:

对象适配器模型

这里的Adapter与上面的不同,是采用继承Target抽象类,包含Adaptee对象的方式来实现Adaptee适配Target的。

例子:将上面例子一用对象适配器来实现

UML图如下

和上面的要求一致,用对象适配器方式实现只需要改Adapter和Target就可以了。

PrintAdapter.java

java 复制代码
package 二十三种设计模式之适配器模式;

public class PrintAdapter extends OfficialPrint{

private MyPrint myprint;
PrintAdapter(String s){
	myprint=new MyPrint(s);
}
	@Override
	public void ToUpperChar() {
		// TODO Auto-generated method stub
		for(int i=0;i<myprint.getWords().length();i++) {
		char word=myprint.getWords().charAt(i);
		System.out.print(Character.toUpperCase(word));
		}
	
	}

	@Override
	public void ToLowerChar() {
		// TODO Auto-generated method stub
		for(int i=0;i<myprint.getWords().length();i++) {
			char word=myprint.getWords().charAt(i);
			System.out.print(Character.toLowerCase(word));
			}
	}

	@Override
	public void ToASCII() {
		// TODO Auto-generated method stub
		for(int i=0;i<myprint.getWords().length();i++) {
			char word=myprint.getWords().charAt(i);
			System.out.print(Character.getNumericValue(word));
			}
	}

}

OfficialPrint.java

java 复制代码
package 二十三种设计模式之适配器模式;

public abstract class OfficialPrint {
public abstract void ToUpperChar();
public abstract void ToLowerChar();
public abstract void ToASCII();
}

三.为什么要使用适配器?

适配器适合用在版本升级的情况下。新版本扮演Adaptee,旧版本扮演Target,编写一个Adapter,让它使用新版本的类来实现旧版本的方法,从而达到升级更新的作用。

相关推荐
重生之后端学习19 小时前
62. 不同路径
开发语言·数据结构·算法·leetcode·职场和发展·深度优先
栗子~~19 小时前
hardhat 单元测试时如何观察gas消耗情况
开发语言·单元测试·区块链·智能合约
The hopes of the whole village19 小时前
Matlab FFT分析
开发语言·matlab
兰文彬19 小时前
n8n 2.x版本没有内嵌Python环境
开发语言·python
yiyaozjk19 小时前
Go基础之环境搭建
开发语言·后端·golang
谁动了我的代码?19 小时前
VNC中使用QT的GDB调试,触发断点时与界面窗口交互导致整个VNC冻结
开发语言·qt·svn
We་ct20 小时前
LeetCode 212. 单词搜索 II:Trie+DFS 高效解法
开发语言·算法·leetcode·typescript·深度优先·图搜索算法·图搜索
OxyTheCrack20 小时前
【C++】简述main函数中的argc与argv
开发语言·c++
历程里程碑20 小时前
Linux 49 HTTP请求与响应实战解析 带http模拟实现源码--万字长文解析
java·开发语言·网络·c++·网络协议·http·排序算法
ZVAyIVqt0UFji20 小时前
高可用虚拟IP(HaVip)技术详解:原理、设计与应用
开发语言·网络·网络协议·tcp/ip·perl