适配器模式

一.什么是适配器模式🍓

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

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

适配器模式的应用场景通常包括已经存在的类,其方法和需求不匹配的情况。通过适配器模式,可以将不同的接口统一起来,使得原本无法协同工作的类能够一起工作。例如,‌电源适配器和‌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,让它使用新版本的类来实现旧版本的方法,从而达到升级更新的作用。

相关推荐
武昌库里写JAVA6 分钟前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
ZSYP-S41 分钟前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos44 分钟前
c++------------------函数
开发语言·c++
程序员_三木1 小时前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
是小崔啊1 小时前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
tianmu_sama1 小时前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
黄公子学安全1 小时前
Java的基础概念(一)
java·开发语言·python
liwulin05061 小时前
【JAVA】Tesseract-OCR截图屏幕指定区域识别0.4.2
java·开发语言·ocr
jackiendsc1 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
Oneforlove_twoforjob1 小时前
【Java基础面试题027】Java的StringBuilder是怎么实现的?
java·开发语言