定义一个操作中算法的骨架,将一些步骤延迟到子类中。
模板方法模式使得子类可以在不改变算法结构的前提下,重写算法的某些步骤。
类比:
解析:
万事万物没有绝对的好与坏,关键在于使用的人、使用的方式。把合适的人或物,放到/应用到合适的位置/场景,才是真正的高手。
各种角色:
要点:
下图展示了,加入Hook Method后,模板方法的执行流程图。
设计模式对比:
下面给出一个利用模板方法模式,制作三明治的例子。
三明治制作的步骤是固定的,需要加面包片,奶油,蔬菜等等,但对于不同类型的三明治,其具体的搭配可以是不同的。
在使用模板方式,应注意对于各个方法的关键字限定。
REPORT ztemplate_method_pattern.
CLASS lcl_template_sandwich DEFINITION ABSTRACT CREATE PROTECTED.
PUBLIC SECTION.
METHODS prepare_sandwich FINAL. " do not allow to redefine
PROTECTED SECTION.
METHODS add_butter. " can be overwritten
METHODS add_extra ABSTRACT. " needs to be redefined
METHODS add_veggetables ABSTRACT. " needs to be redefined
PRIVATE SECTION.
METHODS slice_bread.
ENDCLASS.
CLASS lcl_template_sandwich IMPLEMENTATION.
METHOD add_butter.
WRITE: / 'Add thin layer of butter'.
ENDMETHOD.
METHOD prepare_sandwich.
slice_bread( ).
add_butter( ).
add_extra( ).
add_veggetables( ).
ENDMETHOD.
METHOD slice_bread.
WRITE:/ 'Slice bread'.
ENDMETHOD.
ENDCLASS.
**********************************************************************
CLASS lcl_cheese_sandwich DEFINITION FINAL CREATE PUBLIC
INHERITING FROM lcl_template_sandwich.
PROTECTED SECTION.
METHODS:
add_butter REDEFINITION,
add_extra REDEFINITION,
add_veggetables REDEFINITION.
ENDCLASS.
CLASS lcl_cheese_sandwich IMPLEMENTATION.
METHOD add_butter.
WRITE: / 'Add thick layer of butter'.
ENDMETHOD.
METHOD add_extra.
WRITE: / 'Add slices of cheese'.
ENDMETHOD.
METHOD add_veggetables.
WRITE: / 'Add tomato slices'.
ENDMETHOD.
ENDCLASS.
**********************************************************************
CLASS lcl_ham_sandwich DEFINITION FINAL CREATE PUBLIC
INHERITING FROM lcl_template_sandwich.
PROTECTED SECTION.
METHODS: add_extra REDEFINITION,
add_veggetables REDEFINITION.
ENDCLASS.
CLASS lcl_ham_sandwich IMPLEMENTATION.
METHOD add_extra.
WRITE: / 'Add slices of ham'.
ENDMETHOD.
METHOD add_veggetables.
WRITE: / 'Add salad leaves'.
WRITE: / 'Add onions'.
ENDMETHOD.
ENDCLASS.
**********************************************************************
START-OF-SELECTION.
**********************************************************************
DATA lt_sandwich TYPE TABLE OF REF TO lcl_template_sandwich.
lt_sandwich = VALUE #( ( NEW lcl_cheese_sandwich( ) )
( NEW lcl_ham_sandwich( ) ) ).
LOOP AT lt_sandwich INTO DATA(lo_sandwich).
WRITE: / '...This is sandwich :' && sy-tabix && '...'.
lo_sandwich->prepare_sandwich( ).
ENDLOOP.
在上例中,我们利用模板三明治,制作了奶酪三明治和火腿三明治。程序运行结果如下:
下面给出一个简单的示例,展示了如何使用Hook Method钩子方法控制模板方法中的执行逻辑:
CLASS lcl_template_sandwich DEFINITION ABSTRACT CREATE PROTECTED.
PUBLIC SECTION.
METHODS prepare_sandwich FINAL. " do not allow to redefine
PROTECTED SECTION.
METHODS add_butter. " can be overwritten
METHODS is_extra_required RETURNING VALUE(rv_yes) TYPE abap_bool. " hook method
METHODS add_extra ABSTRACT. " needs to be redefined
METHODS add_veggetables ABSTRACT. " needs to be redefined
PRIVATE SECTION.
METHODS slice_bread.
ENDCLASS.
CLASS lcl_template_sandwich IMPLEMENTATION.
METHOD add_butter.
WRITE: / 'Add thin layer of butter'.
ENDMETHOD.
METHOD prepare_sandwich.
slice_bread( ).
add_butter( ).
IF is_extra_required( ). " hook to control whether a specific step needs to be executed
add_extra( ).
ENDIF.
add_veggetables( ).
ENDMETHOD.
METHOD slice_bread.
WRITE:/ 'Slice bread'.
ENDMETHOD.
METHOD is_extra_required.
rv_yes = abap_false.
ENDMETHOD.
ENDCLASS.
此例中的方法 :
* METHODS is_extra_required RETURNING VALUE(rv_yes) TYPE abap_bool. *
就是一个hook method,它使得子类可以有选择地实现模板类中定义的步骤方法,并通过返回值,控制模板类中算法的执行。
.
.
.
以上,是本篇对模板方法模式的总结,欢迎分享、留言。
本博客专注于技术分享,干货满满,持续更新。
欢迎关注❤️、点赞、转发!