适配器模式

一.什么是适配器模式🍓

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

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

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

相关推荐
懒大王爱吃狼25 分钟前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
秃头佛爷1 小时前
Python学习大纲总结及注意事项
开发语言·python·学习
待磨的钝刨1 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
XiaoLeisj3 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
励志成为嵌入式工程师4 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉5 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer5 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq5 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
记录成长java6 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山6 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js