技术开发 频道

ABAP与设计模式之装饰者模式

【IT168 技术文章】

    首先,按照惯例,上例子程序的类图


    测试程序如下:

    REPORT ZBOBO_DP_003_RE .

    
*The class and interface for this program

    include zbobo_dp_003_if_cl.

    
*Reference data for drink definition

    data: dr_ref type ref to drink.

    
*Temp reference for decorator

    data:tdr type ref to drink.

    start
-of-selection.

    
*-------------------start decorate---------------*

    
* Narrowing cast

    
* Create darkroast object

    create object tdr type darkroast.

    
* Make dr_ref point to the object darkroast

    
* And this is the need to be decorated material

    dr_ref
= tdr.

    
* Use mocha to decorate object darkroast

    create object tdr type mocha

    exporting dr
= dr_ref. "This dr_ref is darkroast

    dr_ref
= tdr.

    
* Use soy to decorate object mocha&darkroast

    create object tdr type soy

    exporting dr
= dr_ref. "This dr_ref is mocha

    dr_ref
= tdr.

    
* Use whip to decorate object soy&mocha&darkroast

    create object tdr type whip

    exporting dr
= dr_ref. "This dr_ref is soy

    dr_ref
= tdr.

    
*-------------------end decorate---------------*

    
* Define data which used to display data

    data: ls type string,lf type f.

    
* Get description

    ls
= dr_ref->getdesc( ).

    
* Get cost

    lf
= dr_ref->cost( ).

    
* Display result

    write:
/ ls, ':$',lf decimals 2 exponent 0.

 

   定义component,在我们的例子中是超类drink,注意它是一个抽象类

    *----------------------------------------------------------------------*

    
* INCLUDE ZBOBO_DP_003_IF_CL *

    
*----------------------------------------------------------------------*

    
*For the Decorator pattern, normally using an abstract super class

    
*And the Decorator class inherite from the super class also as an

    
* abstract class

    
*Super abstract class with drink

    
class drink definition abstract.

    
public section.

    data: desc type string.

    methods:

    
* Get the drink's description

    getdesc returning value(de) type string,

    
* Because the cost must be calculate from every concrete material

    
* It should be an abstract method

    cost
abstract returning value(co) type f.

    endclass.

    
*Implement the drink class

    
class drink implementation.

    method getdesc.

    
* Return the description

    de
= desc.

    endmethod.

    endclass.

    定义concrete component,在我们的例子中,它是饮料类的一个子类darkroast

    *An concrete class for drink, as one need to be decorated

    
class darkroast definition inheriting from drink.

    
public section.

    methods:

    
* initialization

    constructor,

    
* The subclass should implement abstract method from super

    cost redefinition.

    endclass.

    
*Implement darkroast

    
class darkroast implementation.

    method constructor.

    call method
super->constructor.

    
* Give a new description

    desc
= 'Darkroast'.

    endmethod.

    method cost.

    
* Get the raw material cost

    co
= '1.99'.

    endmethod.

    endclass.

     定义装饰者抽象类,注意,他只不过继承了drink类,并没有作什么,我们需要的只不过是一个接口,一个装饰者和被装饰者的交互接口。

   *Decorator definition, which will decorate the raw material

    
*The decorator should be as abstract class

    
*It is just for supply an interface, it won't implement

    
*any method of super class

    
*Or you could define new method here so that the subclass

    
*of decorator should have new method in it

    
class decorator definition abstract

    inheriting from drink.

    endclass.

    
class decorator implementation.

    endclass.
 

    定义具体的装饰者

    *Define the concrete decorator which will used to decorate

    
* the concrete drink object, for exp: darkroast

    
class mocha definition inheriting from decorator.

    
public section.

    
* Define the interface which will point to super class drink

    data:

    drink type ref to drink.

    methods:

    
* Ininitialization

    constructor

    importing dr type ref to drink,

    
* Redifine the getdesc method so that we can get the right name

    
* of the decorated drink

    getdesc redefinition,

    
* Redifine the cost method so that we can get the right price

    
* of the decorated drink

    cost redefinition.

    endclass.

    
class mocha implementation.

    method constructor.

    call method
super->constructor.

    
* Make drink instance variant point to decorator

    
* For example, if darkroast decorated with mocha

    
* the reference drink shoul be pointed to darkroast

    drink
= dr.

    endmethod.

    method getdesc.

    
* This method will show how many decorate material we used

    data: ls_mocha type string.

    ls_mocha
= drink->getdesc( ).

    concatenate ls_mocha
',Mocha' into de.

    endmethod.

    method cost.

    
* Calculate the total price of the new drink which be decorated

    
* by the decorator

    data: lf_mocha type f.

    lf_mocha
= drink->cost( ).

    co
= lf_mocha + '0.20'.

    endmethod.

    endclass.

    定义其他的装饰者,和上面的差不多

    *The below part is mostly the same as mocha, because all of them

    
*are decorators for the drink raw material

    
class soy definition inheriting from decorator.

    
public section.

    data:

    drink type ref to drink.

    methods:

    constructor

    importing dr type ref to drink,

    getdesc redefinition,

    cost redefinition.

    endclass.

    
class soy implementation.

    method constructor.

    call method
super->constructor.

    drink
= dr.

    endmethod.

    method getdesc.

    data: lssoy type string.

    lssoy
= drink->getdesc( ).

    concatenate lssoy
',Soy' into de.

    endmethod.

    method cost.

    data: lfsoy type f.

    lfsoy
= drink->cost( ).

    co
= lfsoy + '0.40'.

    endmethod.

    endclass.

    
class whip definition inheriting from decorator.

    
public section.

    data:

    drink type ref to drink.

    methods:

    constructor

    importing dr type ref to drink,

    getdesc redefinition,

    cost redefinition.

    endclass.

    
class whip implementation.

    method constructor.

    call method
super->constructor.

    drink
= dr.

    endmethod.

    method getdesc.

    data: lswhip type string.

    lswhip
= drink->getdesc( ).

    concatenate lswhip
',Whip' into de.

    endmethod.

    method cost.

    data: lfwhip type f.

    lfwhip
= drink->cost( ).

    co
= lfwhip + '0.60'.

    endmethod.

    endclass.

    这个程序比较难理解,有点像我们平时写的递归,下面我把getdesc方法的顺序画出来就比较容易理解了,说明如下:

    显示的图片不是很清楚地话,你可以用右键--〉图片另存为到本地就可以看清楚了。

0
相关文章