ABAP与设计模式之工厂方法模式

 

在原文基础上整理了一下,并做了测试,代码可运行。

原文地址: http://tech.sina.com.cn/s/2009-08-07/10501017671.shtml

 

内容:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

简单来说,工厂方法模式能够封装具体的类型的实例化。

结构:

Product:所有产品都必须实现这个共同的接口,这样一来,使用这些产品的类就可以引用这个接口,而不是具体类。

ConcreteCreator:负责创建一个或者多个具体产品,只有concrete creator类知道如何创建这些产品。同时,它实现了factory method,以实际制造出产品。

Creator: 是一个抽象类,它实现了所有操作产品的方法,但不实现工厂方法。其所有的子类都必须实现这个抽象的factorymethod()方法。

实例程序,首先给出类图:

 

注意:创建类和产品类是平行的,因为他们都是抽象类,而抽象类都有许多具体的子类,每个子类都有自己特定的实现。

测试程序如下:

 

REPORT  zgary_t007.

INCLUDE zgary_t007_class_define.

*This data used to create two type of concrete creator
DATA: ny_ref  TYPE REF TO pizzastore,
      chi_ref TYPE REF TO pizzastore.

*the different pizza have the same interface
DATA: pz_ref TYPE REF TO pizza.

START-OF-SELECTION.

* Create two different pizzastore
  CREATE OBJECT ny_ref TYPE ny.  "For NY
  CREATE OBJECT chi_ref TYPE chi."For Chi

* Book NY store's pizza
  CALL METHOD ny_ref->orderpizza
    EXPORTING
      pz_name1 = 'CHEESE'
    RECEIVING
      pz       = pz_ref.

* Get the pizza's name
  DATA: ls TYPE string.
  CALL METHOD pz_ref->getname
    RECEIVING
      na = ls.

  WRITE: / 'Ethan ordered a:',ls.

  SKIP.

* Book Chi store's pizza
  CALL METHOD chi_ref->orderpizza
    EXPORTING
      pz_name1 = 'CHEESE'
    RECEIVING
      pz       = pz_ref.

* Get the pizza's name
  CALL METHOD pz_ref->getname
    RECEIVING
      na = ls.

  WRITE: / 'Joel ordered a:', ls.

*&---------------------------------------------------------------------*
*&  Include           ZGARY_T007_CLASS_DEFINE
*&---------------------------------------------------------------------*

*抽象产品类:
*declare product class
CLASS pizza DEFINITION ABSTRACT.

  PUBLIC SECTION.
* define instance variants
    DATA: name  TYPE string,
          dough TYPE string,
          sauce TYPE string.

    DATA: BEGIN OF rtab,
             str TYPE string,
          END OF rtab,
          itab LIKE TABLE OF rtab.

* methods which will be inherited by subclass
    METHODS:
      prepare, " prepare pizza
      bake,    " bake pizza
      cut,     " cut pizza
      box,     " boxing pizza
      getname  " getter method to get pizza name
        RETURNING value(na) TYPE string.

ENDCLASS.                    "

*implement the pizza class
CLASS pizza IMPLEMENTATION.
  METHOD prepare.
    WRITE: / 'Preparing:', name,
           / 'Tossing dough....',
           / 'Adding sauce....',
           / 'Adding toppings:'.

    LOOP AT itab INTO rtab.
      WRITE: / rtab-str.
    ENDLOOP.
  ENDMETHOD.                    "prepare

  METHOD bake.
    WRITE: / 'Bake for 25 minutes at 350'.
  ENDMETHOD.                    "bake

  METHOD cut.
    WRITE: / 'Cutting the pizza into diagonal slices'.
  ENDMETHOD.                    "cut

  METHOD box.
    WRITE: / 'place pizza in official PizzaStore box'.
  ENDMETHOD.                    "box

  METHOD getname.
    na = name.
  ENDMETHOD.                    "getname

ENDCLASS.                    "

*工厂类:
*delare plant method class
*we can now define plant class, note that it is in the same leve as produ
CLASS pizzastore DEFINITION ABSTRACT.
  PUBLIC SECTION.

    METHODS:
      orderpizza " this method is used to order the concrete product
        IMPORTING pz_name1  TYPE string
        RETURNING value(pz) TYPE REF TO pizza.

  PROTECTED SECTION.
    METHODS:
      "this method seems LIKE a factory
      "because this method is ABSTRACT, the subclass must instantiate thi
      "this method must have a return value, which is the concrete produc
      createpizza ABSTRACT
        IMPORTING pz_name2 TYPE string
        RETURNING value(pz) TYPE REF TO pizza.

ENDCLASS.                    "

*----------------------------------------------------------------------*
*       CLASS pizzastore IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS pizzastore IMPLEMENTATION.

  METHOD orderpizza.

    DATA: pz_ref TYPE REF TO pizza.

    "this is the key part of factory method pattern
    "we use factory method to create concrete product
    CALL METHOD createpizza
      EXPORTING
        pz_name2 = pz_name1
      RECEIVING
        pz       = pz_ref.

    " other methods
    CALL METHOD:
      pz_ref->prepare,
      pz_ref->bake,
      pz_ref->cut,
      pz_ref->box.

    " return the concrete product which have been created
    pz = pz_ref.

  ENDMETHOD.                    "orderpizza

ENDCLASS.                    "pizzastore IMPLEMENTATION

*具体产品类:
*ok, now we can concrete product
CLASS nystylepizza1 DEFINITION

INHERITING FROM pizza.

  PUBLIC SECTION.
    METHODS:
      constructor.

ENDCLASS.                    "pizzastore IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS nystylepizza1 IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS nystylepizza1 IMPLEMENTATION.

  METHOD constructor.

    CALL METHOD super->constructor.
    name     = 'NY style Sauce and Cheese Pizza'.
    dough    = 'Thin Crust Dough'.
    sauce    = 'Marinara Sauce'.
    rtab-str = 'Grated Reggiano Cheese'.
    APPEND rtab TO itab.
  ENDMETHOD.                    "constructor

ENDCLASS.                    "nystylepizza1 IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS chistylepizza1  DEFINITIO
*----------------------------------------------------------------------*
CLASS chistylepizza1 DEFINITION

INHERITING FROM pizza.

  PUBLIC SECTION.
    METHODS:
      constructor,
      cut REDEFINITION.

ENDCLASS.                    "chistylepizza1  DEFINITIO

*----------------------------------------------------------------------*
*       CLASS chistylepizza1 IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS chistylepizza1 IMPLEMENTATION.

  METHOD constructor.
    CALL METHOD super->constructor.
    name     = 'Chicago Style Deep Dish Cheese Pizza'.
    dough    = 'Extra Thick Crust Dough'.
    sauce    = 'Plum Tomato Sauce'.
    rtab-str = 'Shredded Mozzarella Cheese'.
    APPEND rtab TO itab.
  ENDMETHOD.                    "constructor

  METHOD cut.
    WRITE: / 'Cutting the pizza into square slices'.
  ENDMETHOD.                    "cut

ENDCLASS.                    "chistylepizza1 IMPLEMENTATION

*具体创建类:
*now we can define the concrete creator
CLASS ny DEFINITION INHERITING FROM pizzastore.

  PROTECTED SECTION.
    METHODS:
      createpizza REDEFINITION.

ENDCLASS.                    "chistylepizza1 IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS ny IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS ny IMPLEMENTATION.

  METHOD createpizza.
    CASE pz_name2.
      WHEN 'CHEESE'.
        CREATE OBJECT pz TYPE nystylepizza1.
      WHEN 'VEGIE'.
      WHEN 'CLAM'.
      WHEN 'PEPPERONI'.
    ENDCASE.

  ENDMETHOD.                    "createpizza

ENDCLASS.                    "ny IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS chi DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS chi DEFINITION INHERITING FROM pizzastore.

  PROTECTED SECTION.
    METHODS:
      createpizza REDEFINITION.

ENDCLASS.                    "chi DEFINITION

*----------------------------------------------------------------------*
*       CLASS chi IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS chi IMPLEMENTATION.

  METHOD createpizza.
    CASE pz_name2.
      WHEN 'CHEESE'.
        CREATE OBJECT pz TYPE chistylepizza1.
      WHEN 'VEGIE'.
      WHEN 'CLAM'.
      WHEN 'PEPPERONI'.
    ENDCASE.
  ENDMETHOD.                    "createpizza

ENDCLASS.                    "chi IMPLEMENTATION

程序运行结果:


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值