适配器模式_结构型_GOF23

📅 发布时间:2026/7/8 8:18:04 👁️ 浏览次数:
适配器模式_结构型_GOF23
适配器模式适配器模式就像生活中的“万能转接头”——它能将不同形状的插头如USB-C转USB-A转换成统一的接口让原本不兼容的设备可以协同工作。在编程中适配器模式用于将不兼容的类接口转换为客户端期望的接口解决代码复用和系统扩展的兼容性问题。一、适配器模式的核心思想接口转换通过中间层适配器将一个类的接口转换成另一个接口。解耦复用客户端只需调用目标接口无需关心底层实现细节。典型场景集成旧系统或第三方库如调用不同数据库驱动。统一多类接口如播放器支持多种音视频格式。避免重复修改现有代码如升级系统时保留旧功能。二、适配器模式的三种角色角色作用类比现实案例目标接口Target客户端期望的接口如USB-C接口用户手中的手机充电接口被适配者Adaptee已存在的类或接口但无法直接使用如旧式USB-A接口老式充电器的USB-A插头适配器Adapter实现目标接口并持有被适配者的引用如转接头USB-C转USB-A转换器三、两种实现方式对比实现方式原理优点缺点类适配器继承被适配者类实现目标接口多继承代码简单直接复用父类方法破坏封装性不支持多语言如Java不支持多继承对象适配器组合被适配者对象实现目标接口推荐方式灵活解耦支持动态替换适配对象需要额外管理对象引用四、代码实现示例场景媒体播放器适配不同格式文件假设现有音频播放器仅支持MP3需扩展支持MP4/AVI格式通过适配器整合新播放器。C 实现对象适配器#includeiostream// 目标接口统一播放接口classMediaPlayer{public:virtualvoidplay(conststd::stringfileType,conststd::stringfileName)0;};// 被适配者高级播放器接口MP4/AVIclassAdvancedPlayer{public:virtualvoidplayMp4(conststd::stringfileName)0;virtualvoidplayAvi(conststd::stringfileName)0;};// 具体被适配者MP4播放器classMp4Player:publicAdvancedPlayer{public:voidplayMp4(conststd::stringfileName)override{std::cout播放MP4文件fileNamestd::endl;}voidplayAvi(conststd::string)override{}// 不支持AVI};// 适配器将高级播放器接口转为目标接口classPlayerAdapter:publicMediaPlayer{private:AdvancedPlayer*player;public:PlayerAdapter(conststd::stringtype){if(typemp4)playernewMp4Player();elseplayernullptr;}voidplay(conststd::stringtype,conststd::stringfile)override{if(typemp4)player-playMp4(file);elsestd::cout格式不支持std::endl;}~PlayerAdapter(){deleteplayer;}};// 客户端调用intmain(){MediaPlayer*playernewPlayerAdapter(mp4);player-play(mp4,movie.mp4);// 输出播放MP4文件movie.mp4deleteplayer;return0;}Python 实现类适配器# 目标接口classUSB_C:defcharge(self):pass# 被适配者旧式USB-A充电器classUSB_A:defold_charge(self):returnUSB-A充电中...# 适配器通过继承实现接口转换classAdapter(USB_C,USB_A):defcharge(self):returnself.old_charge()# 客户端调用adapterAdapter()print(adapter.charge())# 输出USB-A充电中...Java 实现对象适配器// 目标接口矩形面积计算interfaceRectangle{intcalculateArea();}// 被适配者旧式矩形类方法名不兼容classLegacyRectangle{publicintcalculateSurface(){return10;// 假设旧方法计算面积}}// 适配器组合方式转换接口classRectangleAdapterimplementsRectangle{privateLegacyRectangleadaptee;publicRectangleAdapter(LegacyRectangleadaptee){this.adapteeadaptee;}OverridepublicintcalculateArea(){returnadaptee.calculateSurface();// 调用旧方法}}// 客户端调用publicclassClient{publicstaticvoidmain(String[]args){RectangleadapternewRectangleAdapter(newLegacyRectangle());System.out.println(面积adapter.calculateArea());// 输出面积10}}五、注意事项与最佳实践避免过度设计若接口差异较小直接修改代码可能更简单。优先选择对象适配器组合比继承更灵活且符合“合成复用原则”。线程安全适配器内部若共享资源需加锁如数据库连接池。性能优化频繁调用的适配器可采用缓存或静态代理。六、适配器模式 VS 其他模式对比项适配器模式装饰器模式目的接口转换功能增强关系不同接口的类协作同一接口的类扩展典型场景整合第三方库动态添加日志/权限校验总结适配器模式是解决接口兼容问题的利器如同代码世界的“万能转换器”。合理使用可显著提升代码复用性和系统扩展性但需根据实际场景权衡实现方式。