Java结构型模式详解:适配器、代理、装饰器
Java结构型模式详解
适配器模式(Adapter)
将一个类的接口转换成客户希望的另一个接口,使原本接口不兼容的类可以一起工作。
public interface MediaPlayer {
void play(String filename);
}
public class VlcPlayer {
public void playVlc(String filename) {
System.out.println("VLC播放: " + filename);
}
}
public class VlcAdapter implements MediaPlayer {
private VlcPlayer vlcPlayer = new VlcPlayer();
@Override
public void play(String filename) {
vlcPlayer.playVlc(filename);
}
}
public class AudioPlayer implements MediaPlayer {
private MediaPlayer vlcAdapter = new VlcAdapter();
@Override
public void play(String filename) {
if (filename.endsWith(".vlc")) {
vlcAdapter.play(filename);
} else {
System.out.println("默认播放: " + filename);
}
}
}
装饰器模式(Decorator)
动态地给对象添加额外职责,比继承更灵活。
public interface DataSource {
void writeData(String data);
String readData();
}
public class FileDataSource implements DataSource {
private String filename;
public FileDataSource(String filename) {
this.filename = filename;
}
@Override
public void writeData(String data) {
System.out.println("写入文件 " + filename + ": " + data);
}
@Override
public String readData() {
return "文件数据";
}
}
public abstract class DataSourceDecorator implements DataSource {
protected DataSource wrapped;
public DataSourceDecorator(DataSource source) {
this.wrapped = source;
}
@Override
public void writeData(String data) { wrapped.writeData(data); }
@Override
public String readData() { return wrapped.readData(); }
}
public class EncryptionDecorator extends DataSourceDecorator {
public EncryptionDecorator(DataSource source) { super(source); }
@Override
public void writeData(String data) {
String encrypted = encrypt(data);
super.writeData(encrypted);
}
@Override
public String readData() {
String data = super.readData();
return decrypt(data);
}
private String encrypt(String data) {
return Base64.getEncoder().encodeToString(data.getBytes());
}
private String decrypt(String data) {
return new String(Base64.getDecoder().decode(data));
}
}
public class CompressionDecorator extends DataSourceDecorator {
public CompressionDecorator(DataSource source) { super(source); }
@Override
public void writeData(String data) {
String compressed = compress(data);
super.writeData(compressed);
}
private String compress(String data) {
return "[压缩]" + data;
}
}
// 使用:自由组合装饰器
DataSource source = new FileDataSource("data.txt");
source = new CompressionDecorator(source);
source = new EncryptionDecorator(source);
source.writeData("敏感数据");
代理模式(Proxy)
为其他对象提供一种代理以控制对这个对象的访问。
public interface Image {
void display();
}
public class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk();
}
private void loadFromDisk() {
System.out.println("从磁盘加载图片: " + filename);
}
@Override
public void display() {
System.out.println("显示图片: " + filename);
}
}
public class ProxyImage implements Image {
private RealImage realImage;
private String filename;
public ProxyImage(String filename) {
this.filename = filename;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(filename);
}
realImage.display();
}
}
// 使用:延迟加载
Image image = new ProxyImage("photo.jpg");
// 图片此时未加载
image.display(); // 第一次调用时加载并显示
image.display(); // 直接显示,不再加载
外观模式(Facade)
为子系统中的一组接口提供一个一致的界面。
public class CPU {
public void freeze() { System.out.println("CPU冻结"); }
public void jump(long address) { System.out.println("CPU跳转到 " + address); }
public void execute() { System.out.println("CPU执行"); }
}
public class Memory {
public void load(long address, String data) {
System.out.println("内存加载: " + data + " 到地址 " + address);
}
}
public class HardDrive {
public String read(long sector, int size) {
return "硬盘数据";
}
}
public class ComputerFacade {
private CPU cpu = new CPU();
private Memory memory = new Memory();
private HardDrive hardDrive = new HardDrive();
public void start() {
System.out.println("=== 电脑启动 ===");
cpu.freeze();
memory.load(0L, hardDrive.read(0L, 1024));
cpu.jump(0L);
cpu.execute();
System.out.println("=== 启动完成 ===");
}
}
// 使用
ComputerFacade computer = new ComputerFacade();
computer.start();
桥接模式(Bridge)
将抽象部分与实现部分分离,使它们可以独立变化。
public interface DrawAPI {
void drawCircle(int x, int y, int radius);
}
public class RedCircle implements DrawAPI {
@Override
public void drawCircle(int x, int y, int radius) {
System.out.println("红色圆形: (" + x + "," + y + ") 半径=" + radius);
}
}
public class BlueCircle implements DrawAPI {
@Override
public void drawCircle(int x, int y, int radius) {
System.out.println("蓝色圆形: (" + x + "," + y + ") 半径=" + radius);
}
}
public abstract class Shape {
protected DrawAPI drawAPI;
protected Shape(DrawAPI drawAPI) {
this.drawAPI = drawAPI;
}
public abstract void draw();
}
public class CircleShape extends Shape {
private int x, y, radius;
public CircleShape(int x, int y, int radius, DrawAPI drawAPI) {
super(drawAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
@Override
public void draw() {
drawAPI.drawCircle(x, y, radius);
}
}
// 使用
Shape redCircle = new CircleShape(10, 10, 5, new RedCircle());
Shape blueCircle = new CircleShape(20, 20, 8, new BlueCircle());
redCircle.draw();
blueCircle.draw();
组合模式(Composite)
将对象组合成树形结构以表示"部分-整体"的层次。
public interface FileSystemComponent {
void show(String indent);
}
public class File implements FileSystemComponent {
private String name;
public File(String name) { this.name = name; }
@Override
public void show(String indent) {
System.out.println(indent + "文件: " + name);
}
}
public class Directory implements FileSystemComponent {
private String name;
private List<FileSystemComponent> children = new ArrayList<>();
public Directory(String name) { this.name = name; }
public void add(FileSystemComponent component) {
children.add(component);
}
@Override
public void show(String indent) {
System.out.println(indent + "目录: " + name);
children.forEach(c -> c.show(indent + " "));
}
}
总结
结构型模式关注类和对象的组合方式。适配器解决接口不兼容,代理控制访问,装饰器动态添加职责,外观简化复杂子系统,桥接分离抽象与实现。