本文字数:1894字,阅读大约需要 7 分钟。
适配器模式(Adapter Pattern)属于结构型模式,用于将一个类的接口转换成客户端所期望的另一个接口。它允许不兼容的类之间进行合作,使得原本因接口不匹配而无法工作的类能够协同工作。
适配器模式在以下情况下特别有用:
适配器模式的实现通常涉及三个角色:目标接口、适配器和被适配者。
在 Java 中,一个常见的使用适配器模式的例子是InputStreamReader
类。该类是Java I/O库中用于将字节流(InputStream
)适配成字符流(Reader
)的适配器。
FileInputStream fis = new FileInputStream("hello world");
InputStreamReader adapter = new InputStreamReader(fis);
BufferedReader bfr = new BufferedReader(adapter);
在这个示例中,客户需要使用BufferedReader
来读取文件字符流。然而,现有的接口只能提供字节流,例如FileInputStream
。为了满足客户的需求,我们需要对现有的接口进行适配。
InputStreamReader
充当了适配器的角色。它持有一个FileInputStream
对象,并通过适配将其转换为所需的字符流接口。可以将InputStreamReader
视为适配器模式的具体实现之一。
通过使用适配器模式,我们成功地将字节流接口适配成了字符流接口,使得BufferedReader
能够以字符方式读取文件内容,从而满足了客户的需求。
适配器模式有两种比较常见的实现方式:
类适配器通过继承来实现适配器功能
// 目标接口
public interface Target {
void request();
}
// 被适配者
public class Adaptee {
public void specificRequest() {
System.out.println("Adaptee: specificRequest");
}
}
// 适配器
public class Adapter extends Adaptee implements Target {
/**
* 采用继承的方式实现转换功能
*/
@Override
public void request() {
super.specificRequest();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
target.request(); // 通过适配器调用被适配者方法
}
}
对象适配器通过组合来实现适配器功能
以下是一个简单的示例代码:
// 目标接口
public interface Target {
void request();
}
// 被适配者
public class Adaptee {
public void specificRequest() {
System.out.println("Adaptee: specificRequest");
}
}
// 适配器
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
target.request(); // 通过适配器调用被适配者方法
}
}
对象适配器和类适配器的区别是:类适配器是类间继承,对象适配器是对象的合成关系,也可以说是类的关联关系,这是两者的根本区别。
一般而言,由于对象适配器是通过类间的关联关系进行耦合的,因此在设计时就可以做到比较灵活,可以适配不同的被适配类,并且允许动态替换被适配对象。另外,对象适配器不受被适配类的限制。
类适配器通过继承现有接口类并实现目标接口,这样的话会使得现有接口类完全对适配器暴露,使得适配器具有现有接口类的全部功能,破坏了封装性,会引入一些设计上的限制。此外从逻辑上来说,这也是不符合常理的,适配器要做的是扩展现有接口类的功能而不是替代,类适配器只有在特定条件下会被使用。
对象适配器持有现有接口类一个实例,并扩展其功能,实现目标接口。这是推荐的方式,优先采用组合而不是继承,会使得代码更利于维护。
优点:
缺点:
适配器模式通过将不兼容的接口转换为可协同工作的形式,实现了不同类之间的互操作。它可以提高代码的复用性和灵活性。但在使用过程中需要注意选择合适的适配器类型,并确保适配器能够正确地转换接口。
希望这篇文章能给你带来收获和思考,如果你也有可借鉴的经验和深入的思考,欢迎评论区留言讨论。如果本文对你有帮助,请帮忙点个在看或者点个赞👍🏻。