1. 目的
将一个类的接口转换成客户希望的另外一个接口。
利用适配器Adapter,使得原本由于接口不兼容而不能一起工作的类可以一起工作。
2. 使用场景
类比:
- 现实世界中存在着各种各样的适配器和转换接口。例如电脑的电源适配器,将220V电压转换成电脑电池的12V工作电压;例如电源插排,将一个电源接口转成成多种不同的电源接口等等。
- 在面向对象的程序世界里,这样的转换接口对应的也即是“适配器模式”。
解析:
- 适配器模式主要是希望复用一些现存的类,但接口又与复用环境要求不一致的情况。
- 使用适配器模式,是一种开发上妥协的结果,也即服务调用方和提供方都不是很容易修改的时候,使用适配器作为一个中间的转化。
设计与妥协:
- 在软件开发阶段,还是应当尽量保证接口的一致性,避免使用适配器;运维阶段,可能出现新需求,但需要复用现存的接口,此时可以妥协使用适配器模式。
- 当然也有特殊情况,例如与第三方组件集成时,没有必要迎合第三方的接口而改动自己的接口,此时可以在设计之初,便考虑使用适配器模式。
适配器模式体现的设计原则有:
3. 类图
在适配器模式中,有4个参与对象:
- Client: 服务的消费端,其仅依赖于Target所定义的接口协议
- Target: 接口端,明确定义的接口的参数,功能
- Adapter: 将Adaptee的接口转换成Target的接口功能
- Adaptee: 需要转换的目标对象
在电脑电源适配器的例子中:
- Client: 笔记本电脑
- Target: 10V直流电
- Adapter: 电源适配器,将220V的交流电转换成12V的直流电
- Adaptee: 220V交流电
在运行时,Client端通过适配器的转换,使用Adaptee完成目标。
4. 代码实现
*&---------------------------------------------------------------------*
*& Report ZADAPTER_PATTERN
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zadapter_pattern.
* this is what you expected. it could be a class or an interface
CLASS lcl_target DEFINITION ABSTRACT.
PUBLIC SECTION.
METHODS request_12v_voltage.
ENDCLASS.
CLASS lcl_target IMPLEMENTATION.
METHOD request_12v_voltage.
ENDMETHOD.
ENDCLASS.
* This is what you have so far, which needs to be adapted
CLASS lcl_adaptee DEFINITION FINAL.
PUBLIC SECTION.
METHODS output_energy.
METHODS output_voltage.
METHODS get_voltage RETURNING VALUE(rv_voltage) TYPE i.
PRIVATE SECTION.
CONSTANTS gc_220v TYPE i VALUE 220.
ENDCLASS.
CLASS lcl_adaptee IMPLEMENTATION.
METHOD output_energy.
WRITE / 'Energy is outputing ...'.
ENDMETHOD.
METHOD get_voltage.
rv_voltage = gc_220v.
ENDMETHOD.
METHOD output_voltage.
WRITE / 'This is a request of_' && gc_220v && 'V_voltage'.
ENDMETHOD.
ENDCLASS.
* Use adapter to do conversion
CLASS lcl_adapter DEFINITION FINAL
INHERITING FROM lcl_target.
PUBLIC SECTION.
METHODS request_12v_voltage REDEFINITION.
PRIVATE SECTION.
DATA mo_adaptee TYPE REF TO lcl_adaptee.
CONSTANTS gc_220v TYPE i VALUE 220.
CONSTANTS gc_12v TYPE i VALUE 12.
ENDCLASS.
CLASS lcl_adapter IMPLEMENTATION.
METHOD request_12v_voltage.
mo_adaptee = NEW #( ).
IF mo_adaptee->get_voltage( ) = 220.
WRITE / 'This is a request of_' && gc_12v && 'V_voltage'.
mo_adaptee->output_energy( ).
ENDIF.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
" from client point of view, it only contacts with lcl_target.
DATA lo_target TYPE REF TO lcl_target.
lo_target = NEW lcl_adapter( ).
lo_target->request_12v_voltage( ).
运行结果:将220V电压转换为12V电压输出
本博客专注于技术分享,干货满满,持续更新。
欢迎关注❤️、点赞👍、转发📣!