我的任务是在 ABAP 中创建 multition 设计模式的简单演示。据我了解,创建的实例应存储到静态内部表中,以便以后使用。这是我的尝试:
CLASS zrp_casino_bl DEFINITION
PUBLIC
FINAL
CREATE PRIVATE .
PUBLIC SECTION.
CLASS-METHODS: get_instance IMPORTING i_player_id TYPE i OPTIONAL"Here i_player_id - key for creating the instance. Assume that duplicate names cannot exist.
"Optional, so that the user has the option to create a new instance or call and existing one via the key
RETURNING VALUE(r_instance) TYPE REF TO zrp_casino_bl.
METHODS: print_player_info.
PROTECTED SECTION.
PRIVATE SECTION.
TYPES: BEGIN OF player_info_st,
player_id TYPE i,
instance TYPE REF TO zrp_casino_bl,
END OF player_info_st,
player_info_tt TYPE TABLE OF player_info_st WITH DEFAULT KEY.
CLASS-DATA: player_info_tab TYPE player_info_tt,
player_id TYPE i,
player_winnings TYPE i,
win_or_loose TYPE abap_bool.
DATA: instance_data TYPE REF TO zrp_casino_bl.
METHODS: assign_winnings RETURNING VALUE(r_winnings) TYPE i,
determine_win_or_loose RETURNING VALUE(r_result) TYPE abap_bool,
constructor IMPORTING i_player_id TYPE i OPTIONAL.
CLASS-METHODS: get_max_player_id RETURNING VALUE(r_maxid) TYPE i,
add_new_instance IMPORTING i_player_id TYPE i OPTIONAL
RETURNING VALUE(r_instance) TYPE REF TO zrp_casino_bl,
retrieve_existing_instance IMPORTING i_player_id TYPE i
RETURNING VALUE(r_instance) TYPE REF TO zrp_casino_bl.
ENDCLASS.
CLASS zrp_casino_bl IMPLEMENTATION.
METHOD determine_win_or_loose.
"some simple stuff here, not important
METHOD assign_winnings.
IF player_id = 1.
r_winnings = 100.
ELSEIF player_id = 2.
r_winnings = 200.
ELSEIF player_id = 3.
r_winnings = 300.
ELSEIF player_id = 4.
r_winnings = -400.
ENDIF.
ENDMETHOD.
METHOD get_max_player_id.
SORT player_info_tab BY player_id DESCENDING.
r_maxid = player_info_tab[ 1 ]-player_id.
ENDMETHOD.
METHOD get_instance.
IF i_player_id IS NOT SUPPLIED.
r_instance = add_new_instance( ).
ELSE.
IF line_exists( player_info_tab[ player_id = i_player_id ] ).
r_instance = retrieve_existing_instance( i_player_id ).
ELSE.
r_instance = add_new_instance( i_player_id ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD constructor.
player_id = i_player_id.
player_winnings = me->assign_winnings( ).
win_or_loose = me->determine_win_or_loose( ).
ENDMETHOD.
METHOD print_player_info.
cl_demo_output=>display( 'Player name: ' && player_id && |\n| &&
'Player winnings: ' && player_winnings && |\n| &&
'Is the player winning : ' && win_or_loose ).
ENDMETHOD.
METHOD add_new_instance.
IF i_player_id IS SUPPLIED.
r_instance = NEW #( i_player_id ).
INSERT VALUE #( player_id = i_player_id instance = r_instance ) INTO TABLE player_info_tab.
ELSE.
r_instance = NEW #( get_max_player_id( ) + 1 ).
INSERT VALUE #( player_id = get_max_player_id( ) + 1 instance = r_instance ) INTO TABLE player_info_tab.
ENDIF.
ENDMETHOD.
METHOD retrieve_existing_instance.
LOOP AT player_info_tab ASSIGNING FIELD-SYMBOL(<info>) WHERE player_id = i_player_id.
r_instance = <info>-instance.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
结果:每次我创建一个这样的新实例时:
DATA(instance1) = zrp_casino_bl=>get_instance( i_player_id = 1 ).
instance1->print_player_info( ).
DATA(instance2) = zrp_casino_bl=>get_instance( i_player_id = 2 ).
instance2->print_player_info( ).
该实例被保存到表中,但会覆盖以前存在的记录。因此,如果我创建一个玩家 ID 为 1、2、3、4 的实例,我将在表中拥有 4 个实例引用,但它们都将引用最后创建的实例。
我理解这个问题 - 我正在使用 NEW 关键字,它会覆盖现有记录。我该如何解决这个问题?任何帮助将不胜感激。