0

我的任务是在 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 关键字,它会覆盖现有记录。我该如何解决这个问题?任何帮助将不胜感激。

4

1 回答 1

1

问题在这里:

CLASS-DATA: player_info_tab TYPE player_info_tt,
            player_id       TYPE i,
            player_winnings TYPE i,
            win_or_loose    TYPE abap_bool.

这将数据定义为静态类数据,这意味着这些变量的实际值在类的所有实例之间共享。您必须将这些变量声明为实例变量(player_info_tab 除外):

CLASS-DATA: player_info_tab TYPE player_info_tt.
DATA:       player_id       TYPE i,
            player_winnings TYPE i,
            win_or_loose    TYPE abap_bool.
于 2020-07-01T10:03:05.377 回答