1. 定义
用一个单独的工厂类(factory class),来控制实例化过程。
2. 解读
类比:
- 简单工厂模式,类似于现实世界的工厂,也即,工厂根据客户需要,生成相应的产品。
- 在程序中,简单工厂模式,根据client的需求,返回相应的实例
解析:
- 类的功能与类的实例化的过程分离
- 隐藏生产类(production class)的功能信息
- 工厂类提升实例化过程的灵活性(不同的场景,返回不同的实例;动态返回实例)
- 工厂类的引入,隔离了调用方与服务提供方,当服务调整时,调用方无需改动
- 工厂类是测试隔离(Test Isolation, Test Double)的实现途径
问题:
- 简单工厂模式,在工厂中包含了必要的判断逻辑,根据客户端的选择条件动态实例化相关的类,对于客户端而言,去除了与具体产品的依赖。但当新增产品类时,工厂方法也要进行相关的调整,增加相关的分支判断。这违背了开放封闭原则。
- 有关简单工厂模式的改进,可以查看工厂方法模式。
结合应用:
- 简单工厂模式经常与策略模式结合使用
3. 举例
3.1 类图:
3.2 Factory根据类型返回实例
对于已知的不同场景,可以利用工厂类,在不同场景下返回对应的实例。
REPORT zsimple_factory_pattern.
**********************************************************************
* A generic interface
**********************************************************************
INTERFACE lif_generic_interface.
METHODS:
method_1,
method_2.
ENDINTERFACE.
CLASS lcl_factory DEFINITION DEFERRED.
**********************************************************************
* Specific class A to implement this interface
* 1) Production class shall be CREATE PRIVATE
* 2) Factory is the friend of production class
* 3) Factory is the only place to get the instance of production class
**********************************************************************
CLASS lcl_class_a DEFINITION FINAL CREATE PRIVATE FRIENDS lcl_factory.
PUBLIC SECTION.
INTERFACES: lif_generic_interface.
ENDCLASS.
CLASS lcl_class_a IMPLEMENTATION.
METHOD lif_generic_interface~method_1.
ENDMETHOD.
METHOD lif_generic_interface~method_2.
ENDMETHOD.
ENDCLASS.
**********************************************************************
* Specific class B to implement this interface
**********************************************************************
CLASS lcl_class_b DEFINITION FINAL CREATE PRIVATE FRIENDS lcl_factory.
PUBLIC SECTION.
INTERFACES: lif_generic_interface.
ENDCLASS.
CLASS lcl_class_b IMPLEMENTATION.
METHOD lif_generic_interface~method_1.
ENDMETHOD.
METHOD lif_generic_interface~method_2.
ENDMETHOD.
ENDCLASS.
**********************************************************************
* Factory class to control the instantiation
**********************************************************************
CLASS lcl_factory DEFINITION FINAL ABSTRACT.
PUBLIC SECTION.
" create per existing type
CLASS-METHODS create
IMPORTING
iv_type TYPE c
RETURNING
VALUE(ro_instance) TYPE REF TO lif_generic_interface.
ENDCLASS.
CLASS lcl_factory IMPLEMENTATION.
METHOD create.
CASE iv_type.
WHEN 'A'.
ro_instance = NEW lcl_class_a( ).
WHEN 'B'.
ro_instance = NEW lcl_class_b( ).
WHEN OTHERS.
ASSERT 1 = 2.
ENDCASE.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
3.3 Factory 动态返回实例
此种模式,更适用于架构性的设计。在架构中,允许不断增加实现相同接口的类,以及在不同场景下实例化它们。
**********************************************************************
* Factory class to control the instantiation
**********************************************************************
CLASS lcl_factory DEFINITION FINAL ABSTRACT.
PUBLIC SECTION.
" if there are multiple class to be implemented by scenario
" a dedicated customizing table could be defined
" the type of instantiation can be determined dynamically
CLASS-METHODS create_from_db
IMPORTING
iv_type TYPE c
RETURNING
VALUE(ro_instance) TYPE REF TO lif_generic_interface.
ENDCLASS.
CLASS lcl_factory IMPLEMENTATION.
METHOD create_from_db.
DATA:
lv_classname TYPE seoclname.
" layout of table ZFACTORYSIMPLE (client independent)
" Field Key Data Element
" TYPE X CHAR01
" CLASS _ SEOCLNAME
* SELECT SINGLE class FROM zfactorysimple
* INTO lv_classname
* WHERE type = iv_type.
IF sy-subrc = 0.
CREATE OBJECT ro_instance TYPE (lv_classname).
ELSE.
" in case getting no concrete class is not a valid situation, make sure
" implementation is complete (table entry is existing)
ASSERT 1 = 2.
ENDIF.
ENDMETHOD.
ENDCLASS.
本博客专注于技术分享,干货满满,持续更新。
欢迎关注❤️、点赞👍、转发📣!