【设计模式】适配器模式和桥接模式
适配器模式
概述
适配器模式是一种结构型设计模式,它将一个类的接口转换成客户端所期望的另一个接口。适配器使得原本由于接口不兼容而不能一起工作的那些类可以协同工作。
实现方式
- 类适配器:通过多重继承实现。
- 对象适配器:通过组合实现。(使用的比较多)
示例代码(对象适配器)
// 目标接口
interface MediaPlayer {
void play(String audioType, String fileName);
}
// 已有类
class AdvancedMediaPlayer {
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " + fileName);
}
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: " + fileName);
}
}
// 适配器类
class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter() {
this.advancedMusicPlayer = new AdvancedMediaPlayer();
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer.playMp4(fileName);
}
}
}
// 使用目标接口的客户端代码
class AudioPlayer implements MediaPlayer {
private MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing mp3 file. Name: " + fileName);
} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {
mediaAdapter = new MediaAdapter();
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media. " + audioType + " format not supported");
}
}
}
public class AdapterPatternDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "beyond the horizon.mp3");
audioPlayer.play("mp4", "alone.mp4");
audioPlayer.play("vlc", "far far away.vlc");
audioPlayer.play("avi", "mind me.avi");
}
}
桥接模式
概述
桥接模式是一种结构型设计模式,它将抽象部分与它的实现部分分离,使它们都可以独立地变化。这样做的目的是为了防止在增加新的具体实现和抽象时导致类数量的急剧增加加粗样式。
实现示例
// 实现部分接口
interface Implementor {
void operationImp();
}
// 具体实现A
class ConcreteImplementorA implements Implementor {
@Override
public void operationImp() {
System.out.println("ConcreteImplementorA operation");
}
}
// 具体实现B
class ConcreteImplementorB implements Implementor {
@Override
public void operationImp() {
System.out.println("ConcreteImplementorB operation");
}
}
// 抽象部分
abstract class Abstraction {
protected Implementor implementor;
public void setImplementor(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
// 扩展抽象部分
class RefinedAbstraction extends Abstraction {
@Override
public void operation() {
implementor.operationImp();
}
}
// 客户端代码
public class BridgePatternDemo {
public static void main(String[] args) {
Abstraction abstraction = new RefinedAbstraction();
abstraction.setImplementor(new ConcreteImplementorA());
abstraction.operation();
abstraction.setImplementor(new ConcreteImplementorB());
abstraction.operation();
}
}
在Java中的应用
-
适配器模式:
- Java标准库中
java.util.Arrays#asList()
方法就是一个适配器的例子,它将数组转换为列表。 - 在图形用户界面(GUI)开发中,经常使用适配器来处理事件监听器。例如,
MouseAdapter
、KeyAdapter
等,这些类提供了默认的方法实现,开发者只需要覆盖感兴趣的方法即可。
- Java标准库中
-
桥接模式:
- JDBC API加粗样式 是桥接模式的一个例子。JDBC驱动程序提供了一个抽象层,允许应用程序通过相同的接口访问不同类型的数据库,而不必关心具体的数据库实现细节。
- 在AWT/Swing中,GUI组件与其外观实现了桥接模式。这允许相同的组件在不同的平台上有不同的外观。