ABAP设计模式之---“装饰模式 (Decorator Pattern)”

1. 目的

不改动功能类的基础上,动态地给一个对象添加一些额外的职责。

2. 解析

类比:

  • 装饰模式可以类比于现实世界的穿衣打扮过程。你的衣柜里有各种各样的衣服,在出门时,你可以选择当日的搭配,可以选择牛仔裤配格子衫,可以大体恤配短裤拖鞋。每一件衣服,可以可以类比成面向对象世界中的一个装饰类。
  • 装饰类间相互独立,可以相互组合,合作完成一种功能搭配。

功能解析:

  • 就增加功能来说,装饰模式比生成子类更灵活
  • 把类中装饰的功能从类中搬出,这样可以简化原有的类
  • 有效区分类的核心功能和装饰功能
  • 使用时,应注意装饰类的调用顺序。当然,最理想的情况下,各个装饰类之间应当是相互独立的
  • 调用方,不需要知道装饰类的存在

核心技术点:

  • Decorator类和功能类之间形成“链状结构”,调用“本层”装饰类前,先调用“上层”装饰类/功能类。

结合应用

  • 可以与工厂模式结合使用,工厂直接返回装饰后的实例对象。

代理模式体现的设计原则有:

  • 单一职责原则 - 专业的类做专业的事
  • 开放封闭原则 - 稳定的核心功能;但在不同的场景下,可以有多种不同的代理类
  • 依赖倒置原则 - client在使用时,其实依赖的是接口,面向接口的编程

3. 类图

实现装饰模式可以有多种方法,本篇中给出了两种实现方式。

  • 使用抽象类
  • 使用接口

3.1 通过继承实现

创建抽象类decorator, 抽象类直接提供形成链状结构的set_component方法,然后继承抽象decorator类来实现不同的装饰类。
在这里插入图片描述

3.3 通过接口实现

装饰类和功能类,实现相同的接口。在实例化装饰类时,用mo_component存储功能类对象,实现链状结构。在这里插入图片描述

3.3 调用时序图

无论通过哪种方式实现,达到的效果是相同的。Client调用功能时,装饰类并不会改变已有的接口结构,而仅仅是在原有功能上,附加了装饰功能。
在这里插入图片描述

4. 代码实现

4.1 通过继承实现

*&---------------------------------------------------------------------*
*& Report zdecorator_pattern
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zdecorator_pattern.

* here the component could be an interface object
CLASS lcl_component DEFINITION.
  PUBLIC SECTION.
    METHODS operation.
ENDCLASS.

CLASS lcl_component IMPLEMENTATION.
  METHOD operation.
    WRITE 'Specific operation from component.'.
  ENDMETHOD.
ENDCLASS.

* Use decorator to extend the behavior of component
CLASS lcl_decorator DEFINITION
INHERITING FROM lcl_component.
  PUBLIC SECTION.
    METHODS set_component
      IMPORTING
        io_component TYPE REF TO lcl_component.

    METHODS operation REDEFINITION.
  PROTECTED SECTION.
    DATA mo_component TYPE REF TO lcl_component.
ENDCLASS.

CLASS lcl_decorator IMPLEMENTATION.
  METHOD set_component.
    mo_component = io_component.
  ENDMETHOD.

  METHOD operation.
    IF mo_component IS BOUND.
      mo_component->operation(  ).
    ENDIF.
  ENDMETHOD.
ENDCLASS.

* Specific decorator class to add specific behavior
CLASS lcl_decorator_a DEFINITION
INHERITING FROM lcl_decorator.
  PUBLIC SECTION.
    METHODS operation REDEFINITION.

  PRIVATE SECTION.
    DATA mv_state TYPE string.
ENDCLASS.

CLASS lcl_decorator_a IMPLEMENTATION.
  METHOD operation.
    super->operation(  ).
    mv_state = 'Some states were described'.
    WRITE / 'Operation in decorator A'.
  ENDMETHOD.
ENDCLASS.

* Specific decorator class to add specific behavior
CLASS lcl_decorator_b DEFINITION
INHERITING FROM lcl_decorator.
  PUBLIC SECTION.
    METHODS operation REDEFINITION.

  PRIVATE SECTION.
    METHODS added_behavior.
ENDCLASS.

CLASS lcl_decorator_b IMPLEMENTATION.
  METHOD operation.
    super->operation(  ).
    added_behavior( ).
    WRITE / 'Operation in decorator B'.
  ENDMETHOD.

  METHOD added_behavior.
    WRITE / 'Some added behavior was done in decorator B'.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA: lo_component   TYPE REF TO lcl_component,
        lo_decorator_a TYPE REF TO lcl_decorator_a,
        lo_decorator_b TYPE REF TO lcl_decorator_b.

  " component and specific decorator is prepared
  lo_component = NEW #( ).
  lo_decorator_a = NEW #( ).
  lo_decorator_b = NEW #( ).

  " behavior of operation is extended by specific decorator
  lo_decorator_a->set_component( lo_component ).
  lo_decorator_b->set_component( lo_decorator_a ).
  lo_decorator_b->operation(  ).

4.2 通过接口实现

*&---------------------------------------------------------------------*
*& Report zdecorator_pattern
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zdecorator_pattern2.

* here the component is an dedicated interface
INTERFACE lif_component.
  METHODS operation.
ENDINTERFACE.

* Target class implements he behavior of component interface
CLASS lcl_target DEFINITION.
  PUBLIC SECTION.
    INTERFACES: lif_component.
ENDCLASS.

CLASS lcl_target IMPLEMENTATION.
  METHOD lif_component~operation.
    WRITE / 'Operation in target'.
  ENDMETHOD.
ENDCLASS.

* Specific decorator class a to add specific behavior
CLASS lcl_decorator_a DEFINITION.
  PUBLIC SECTION.
    METHODS constructor
      IMPORTING
        io_component TYPE REF TO lif_component.

    INTERFACES: lif_component.
  PRIVATE SECTION.
    METHODS added_behavior.
    DATA mo_component TYPE REF TO lif_component.
ENDCLASS.

CLASS lcl_decorator_a IMPLEMENTATION.
  METHOD constructor.
    mo_component = io_component.
  ENDMETHOD.

  METHOD lif_component~operation.
    IF mo_component IS BOUND.
      mo_component->operation(  ).
      added_behavior( ).
    ENDIF.
  ENDMETHOD.

  METHOD added_behavior.
    WRITE / 'Operation in decorator a'.
  ENDMETHOD.
ENDCLASS.

* Specific decorator class b to add specific behavior
CLASS lcl_decorator_b DEFINITION.
  PUBLIC SECTION.
    METHODS constructor
      IMPORTING
        io_component TYPE REF TO lif_component.

    INTERFACES: lif_component.
  PRIVATE SECTION.
    METHODS added_behavior.
    DATA mo_component TYPE REF TO lif_component.
ENDCLASS.

CLASS lcl_decorator_b IMPLEMENTATION.
  METHOD constructor.
    mo_component = io_component.
  ENDMETHOD.

  METHOD lif_component~operation.
    IF mo_component IS BOUND.
      mo_component->operation(  ).
      added_behavior( ).
    ENDIF.
  ENDMETHOD.

  METHOD added_behavior.
    WRITE / 'Operation in decorator b'.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  DATA lo_component TYPE REF TO lif_component.
  DATA lo_target TYPE REF TO lcl_target.
  DATA lo_decorator_a TYPE REF TO lcl_decorator_a.
  DATA lo_decorator_b TYPE REF TO lcl_decorator_b.

  " prepare service via decorator
  lo_target = NEW lcl_target(  ).
  lo_decorator_a = NEW lcl_decorator_a( lo_target ).
  lo_decorator_b = NEW lcl_decorator_b( lo_decorator_a ).

  " return service to client
  lo_component = lo_decorator_b.

  " Client uses service without knowing decorating details
  lo_component->operation(  ).

运行结果如下:
在这里插入图片描述

本博客专注于技术分享,干货满满,持续更新。
欢迎关注❤️、点赞👍、转发📣!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十年铸器

给作者赏杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值