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