什么是适配器模式?
在程序设计中,经常会存在一种情况:现有的程序无法直接使用,需要做适当的变换才能使用。
而用于填补“现有程序”和“所需程序”之间差异的设计模式就是适配器模式(Adapter)。
不理解?没关系,跟你分享一个生活中的例子!
我们在使用笔记本电脑时通常会插上电源,难道我们直接让220v的交流电通到电脑上吗?显然不是。通常,我们会使用AC适配器将家用的220v的交流电转化为电脑所需的直流电。这个就是适配器的工作,位于实际情况与需求之间,填补两者的差异。
为什么要使用适配器模式?
那为什么在程序设计中要使用适配器模式呢?答案很简单,为了提高代码的复用性,减少重复开发。
适配器模式如何实现?
适配器模式的实现有两种方式:
- 类适配器模式(使用继承和接口实现的适配器)
- 对象适配器模式(使用委托的适配器)
场景描述
下面用一个场景示例来介绍适配器模式的两种实现。
现有一个类Banner和一个接口Print。
Banner类:包含两个方法showWithParen()、showWithAster()。
showWithParen(): 为字符串添加一对括号(),如输入"hello",输出"(hello)"
showWithAster(): 为字符串添加一对**,如输入"hello",输出"*hello*"
Print接口:声明了两种方法printWeak()、printStrong()。
printWeak()方法需要实现功能:为字符串添加一对括号(),如输入"hello",输出"(hello)"
printStrong()方法需要实现功能:为字符串添加一对星号**,如输入"hello",输出"*hello*"
class Banner{
private String string;
public Banner(String string){
this.string = string;
}
public void showWithParen(){
System.out.println("(" + string + ")");
}
public void showWithAster(){
System.out.println("*" + string + "*");
}
}
interface Print{
public abstract void printWeak();
public abstract void printStrong();
}
现在我们需要实现Print接口里的方法,我们应该如何使用适配器模式?
方式一:类适配器模式
编写一个类PrintBanner,继承Banner类,实现Print接口,在重写printWeak()和printStrong()的时候分别调用Banner类中的showWithParen()和showWithAster()方法。
class PrintBanner extends Banner implements Print{
public PrintBanner(String string) {
super(string);
}
//我们只需要调用父类Banner中的方法即可
@Override
public void printWeak() {
showWithParen();
}
@Override
public void printStrong() {
showWithAster();
}
}
完整代码如下:
/**
* Author: Jayden
* Date: 2024/4/1 10:52
* Version: 1.0
* Description:
* Adapter(适配器)模式有以下两种:
* ①类适配器模式(使用继承的适配器)
* ②对象适配器模式(使用委托的适配器)
*
*
* 现有:
* Banner类:包含两个方法showWithParen()、showWithAster()
* showWithParen(): 为字符串添加一对括号(),如输入"hello",输出"(hello)"
* showWithAster(): 为字符串添加一对**,如输入"hello",输出"*hello*"
*
* Print接口:声明了两种方法printWeak()、printStrong()
*
*
* 需求:
* printWeak()方法需要实现下述功能:
* 为字符串添加一对括号(),如输入"hello",输出"(hello)"
* printStrong()方法需要实现下述功能:
* 为字符串添加一对星号**,如输入"hello",输出"*hello*"
*
*
* 具体实现:
* 编写一个类实现Print接口,继承Banner类,在重写printWeak()和printStrong()的时候分别调用Banner类中的showWithParen()和
* showWithAster()方法。精髓所在!!避免了代码重复!
*/
public class Demo01 {
public static void main(String[] args) {
Print printBanner = new PrintBanner("hello");
printBanner.printWeak();
printBanner.printStrong();
}
}
class Banner{
private String string;
public Banner(String string){
this.string = string;
}
public void showWithParen(){
System.out.println("(" + string + ")");
}
public void showWithAster(){
System.out.println("*" + string + "*");
}
}
//我们要做的就是利用现有的代码实现这个接口里的方法,而不是重新写一遍写过的代码
interface Print{
public abstract void printWeak();
public abstract void printStrong();
}
class PrintBanner extends Banner implements Print{
public PrintBanner(String string) {
super(string);
}
//我们只需要调用父类Banner中的方法即可
@Override
public void printWeak() {
showWithParen();
}
@Override
public void printStrong() {
showWithAster();
}
}
方式二:对象适配器模式
Banner类不变,Print接口变成抽象类后,我们又该如何处理?
创建一个类PrintBanner继承Print,然后在PrintBanner内部维护一个Banner对象,调用Banner对象中已经实现的showWithPren()和showWithAster()方法即可,用这个对象去调用已实现的方法即为委托。
完整代码如下:
package adapterPattern.pattern02;
/**
* Author: Jayden
* Date: 2024/4/1 11:24
* Version: 1.0
* Description:
* 该示例实现对象适配器模式(使用委托的适配器)
*/
public class Demo02 {
public static void main(String[] args) {
Print printBanner = new PrintBanner("hello");
printBanner.printWeak();
printBanner.printStrong();
}
}
class Banner{
private String string;
public Banner(String string){
this.string = string;
}
public void showWithParen(){
System.out.println("(" + string + ")");
}
public void showWithAster(){
System.out.println("*" + string + "*");
}
}
abstract class Print{
abstract void printWeak();
abstract void printStrong();
}
//采用对象适配器模式后,该类的内部会维护一个Banner对象,用这个对象去调用已实现的方法即为委托
class PrintBanner extends Print{
private Banner banner;
public PrintBanner(String s){
this.banner = new Banner(s);
}
@Override
void printWeak() {
banner.showWithParen();
}
@Override
void printStrong() {
banner.showWithAster();
}
}
有人可能会有疑问,为什么main函数中要使用 Print printBanner = new PrintBanner("hello);
而不使用 PrintBanner printBanner = new PrintBanner("hello);
标签:string,适配器,详解,void,Print,设计模式,Banner,public From: https://blog.csdn.net/m0_63352294/article/details/137232166因为示例程序主要想强调Print方法的实现,PrintBanner因为实现了Print接口,继承了Banner类,所以内部会有多种方法。而Print接口中只有printWeak()和printStrong()两种方法,可以更明确地表明程序的意图。