适配器模式全方位深度解析

2 阅读20分钟

一、模式定义

适配器模式是一种结构型设计模式,它允许不兼容的接口之间能够协同工作。适配器模式通过将一个类的接口转换成客户期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。

二、Java源代码实现

1. 类适配器(通过继承实现)

// 1. 目标接口(Target) - 客户端期望的接口
public interface MediaPlayer {
    void play(String audioType, String fileName);
    
    // 默认方法
    default void stop() {
        System.out.println("停止播放");
    }
}

// 2. 被适配者(Adaptee) - 已存在的、不兼容的接口
public class AdvancedMediaPlayer {
    public void playVlc(String fileName) {
        System.out.println("播放VLC文件: " + fileName);
    }
    
    public void playMp4(String fileName) {
        System.out.println("播放MP4文件: " + fileName);
    }
    
    public void playAvi(String fileName) {
        System.out.println("播放AVI文件: " + fileName);
    }
    
    public void stopPlaying() {
        System.out.println("停止播放");
    }
    
    public void setVolume(int volume) {
        System.out.println("设置音量: " + volume);
    }
}

// 3. 类适配器 - 通过继承被适配者实现目标接口
public class MediaAdapter extends AdvancedMediaPlayer implements MediaPlayer {
    
    @Override
    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("vlc")) {
            playVlc(fileName);
        } else if (audioType.equalsIgnoreCase("mp4")) {
            playMp4(fileName);
        } else if (audioType.equalsIgnoreCase("avi")) {
            playAvi(fileName);
        } else {
            System.out.println("不支持的文件格式: " + audioType);
        }
    }
    
    // 可以添加额外的适配方法
    public void playWithVolume(String audioType, String fileName, int volume) {
        play(audioType, fileName);
        setVolume(volume);
    }
}

2. 对象适配器(通过组合实现)

// 1. 目标接口
public interface MediaPlayer {
    void play(String audioType, String fileName);
    void stop();
    
    // 新增功能
    void setVolume(int volume);
    int getCurrentTime();
    
    // 默认方法
    default boolean isPlaying() {
        return false;
    }
}

// 2. 被适配者接口
public interface AdvancedMediaPlayer {
    void playVlc(String fileName);
    void playMp4(String fileName);
    void playMkv(String fileName);
    void playFlv(String fileName);
    
    void stop();
    void setVolume(int volume);
    int getCurrentPosition();
}

// 3. 具体被适配者实现
public class VlcPlayer implements AdvancedMediaPlayer {
    private boolean isPlaying = false;
    private int currentPosition = 0;
    private int volume = 50;
    
    @Override
    public void playVlc(String fileName) {
        isPlaying = true;
        currentPosition = 0;
        System.out.println("VLC播放器正在播放: " + fileName);
    }
    
    @Override
    public void playMp4(String fileName) {
        throw new UnsupportedOperationException("VLC播放器不支持MP4格式");
    }
    
    @Override
    public void playMkv(String fileName) {
        throw new UnsupportedOperationException("VLC播放器不支持MKV格式");
    }
    
    @Override
    public void playFlv(String fileName) {
        throw new UnsupportedOperationException("VLC播放器不支持FLV格式");
    }
    
    @Override
    public void stop() {
        isPlaying = false;
        System.out.println("VLC播放器停止播放");
    }
    
    @Override
    public void setVolume(int volume) {
        this.volume = volume;
        System.out.println("VLC播放器音量设置为: " + volume);
    }
    
    @Override
    public int getCurrentPosition() {
        return currentPosition;
    }
}

public class Mp4Player implements AdvancedMediaPlayer {
    private boolean isPlaying = false;
    private int currentPosition = 0;
    private int volume = 50;
    
    @Override
    public void playVlc(String fileName) {
        throw new UnsupportedOperationException("MP4播放器不支持VLC格式");
    }
    
    @Override
    public void playMp4(String fileName) {
        isPlaying = true;
        currentPosition = 0;
        System.out.println("MP4播放器正在播放: " + fileName);
    }
    
    @Override
    public void playMkv(String fileName) {
        throw new UnsupportedOperationException("MP4播放器不支持MKV格式");
    }
    
    @Override
    public void playFlv(String fileName) {
        throw new UnsupportedOperationException("MP4播放器不支持FLV格式");
    }
    
    @Override
    public void stop() {
        isPlaying = false;
        System.out.println("MP4播放器停止播放");
    }
    
    @Override
    public void setVolume(int volume) {
        this.volume = volume;
        System.out.println("MP4播放器音量设置为: " + volume);
    }
    
    @Override
    public int getCurrentPosition() {
        return currentPosition;
    }
}

// 4. 对象适配器 - 通过组合被适配者实现目标接口
public class MediaAdapter implements MediaPlayer {
    // 组合被适配者
    private AdvancedMediaPlayer advancedMusicPlayer;
    private String currentFile;
    private boolean isPlaying = false;
    private int currentTime = 0;
    
    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer = new Mp4Player();
        } else {
            throw new IllegalArgumentException("不支持的文件格式: " + audioType);
        }
    }
    
    // 也可以直接传入被适配者
    public MediaAdapter(AdvancedMediaPlayer player) {
        this.advancedMusicPlayer = player;
    }
    
    @Override
    public void play(String audioType, String fileName) {
        this.currentFile = fileName;
        
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer.playVlc(fileName);
            isPlaying = true;
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer.playMp4(fileName);
            isPlaying = true;
        } else if (audioType.equalsIgnoreCase("mkv") || audioType.equalsIgnoreCase("flv")) {
            System.out.println("暂时不支持 " + audioType + " 格式,正在转换为兼容格式...");
            // 模拟格式转换
            String convertedFile = convertFormat(fileName, audioType, "mp4");
            advancedMusicPlayer.playMp4(convertedFile);
            isPlaying = true;
        } else {
            System.out.println("不支持的文件格式: " + audioType);
        }
    }
    
    @Override
    public void stop() {
        if (isPlaying) {
            advancedMusicPlayer.stop();
            isPlaying = false;
        }
    }
    
    @Override
    public void setVolume(int volume) {
        advancedMusicPlayer.setVolume(volume);
    }
    
    @Override
    public int getCurrentTime() {
        if (isPlaying) {
            return advancedMusicPlayer.getCurrentPosition();
        }
        return currentTime;
    }
    
    @Override
    public boolean isPlaying() {
        return isPlaying;
    }
    
    // 适配器可以添加额外功能
    public String getCurrentFile() {
        return currentFile;
    }
    
    public String getPlayerType() {
        return advancedMusicPlayer.getClass().getSimpleName();
    }
    
    // 格式转换方法
    private String convertFormat(String fileName, String fromFormat, String toFormat) {
        String baseName = fileName.substring(0, fileName.lastIndexOf('.'));
        return baseName + "." + toFormat.toLowerCase();
    }
}

// 5. 客户端使用
public class AudioPlayer implements MediaPlayer {
    private MediaAdapter mediaAdapter;
    
    @Override
    public void play(String audioType, String fileName) {
        // 内置支持mp3格式
        if (audioType.equalsIgnoreCase("mp3")) {
            System.out.println("播放MP3文件: " + fileName);
        } 
        // 使用适配器播放其他格式
        else if (audioType.equalsIgnoreCase("vlc") 
                || audioType.equalsIgnoreCase("mp4")
                || audioType.equalsIgnoreCase("mkv")
                || audioType.equalsIgnoreCase("flv")) {
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        } else {
            System.out.println("不支持的文件格式: " + audioType);
        }
    }
    
    @Override
    public void stop() {
        if (mediaAdapter != null) {
            mediaAdapter.stop();
        } else {
            System.out.println("停止播放MP3");
        }
    }
    
    @Override
    public void setVolume(int volume) {
        if (mediaAdapter != null) {
            mediaAdapter.setVolume(volume);
        } else {
            System.out.println("设置MP3播放器音量: " + volume);
        }
    }
    
    @Override
    public int getCurrentTime() {
        if (mediaAdapter != null) {
            return mediaAdapter.getCurrentTime();
        }
        return 0;
    }
}

3. 双向适配器

// 1. 目标接口A
public interface NewLogger {
    void log(String message);
    void error(String error);
    void warn(String warning);
    
    default void log(String level, String message) {
        System.out.println("[" + level + "] " + message);
    }
}

// 2. 目标接口B
public interface LegacyLogger {
    void writeLog(String log);
    void writeError(String error);
    void writeWarning(String warning);
    
    void setLogLevel(int level);
    int getLogLevel();
}

// 3. 具体实现
 implements NewLogger {
    @Override
    public void log(String message) {
        System.out.println("[INFO] " + message);
    }
    
    @Override
    public void error(String error) {
        System.out.println("[ERROR] " + error);
    }
    
    @Override
    public void warn(String warning) {
        System.out.println("[WARN] " + warning);
    }
}

public class OldLogger implements LegacyLogger {
    private int logLevel = 1; // 1=INFO, 2=WARN, 3=ERROR
    
    @Override
    public void writeLog(String log) {
        if (logLevel <= 1) {
            System.out.println("LOG: " + log);
        }
    }
    
    @Override
    public void writeError(String error) {
        if (logLevel <= 3) {
            System.out.println("ERROR: " + error);
        }
    }
    
    @Override
    public void writeWarning(String warning) {
        if (logLevel <= 2) {
            System.out.println("WARNING: " + warning);
        }
    }
    
    @Override
    public void setLogLevel(int level) {
        this.logLevel = level;
    }
    
    @Override
    public int getLogLevel() {
        return logLevel;
    }
}

// 4. 双向适配器 - 实现两个接口
public class TwoWayLoggerAdapter implements NewLogger, LegacyLogger {
    private NewLogger newLogger;
    private LegacyLogger legacyLogger;
    
    public TwoWayLoggerAdapter(NewLogger newLogger) {
        this.newLogger = newLogger;
        this.legacyLogger = new LegacyLogger() {
            @Override
            public void writeLog(String log) {
                newLogger.log(log);
            }
            
            @Override
            public void writeError(String error) {
                newLogger.error(error);
            }
            
            @Override
            public void writeWarning(String warning) {
                newLogger.warn(warning);
            }
            
            @Override
            public void setLogLevel(int level) {
                // 忽略,新日志系统不使用级别
            }
            
            @Override
            public int getLogLevel() {
                return 1;
            }
        };
    }
    
    public TwoWayLoggerAdapter(LegacyLogger legacyLogger) {
        this.legacyLogger = legacyLogger;
        this.newLogger = new NewLogger() {
            @Override
            public void log(String message) {
                legacyLogger.writeLog(message);
            }
            
            @Override
            public void error(String error) {
                legacyLogger.writeError(error);
            }
            
            @Override
            public void warn(String warning) {
                legacyLogger.writeWarning(warning);
            }
        };
    }
    
    // 实现NewLogger接口
    @Override
    public void log(String message) {
        legacyLogger.writeLog(message);
    }
    
    @Override
    public void error(String error) {
        legacyLogger.writeError(error);
    }
    
    @Override
    public void warn(String warning) {
        legacyLogger.writeWarning(warning);
    }
    
    // 实现LegacyLogger接口
    @Override
    public void writeLog(String log) {
        newLogger.log(log);
    }
    
    @Override
    public void writeError(String error) {
        newLogger.error(error);
    }
    
    @Override
    public void writeWarning(String warning) {
        newLogger.warn(warning);
    }
    
    @Override
    public void setLogLevel(int level) {
        legacyLogger.setLogLevel(level);
    }
    
    @Override
    public int getLogLevel() {
        return legacyLogger.getLogLevel();
    }
}

4. 默认适配器(接口适配器)

// 1. 大接口 - 包含很多方法
public interface FileOperations {
    void open(String fileName);
    void close();
    void read();
    void write(String content);
    void delete();
    void rename(String newName);
    void copy(String destination);
    void move(String destination);
    void setPermissions(int permissions);
    int getSize();
    String getContent();
    boolean exists();
    boolean isDirectory();
    boolean isFile();
    Date getLastModified();
    void setLastModified(Date date);
}

// 2. 默认适配器 - 提供空实现
public abstract class FileOperationsAdapter implements FileOperations {
    @Override
    public void open(String fileName) {
        // 默认实现
    }
    
    @Override
    public void close() {
        // 默认实现
    }
    
    @Override
    public void read() {
        // 默认实现
    }
    
    @Override
    public void write(String content) {
        // 默认实现
    }
    
    @Override
    public void delete() {
        // 默认实现
    }
    
    @Override
    public void rename(String newName) {
        // 默认实现
    }
    
    @Override
    public void copy(String destination) {
        // 默认实现
    }
    
    @Override
    public void move(String destination) {
        // 默认实现
    }
    
    @Override
    public void setPermissions(int permissions) {
        // 默认实现
    }
    
    @Override
    public int getSize() {
        return 0;
    }
    
    @Override
    public String getContent() {
        return "";
    }
    
    @Override
    public boolean exists() {
        return false;
    }
    
    @Override
    public boolean isDirectory() {
        return false;
    }
    
    @Override
    public boolean isFile() {
        return false;
    }
    
    @Override
    public Date getLastModified() {
        return new Date();
    }
    
    @Override
    public void setLastModified(Date date) {
        // 默认实现
    }
}

// 3. 具体实现 - 只需要实现需要的方法
public class SimpleFileReader extends FileOperationsAdapter {
    private String fileName;
    private String content = "";
    
    public SimpleFileReader(String fileName) {
        this.fileName = fileName;
    }
    
    @Override
    public void open(String fileName) {
        this.fileName = fileName;
        System.out.println("打开文件: " + fileName);
    }
    
    @Override
    public void read() {
        // 模拟读取文件
        content = "这是文件 " + fileName + " 的内容";
        System.out.println("读取文件: " + fileName);
    }
    
    @Override
    public String getContent() {
        return content;
    }
    
    @Override
    public boolean exists() {
        return true; // 假设文件存在
    }
    
    // 只需要实现需要的方法,其他方法使用默认实现
}

// 4. 只读文件适配器
public class ReadOnlyFileAdapter extends FileOperationsAdapter {
    private String fileName;
    
    public ReadOnlyFileAdapter(String fileName) {
        this.fileName = fileName;
    }
    
    @Override
    public void open(String fileName) {
        this.fileName = fileName;
        System.out.println("以只读方式打开文件: " + fileName);
    }
    
    @Override
    public void read() {
        System.out.println("读取文件内容");
    }
    
    @Override
    public String getContent() {
        return "只读文件内容";
    }
    
    // 重写修改方法,抛出异常
    @Override
    public void write(String content) {
        throw new UnsupportedOperationException("只读文件,不能写入");
    }
    
    @Override
    public void delete() {
        throw new UnsupportedOperationException("只读文件,不能删除");
    }
    
    @Override
    public void rename(String newName) {
        throw new UnsupportedOperationException("只读文件,不能重命名");
    }
}

5. 客户端使用示例

public class AdapterPatternDemo {
    public static void main(String[] args) {
        System.out.println("=== 适配器模式示例 ===\n");
        
        // 测试对象适配器
        testObjectAdapter();
        
        // 测试类适配器
        testClassAdapter();
        
        // 测试双向适配器
        testTwoWayAdapter();
        
        // 测试默认适配器
        testDefaultAdapter();
        
        // 测试实际场景
        testRealWorldScenario();
    }
    
    private static void testObjectAdapter() {
        System.out.println("1. 对象适配器示例:");
        
        AudioPlayer audioPlayer = new AudioPlayer();
        
        // 播放各种格式
        audioPlayer.play("mp3", "song.mp3");
        audioPlayer.play("mp4", "movie.mp4");
        audioPlayer.play("vlc", "video.vlc");
        audioPlayer.play("mkv", "film.mkv");
        audioPlayer.play("avi", "video.avi");
        
        // 控制播放
        audioPlayer.setVolume(80);
        System.out.println("当前时间: " + audioPlayer.getCurrentTime());
        audioPlayer.stop();
    }
    
    private static void testClassAdapter() {
        System.out.println("\n2. 类适配器示例:");
        
        MediaAdapter adapter = new MediaAdapter();
        
        // 使用适配器播放
        adapter.play("vlc", "video.vlc");
        adapter.play("mp4", "movie.mp4");
        
        // 使用额外功能
        adapter.playWithVolume("avi", "film.avi", 75);
        adapter.stop();
    }
    
    private static void testTwoWayAdapter() {
        System.out.println("\n3. 双向适配器示例:");
        
        // 新系统使用旧日志
        ModernLogger modernLogger = new ModernLogger();
        TwoWayLoggerAdapter adapter1 = new TwoWayLoggerAdapter(modernLogger);
        
        // 通过LegacyLogger接口调用
        adapter1.writeLog("通过LegacyLogger接口记录日志");
        adapter1.writeError("通过LegacyLogger接口记录错误");
        
        // 旧系统使用新日志
        OldLogger oldLogger = new OldLogger();
        TwoWayLoggerAdapter adapter2 = new TwoWayLoggerAdapter(oldLogger);
        
        // 通过NewLogger接口调用
        adapter2.log("通过NewLogger接口记录日志");
        adapter2.error("通过NewLogger接口记录错误");
    }
    
    private static void testDefaultAdapter() {
        System.out.println("\n4. 默认适配器示例:");
        
        // 使用简单文件阅读器
        SimpleFileReader reader = new SimpleFileReader("test.txt");
        reader.open("test.txt");
        reader.read();
        System.out.println("文件内容: " + reader.getContent());
        
        // 使用只读文件适配器
        ReadOnlyFileAdapter readOnlyFile = new ReadOnlyFileAdapter("readonly.txt");
        readOnlyFile.open("readonly.txt");
        readOnlyFile.read();
        
        try {
            readOnlyFile.write("新内容");
        } catch (UnsupportedOperationException e) {
            System.out.println("预期异常: " + e.getMessage());
        }
    }
    
    private static void testRealWorldScenario() {
        System.out.println("\n5. 实际场景示例:");
        
        // 场景:旧支付系统适配
        PaymentSystem paymentSystem = new PaymentSystem();
        paymentSystem.processPayments();
    }
}

// 实际场景示例:支付系统适配
interface NewPaymentGateway {
    boolean authorizePayment(String cardNumber, double amount);
    boolean capturePayment(String transactionId);
    boolean refundPayment(String transactionId, double amount);
    String getPaymentStatus(String transactionId);
}

class PayPalGateway implements NewPaymentGateway {
    @Override
    public boolean authorizePayment(String cardNumber, double amount) {
        System.out.println("PayPal: 授权支付 " + amount + " 元,卡号: " + cardNumber);
        return true;
    }
    
    @Override
    public boolean capturePayment(String transactionId) {
        System.out.println("PayPal: 捕获交易 " + transactionId);
        return true;
    }
    
    @Override
    public boolean refundPayment(String transactionId, double amount) {
        System.out.println("PayPal: 退款 " + amount + " 元,交易号: " + transactionId);
        return true;
    }
    
    @Override
    public String getPaymentStatus(String transactionId) {
        return "COMPLETED";
    }
}

// 旧的支付接口
interface LegacyPaymentSystem {
    boolean processCreditCard(String cardNumber, String expiryDate, String cvv, double amount);
    boolean processRefund(String orderId, double amount);
    String checkTransactionStatus(String orderId);
}

class OldPaymentSystem implements LegacyPaymentSystem {
    @Override
    public boolean processCreditCard(String cardNumber, String expiryDate, String cvv, double amount) {
        System.out.println("旧系统: 处理信用卡支付,卡号: " + cardNumber + 
                          ", 有效期: " + expiryDate + 
                          ", 金额: " + amount);
        return true;
    }
    
    @Override
    public boolean processRefund(String orderId, double amount) {
        System.out.println("旧系统: 处理退款,订单号: " + orderId + ", 金额: " + amount);
        return true;
    }
    
    @Override
    public String checkTransactionStatus(String orderId) {
        return "SUCCESS";
    }
}

// 支付适配器
class PaymentAdapter implements NewPaymentGateway {
    private LegacyPaymentSystem legacyPaymentSystem;
    
    public PaymentAdapter(LegacyPaymentSystem legacyPaymentSystem) {
        this.legacyPaymentSystem = legacyPaymentSystem;
    }
    
    @Override
    public boolean authorizePayment(String cardNumber, double amount) {
        // 模拟从卡号中提取有效期和CVV
        String expiryDate = "12/26"; // 模拟
        String cvv = "123"; // 模拟
        
        return legacyPaymentSystem.processCreditCard(cardNumber, expiryDate, cvv, amount);
    }
    
    @Override
    public boolean capturePayment(String transactionId) {
        // 旧系统没有单独的捕获步骤,所以直接返回成功
        System.out.println("适配器: 自动捕获交易 " + transactionId);
        return true;
    }
    
    @Override
    public boolean refundPayment(String transactionId, double amount) {
        return legacyPaymentSystem.processRefund(transactionId, amount);
    }
    
    @Override
    public String getPaymentStatus(String transactionId) {
        return legacyPaymentSystem.checkTransactionStatus(transactionId);
    }
}

// 支付系统
class PaymentSystem {
    public void processPayments() {
        System.out.println("\n支付系统演示:");
        
        // 使用新的支付网关
        NewPaymentGateway payPal = new PayPalGateway();
        payPal.authorizePayment("4111111111111111", 100.00);
        
        // 通过适配器使用旧的支付系统
        LegacyPaymentSystem oldSystem = new OldPaymentSystem();
        NewPaymentGateway adaptedSystem = new PaymentAdapter(oldSystem);
        
        adaptedSystem.authorizePayment("4222222222222222", 200.00);
        adaptedSystem.capturePayment("TXN12345");
        adaptedSystem.refundPayment("TXN12345", 50.00);
        
        String status = adaptedSystem.getPaymentStatus("TXN12345");
        System.out.println("交易状态: " + status);
    }
}

三、应用场景深度解析

1. 系统集成和遗留系统适配

// 场景:新旧系统集成
public class SystemIntegrationExample {
    
    // 新系统接口
    interface ModernDataService {
        JsonObject fetchData(String query);
        void saveData(JsonObject data);
    }
    
    // 旧系统接口
    interface LegacyDataService {
        String getData(String sql);
        void insertData(String table, Map<String, String> data);
    }
    
    // 适配器
    class DataServiceAdapter implements ModernDataService {
        private LegacyDataService legacyService;
        
        public DataServiceAdapter(LegacyDataService legacyService) {
            this.legacyService = legacyService;
        }
        
        @Override
        public JsonObject fetchData(String query) {
            // 将现代查询转换为SQL
            String sql = convertToSql(query);
            String data = legacyService.getData(sql);
            
            // 将字符串转换为JSON
            return convertToJson(data);
        }
        
        @Override
        public void saveData(JsonObject data) {
            // 将JSON转换为表数据
            Map<String, String> tableData = convertToTableData(data);
            legacyService.insertData("modern_table", tableData);
        }
        
        private String convertToSql(String query) {
            // 转换逻辑
            return "SELECT * FROM table WHERE " + query;
        }
        
        private JsonObject convertToJson(String data) {
            // 转换逻辑
            return new JsonObject();
        }
        
        private Map<String, String> convertToTableData(JsonObject json) {
            // 转换逻辑
            return new HashMap<>();
        }
    }
    
    class JsonObject {
        // JSON对象实现
    }
}

2. 第三方库和API适配

// 场景:统一不同地图服务API
public class MapServiceAdapterExample {
    
    // 统一地图接口
    interface MapService {
        Location geocode(String address);
        Route calculateRoute(Location start, Location end);
        List<Location> searchNearby(Location center, String keyword);
    }
    
    // Google Maps适配
    class GoogleMapsAdapter implements MapService {
        private GoogleMapsService googleMaps;
        
        public GoogleMapsAdapter(GoogleMapsService googleMaps) {
            this.googleMaps = googleMaps;
        }
        
        @Override
        public Location geocode(String address) {
            GoogleGeocodeResult result = googleMaps.geocode(address);
            return convertToLocation(result);
        }
        
        @Override
        public Route calculateRoute(Location start, Location end) {
            GoogleRoute googleRoute = googleMaps.getDirections(
                convertToGoogleLocation(start),
                convertToGoogleLocation(end)
            );
            return convertToRoute(googleRoute);
        }
        
        // 转换方法...
    }
    
    // Baidu Maps适配
    class BaiduMapsAdapter implements MapService {
        private BaiduMapsService baiduMaps;
        
        public BaiduMapsAdapter(BaiduMapsService baiduMaps) {
            this.baiduMaps = baiduMaps;
        }
        
        @Override
        public Location geocode(String address) {
            BaiduGeocodeResult result = baiduMaps.geocode(address);
            return convertToLocation(result);
        }
        
        // 其他方法实现...
    }
    
    // 使用
    class MapClient {
        private MapService mapService;
        
        public void setMapProvider(String provider) {
            if (provider.equals("google")) {
                mapService = new GoogleMapsAdapter(new GoogleMapsService());
            } else if (provider.equals("baidu")) {
                mapService = new BaiduMapsAdapter(new BaiduMapsService());
            }
        }
        
        public void findRoute(String startAddress, String endAddress) {
            Location start = mapService.geocode(startAddress);
            Location end = mapService.geocode(endAddress);
            Route route = mapService.calculateRoute(start, end);
            // 使用路由...
        }
    }
}

3. 数据库驱动适配

// 场景:统一数据库访问接口
public class DatabaseAdapterExample {
    
    // 统一数据库接口
    interface Database {
        Connection connect(String url, String username, String password);
        ResultSet executeQuery(String sql);
        int executeUpdate(String sql);
        void close();
    }
    
    // MySQL适配器
    class MySQLAdapter implements Database {
        private com.mysql.jdbc.Connection mysqlConn;
        
        @Override
        public Connection connect(String url, String username, String password) {
            mysqlConn = com.mysql.jdbc.DriverManager.getConnection(
                "jdbc:mysql://" + url, username, password);
            return new ConnectionAdapter(mysqlConn);
        }
        
        @Override
        public ResultSet executeQuery(String sql) {
            com.mysql.jdbc.ResultSet rs = mysqlConn.executeQuery(sql);
            return new ResultSetAdapter(rs);
        }
        
        // 其他方法...
    }
    
    // PostgreSQL适配器
    class PostgreSQLAdapter implements Database {
        private org.postgresql.Connection pgConn;
        
        @Override
        public Connection connect(String url, String username, String password) {
            pgConn = org.postgresql.DriverManager.getConnection(
                "jdbc:postgresql://" + url, username, password);
            return new ConnectionAdapter(pgConn);
        }
        
        // 其他方法...
    }
    
    // 连接适配器
    class ConnectionAdapter implements Connection {
        private Object nativeConnection;
        
        public ConnectionAdapter(Object nativeConnection) {
            this.nativeConnection = nativeConnection;
        }
        
        // 实现统一连接接口...
    }
}

4. UI组件适配

// 场景:适配不同UI框架组件
public class UIComponentAdapterExample {
    
    // 统一UI组件接口
    interface UIComponent {
        void render();
        void setText(String text);
        String getText();
        void setEnabled(boolean enabled);
        void addClickListener(ClickListener listener);
    }
    
    // Swing按钮适配器
    class SwingButtonAdapter implements UIComponent {
        private JButton swingButton;
        
        public SwingButtonAdapter(JButton button) {
            this.swingButton = button;
        }
        
        @Override
        public void render() {
            swingButton.setVisible(true);
        }
        
        @Override
        public void setText(String text) {
            swingButton.setText(text);
        }
        
        @Override
        public String getText() {
            return swingButton.getText();
        }
        
        @Override
        public void setEnabled(boolean enabled) {
            swingButton.setEnabled(enabled);
        }
        
        @Override
        public void addClickListener(ClickListener listener) {
            swingButton.addActionListener(e -> listener.onClick());
        }
    }
    
    // JavaFX按钮适配器
    class JavaFXButtonAdapter implements UIComponent {
        private Button fxButton;
        
        public JavaFXButtonAdapter(Button button) {
            this.fxButton = button;
        }
        
        @Override
        public void render() {
            fxButton.setVisible(true);
        }
        
        @Override
        public void setText(String text) {
            fxButton.setText(text);
        }
        
        @Override
        public String getText() {
            return fxButton.getText();
        }
        
        @Override
        public void setEnabled(boolean enabled) {
            fxButton.setDisable(!enabled);
        }
        
        @Override
        public void addClickListener(ClickListener listener) {
            fxButton.setOnAction(e -> listener.onClick());
        }
    }
    
    // Web按钮适配器
    class WebButtonAdapter implements UIComponent {
        private WebElement webButton;
        
        public WebButtonAdapter(WebElement button) {
            this.webButton = button;
        }
        
        @Override
        public void render() {
            // Web元素自动渲染
        }
        
        @Override
        public void setText(String text) {
            webButton.setText(text);
        }
        
        @Override
        public String getText() {
            return webButton.getText();
        }
        
        @Override
        public void setEnabled(boolean enabled) {
            webButton.setEnabled(enabled);
        }
        
        @Override
        public void addClickListener(ClickListener listener) {
            webButton.addClickHandler(e -> listener.onClick());
        }
    }
}

四、优缺点深度解析

优点

  1. 解耦客户端和适配者

    • 客户端只依赖目标接口
    • 适配者和客户端完全解耦
    • 符合依赖倒置原则
  2. 复用现有类

    • 可以重用现有的、功能完善的类
    • 不需要修改现有代码
    • 符合开闭原则
  3. 提高灵活性和扩展性

    • 可以轻松添加新的适配器
    • 支持多个适配者适配同一目标
    • 支持一个适配者适配多个目标
  4. 简化系统架构

    • 统一了不兼容的接口
    • 使系统更易于理解和维护
    • 降低了系统复杂度
  5. 支持双向适配

    • 可以实现双向适配器
    • 新旧系统可以互相调用
    • 支持渐进式迁移

缺点

  1. 增加系统复杂度

    • 引入了额外的类和接口
    • 增加了代码的理解难度
    • 可能产生过多的适配器类
  2. 性能开销

    • 额外的间接调用带来性能损失
    • 转换过程可能消耗资源
    • 对性能敏感的系统需谨慎使用
  3. 设计过度

    • 简单场景下可能过度设计
    • 可能增加不必要的抽象层
    • 可能使简单问题复杂化
  4. 适配限制

    • 不是所有不兼容都能适配
    • 某些语义差异难以适配
    • 功能缺失无法通过适配器弥补
  5. 调试困难

    • 调用链变长,调试困难
    • 错误可能被适配器隐藏
    • 难以追踪原始问题

五、使用要点与最佳实践

1. 适配器vs装饰器vs代理模式

// 模式选择指南
public class PatternSelectionGuide {
    /*
     * 使用适配器模式当:
     * 1. 需要将不兼容接口转换为兼容接口
     * 2. 需要重用现有类但其接口不匹配
     * 3. 需要统一多个类的接口
     * 
     * 使用装饰器模式当:
     * 1. 需要动态添加功能
     * 2. 需要透明地扩展对象功能
     * 3. 需要避免子类爆炸
     * 
     * 使用代理模式当:
     * 1. 需要控制对对象的访问
     * 2. 需要延迟加载或缓存
     * 3. 需要添加访问控制
     */
    
    // 示例:三种模式的对比
    interface Image {
        void display();
    }
    
    // 被适配者
    class LegacyImage {
        public void show() {
            System.out.println("显示图片");
        }
    }
    
    // 适配器
    class ImageAdapter implements Image {
        private LegacyImage legacyImage;
        
        public ImageAdapter(LegacyImage legacyImage) {
            this.legacyImage = legacyImage;
        }
        
        @Override
        public void display() {
            legacyImage.show(); // 适配
        }
    }
    
    // 装饰器
    class ImageDecorator implements Image {
        protected Image decoratedImage;
        
        public ImageDecorator(Image image) {
            this.decoratedImage = image;
        }
        
        @Override
        public void display() {
            decoratedImage.display();
        }
    }
    
    class WatermarkDecorator extends ImageDecorator {
        public WatermarkDecorator(Image image) {
            super(image);
        }
        
        @Override
        public void display() {
            super.display();
            addWatermark();
        }
        
        private void addWatermark() {
            System.out.println("添加水印");
        }
    }
    
    // 代理
    class ImageProxy implements Image {
        private RealImage realImage;
        private String fileName;
        
        public ImageProxy(String fileName) {
            this.fileName = fileName;
        }
        
        @Override
        public void display() {
            if (realImage == null) {
                realImage = new RealImage(fileName); // 延迟加载
            }
            realImage.display();
        }
    }
}

2. 适配器设计模式的选择

// 类适配器 vs 对象适配器
public class AdapterTypeSelection {
    /*
     * 类适配器(继承):
     * 优点:
     * 1. 简单直接
     * 2. 可以重写被适配者的方法
     * 3. 只需要一个对象
     * 
     * 缺点:
     * 1. 需要多重继承(Java不支持)
     * 2. 对适配者的子类不透明
     * 3. 破坏封装性
     * 
     * 对象适配器(组合):
     * 优点:
     * 1. 更灵活
     * 2. 可以适配多个适配者
     * 3. 符合组合优于继承原则
     * 4. 对适配者的子类透明
     * 
     * 缺点:
     * 1. 需要额外对象
     * 2. 稍微复杂
     */
    
    // 选择建议:
    // 1. 如果需要多重继承功能 -> 类适配器
    // 2. 如果需要适配多个对象 -> 对象适配器
    // 3. 如果需要重写行为 -> 类适配器
    // 4. 如果需要更灵活的设计 -> 对象适配器
    // 5. 大多数情况下 -> 使用对象适配器
}

3. 智能适配器

// 智能适配器:包含额外逻辑
public class SmartAdapterExample {
    
    interface TemperatureSensor {
        double getTemperature();
        TemperatureUnit getUnit();
    }
    
    // 智能适配器
    class SmartTemperatureAdapter implements TemperatureSensor {
        private LegacyThermometer legacyThermometer;
        private TemperatureUnit targetUnit;
        private double calibrationOffset = 0.0;
        private boolean useCaching = false;
        private Double cachedValue = null;
        private long cacheExpiry = 0;
        
        public SmartTemperatureAdapter(LegacyThermometer thermometer, TemperatureUnit targetUnit) {
            this.legacyThermometer = thermometer;
            this.targetUnit = targetUnit;
        }
        
        @Override
        public double getTemperature() {
            if (useCaching && cachedValue != null && 
                System.currentTimeMillis() < cacheExpiry) {
                return cachedValue;
            }
            
            double rawValue = legacyThermometer.readValue();
            
            // 单位转换
            double convertedValue = convertUnit(rawValue, 
                legacyThermometer.getUnit(), targetUnit);
            
            // 校准
            double calibratedValue = convertedValue + calibrationOffset;
            
            // 范围限制
            double finalValue = clamp(calibratedValue, -100.0, 200.0);
            
            if (useCaching) {
                cachedValue = finalValue;
                cacheExpiry = System.currentTimeMillis() + 1000; // 1秒缓存
            }
            
            return finalValue;
        }
        
        @Override
        public TemperatureUnit getUnit() {
            return targetUnit;
        }
        
        // 额外功能
        public void setCalibrationOffset(double offset) {
            this.calibrationOffset = offset;
        }
        
        public void enableCaching(boolean enable) {
            this.useCaching = enable;
        }
        
        public void setCacheDuration(long milliseconds) {
            this.cacheExpiry = System.currentTimeMillis() + milliseconds;
        }
        
        public boolean isOutOfRange() {
            double temp = getTemperature();
            return temp < -50.0 || temp > 100.0;
        }
        
        private double convertUnit(double value, TemperatureUnit from, TemperatureUnit to) {
            if (from == to) return value;
            
            if (from == TemperatureUnit.CELSIUS && to == TemperatureUnit.FAHRENHEIT) {
                return value * 9/5 + 32;
            } else if (from == TemperatureUnit.FAHRENHEIT && to == TemperatureUnit.CELSIUS) {
                return (value - 32) * 5/9;
            } else if (from == TemperatureUnit.KELVIN && to == TemperatureUnit.CELSIUS) {
                return value - 273.15;
            }
            
            return value;
        }
        
        private double clamp(double value, double min, double max) {
            return Math.max(min, Math.min(max, value));
        }
    }
    
    enum TemperatureUnit {
        CELSIUS, FAHRENHEIT, KELVIN
    }
    
    class LegacyThermometer {
        public double readValue() {
            return 25.0; // 模拟读取
        }
        
        public TemperatureUnit getUnit() {
            return TemperatureUnit.CELSIUS;
        }
    }
}

4. 适配器注册表

// 适配器注册表:管理多个适配器
public class AdapterRegistry {
    private final Map<Class<?>, Map<Class<?>, AdapterFactory<?, ?>>> registry = new HashMap<>();
    
    public <S, T> void registerAdapter(Class<S> sourceType, 
                                       Class<T> targetType, 
                                       AdapterFactory<S, T> factory) {
        registry.computeIfAbsent(sourceType, k -> new HashMap<>())
                .put(targetType, factory);
    }
    
    @SuppressWarnings("unchecked")
    public <S, T> T adapt(S source, Class<T> targetType) {
        if (source == null) {
            return null;
        }
        
        Class<?> sourceType = source.getClass();
        Map<Class<?>, AdapterFactory<?, ?>> targetMap = registry.get(sourceType);
        
        if (targetMap != null) {
            AdapterFactory<S, T> factory = (AdapterFactory<S, T>) targetMap.get(targetType);
            if (factory != null) {
                return factory.create(source);
            }
        }
        
        // 尝试查找父类适配器
        for (Class<?> superType : registry.keySet()) {
            if (superType.isAssignableFrom(sourceType)) {
                Map<Class<?>, AdapterFactory<?, ?>> superTargetMap = registry.get(superType);
                if (superTargetMap != null) {
                    AdapterFactory<S, T> factory = (AdapterFactory<S, T>) 
                        superTargetMap.get(targetType);
                    if (factory != null) {
                        return factory.create(source);
                    }
                }
            }
        }
        
        throw new NoAdapterFoundException(
            "No adapter found from " + sourceType + " to " + targetType);
    }
    
    public <S, T> boolean canAdapt(Class<S> sourceType, Class<T> targetType) {
        if (registry.containsKey(sourceType)) {
            return registry.get(sourceType).containsKey(targetType);
        }
        
        // 检查父类
        for (Class<?> registeredSource : registry.keySet()) {
            if (registeredSource.isAssignableFrom(sourceType)) {
                if (registry.get(registeredSource).containsKey(targetType)) {
                    return true;
                }
            }
        }
        
        return false;
    }
    
    interface AdapterFactory<S, T> {
        T create(S source);
    }
    
    class NoAdapterFoundException extends RuntimeException {
        public NoAdapterFoundException(String message) {
            super(message);
        }
    }
}

// 使用注册表
class RegistryExample {
    public static void main(String[] args) {
        AdapterRegistry registry = new AdapterRegistry();
        
        // 注册适配器
        registry.registerAdapter(LegacyUser.class, ModernUser.class, 
            source -> new UserAdapter(source).adapt());
        
        registry.registerAdapter(LegacyProduct.class, ModernProduct.class,
            source -> new ProductAdapter(source).adapt());
        
        // 使用适配器
        LegacyUser legacyUser = new LegacyUser("John", "Doe", 30);
        ModernUser modernUser = registry.adapt(legacyUser, ModernUser.class);
        
        System.out.println("适配后的用户: " + modernUser.getFullName());
    }
}

5. 测试策略

// 适配器模式测试
public class AdapterPatternTest {
    
    @Test
    void testAdapterBasicFunctionality() {
        // 测试基本适配功能
        LegacyThermometer thermometer = new LegacyThermometer();
        SmartTemperatureAdapter adapter = new SmartTemperatureAdapter(
            thermometer, TemperatureUnit.FAHRENHEIT);
        
        double temperature = adapter.getTemperature();
        
        // 验证温度转换
        assertTrue(temperature > 0, "温度应为正数");
        assertEquals(TemperatureUnit.FAHRENHEIT, adapter.getUnit());
    }
    
    @Test
    void testAdapterWithCalibration() {
        // 测试带校准的适配器
        LegacyThermometer thermometer = new LegacyThermometer();
        SmartTemperatureAdapter adapter = new SmartTemperatureAdapter(
            thermometer, TemperatureUnit.CELSIUS);
        
        double originalTemp = adapter.getTemperature();
        
        adapter.setCalibrationOffset(5.0);
        double calibratedTemp = adapter.getTemperature();
        
        assertEquals(originalTemp + 5.0, calibratedTemp, 0.001);
    }
    
    @Test
    void testAdapterExceptionHandling() {
        // 测试适配器异常处理
        LegacyThermometer brokenThermometer = new BrokenThermometer();
        SmartTemperatureAdapter adapter = new SmartTemperatureAdapter(
            brokenThermometer, TemperatureUnit.CELSIUS);
        
        // 应该处理异常并返回默认值
        assertDoesNotThrow(() -> adapter.getTemperature());
    }
    
    @Test
    void testAdapterPerformance() {
        // 测试适配器性能
        LegacyThermometer thermometer = new LegacyThermometer();
        SmartTemperatureAdapter adapter = new SmartTemperatureAdapter(
            thermometer, TemperatureUnit.FAHRENHEIT);
        
        long startTime = System.nanoTime();
        
        for (int i = 0; i < 10000; i++) {
            adapter.getTemperature();
        }
        
        long duration = System.nanoTime() - startTime;
        
        assertTrue(duration < 1_000_000_000, "10000次调用应在1秒内完成");
    }
    
    @Test
    void testAdapterThreadSafety() throws InterruptedException {
        // 测试适配器线程安全
        LegacyThermometer thermometer = new LegacyThermometer();
        SmartTemperatureAdapter adapter = new SmartTemperatureAdapter(
            thermometer, TemperatureUnit.CELSIUS);
        
        int threadCount = 10;
        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        List<Future<Double>> results = new ArrayList<>();
        
        for (int i = 0; i < threadCount; i++) {
            results.add(executor.submit(adapter::getTemperature));
        }
        
        for (Future<Double> result : results) {
            assertDoesNotThrow(result::get);
        }
        
        executor.shutdown();
        assertTrue(executor.awaitTermination(5, TimeUnit.SECONDS));
    }
    
    @Test
    void testAdapterRegistry() {
        // 测试适配器注册表
        AdapterRegistry registry = new AdapterRegistry();
        registry.registerAdapter(LegacyUser.class, ModernUser.class,
            legacy -> new UserAdapter(legacy).adapt());
        
        LegacyUser legacyUser = new LegacyUser("Alice", "Smith", 25);
        ModernUser modernUser = registry.adapt(legacyUser, ModernUser.class);
        
        assertNotNull(modernUser);
        assertEquals("Alice Smith", modernUser.getFullName());
        
        // 测试不支持的转换
        assertThrows(NoAdapterFoundException.class, () -> {
            registry.adapt(legacyUser, String.class);
        });
    }
    
    // 测试辅助类
    class BrokenThermometer extends LegacyThermometer {
        @Override
        public double readValue() {
            throw new RuntimeException("传感器故障");
        }
    }
}

六、与其他模式的比较

模式相似点不同点适用场景
装饰器模式都包装对象装饰器增强功能,适配器转换接口需要功能扩展用装饰器,需要接口转换用适配器
代理模式都包装对象代理控制访问,适配器转换接口需要访问控制用代理,需要接口转换用适配器
外观模式都简化接口外观简化子系统接口,适配器转换单个接口简化复杂子系统用外观,转换不兼容接口用适配器
桥接模式都解耦抽象和实现桥接分离抽象和实现,适配器使不兼容接口协同工作多维度变化用桥接,接口不兼容用适配器

七、实际应用示例

示例1:Java标准库中的适配器

// Java标准库中的适配器模式
public class JavaStandardLibraryAdapters {
    public static void main(String[] args) {
        // 1. InputStreamReader/OutputStreamWriter
        // 将字节流适配为字符流
        try (InputStreamReader reader = 
                new InputStreamReader(System.in)) {
            // 字节流 -> 字符流
        }
        
        // 2. Arrays.asList() - 数组到List的适配器
        String[] array = {"a", "b", "c"};
        List<String> list = Arrays.asList(array);
        
        // 3. Collections.unmodifiableXXX() - 只读适配器
        List<String> modifiable = new ArrayList<>();
        List<String> unmodifiable = Collections.unmodifiableList(modifiable);
        
        // 4. Enumeration -> Iterator适配器
        Vector<String> vector = new Vector<>();
        Enumeration<String> enumeration = vector.elements();
        Iterator<String> iterator = new EnumerationIterator<>(enumeration);
        
        // 5. Runnable适配器
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("运行中");
            }
        });
        
        // 6. TimerTask适配器
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("定时任务");
            }
        }, 1000);
    }
    
    // Enumeration到Iterator的适配器
    static class EnumerationIterator<E> implements Iterator<E> {
        private final Enumeration<E> enumeration;
        
        public EnumerationIterator(Enumeration<E> enumeration) {
            this.enumeration = enumeration;
        }
        
        @Override
        public boolean hasNext() {
            return enumeration.hasMoreElements();
        }
        
        @Override
        public E next() {
            return enumeration.nextElement();
        }
        
        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}

示例2:Spring框架中的适配器

// Spring框架中的适配器模式
@Configuration
public class SpringAdaptersExample {
    
    // 1. HandlerAdapter - 处理各种Handler
    @Bean
    public HandlerAdapter handlerAdapter() {
        return new SimpleControllerHandlerAdapter();
    }
    
    // 2. MessageConverter - 消息转换适配器
    @Bean
    public HttpMessageConverter<String> stringMessageConverter() {
        return new StringHttpMessageConverter();
    }
    
    // 3. WebMvcConfigurer适配器
    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/home").setViewName("home");
            }
        };
    }
    
    // 4. 事件监听器适配器
    @Bean
    public ApplicationListener<ContextRefreshedEvent> contextRefreshedListener() {
        return new ApplicationListenerAdapter() {
            @Override
            public void onApplicationEvent(ContextRefreshedEvent event) {
                System.out.println("应用上下文已刷新");
            }
        };
    }
    
    // 5. 属性编辑器适配器
    @Bean
    public CustomEditorConfigurer customEditorConfigurer() {
        CustomEditorConfigurer configurer = new CustomEditorConfigurer();
        Map<Class<?>, Class<? extends PropertyEditor>> editors = new HashMap<>();
        editors.put(Date.class, CustomDateEditor.class);
        configurer.setCustomEditors(editors);
        return configurer;
    }
}

// 自定义适配器示例
@Component
public class LegacyServiceAdapter implements ModernService {
    
    private final LegacyService legacyService;
    
    public LegacyServiceAdapter(LegacyService legacyService) {
        this.legacyService = legacyService;
    }
    
    @Override
    public ModernResult process(ModernRequest request) {
        // 转换请求
        LegacyRequest legacyRequest = convertRequest(request);
        
        // 调用遗留服务
        LegacyResult legacyResult = legacyService.processLegacy(legacyRequest);
        
        // 转换结果
        return convertResult(legacyResult);
    }
    
    private LegacyRequest convertRequest(ModernRequest request) {
        // 转换逻辑
        return new LegacyRequest();
    }
    
    private ModernResult convertResult(LegacyResult result) {
        // 转换逻辑
        return new ModernResult();
    }
}

八、注意事项

  1. 避免过度使用:不要为每个接口不匹配都创建适配器
  2. 保持适配器简单:适配器应专注于接口转换,避免复杂业务逻辑
  3. 考虑性能影响:频繁调用的适配器需要考虑性能优化
  4. 处理异常:适配器应妥善处理转换过程中的异常
  5. 保持透明性:适配器应对客户端透明
  6. 文档化转换规则:明确记录接口转换规则
  7. 测试适配器:充分测试适配器的各种转换场景
  8. 考虑双向适配:如果需要双向交互,考虑实现双向适配器
  9. 避免适配器链:避免多层适配器嵌套,增加复杂性
  10. 使用合适模式:根据场景选择类适配器或对象适配器

九、总结

适配器模式是一种强大的结构型模式,特别适用于:

  • 集成遗留系统
  • 使用第三方库
  • 统一多个接口
  • 支持多种实现

适配器模式的核心价值

  1. 解耦:将客户端与具体实现解耦
  2. 复用:重用现有代码,无需修改
  3. 灵活:支持多种适配方式
  4. 渐进:支持系统渐进式重构

最佳实践建议

  1. 优先使用对象适配器:更灵活,符合组合优于继承原则
  2. 保持适配器单一职责:一个适配器只负责一种转换
  3. 添加适当日志:便于调试转换过程
  4. 考虑性能优化:对频繁调用的适配器进行优化
  5. 充分测试:测试各种边界情况和异常场景
  6. 文档化:明确记录适配器的转换规则和限制

适配器模式是处理系统集成、技术升级和多平台支持的必备工具。正确使用适配器模式可以显著提高系统的灵活性、可维护性和可扩展性。