← 返回首页

Java结构型模式详解:适配器、代理、装饰器

📂 java ⏱ 4 min 747 words

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 + "  "));
    }
}

总结

结构型模式关注类和对象的组合方式。适配器解决接口不兼容,代理控制访问,装饰器动态添加职责,外观简化复杂子系统,桥接分离抽象与实现。