10월 13일..
1.
SINGLETON
보통 Singleton pattern 시스템에 객체를 오직 1개만 사용하기 위하여 만든다.
SE24 -> CL_SINGLETON
사용 이유 One Instance possible
Singleton의 대표적인 부분은 자바에서의 Servlet 객체일듯 하다. 1개만 ... 해서 모두 빌려쓰는...
2. Friend - FriendShip의 관계......
Private 인 객체나 메소드에도 Friend 관계가 정의되면 접근 할 수 있게 된다.
Visual basic 에 Friend 라는 접근자가 있는걸 본적이 있다 사용해 본적은 없지만...
그 언어에서도 사용을 지양하라고 봤던 것 같다.
A 운전자는 자기 자동차를 운전할 수 있다.
다른 사람들은 A운전자의 자동차를 운전할 수 없다.
근데 정비기사님 께서는 A운전자의 자동사를 시운전 할 수 있다는.. 그런 이야기를 봤었다.
하지만 실제 객체들의 관계를 정의할때 모호해 질 위험이 아주 커 보인다....
3. 예외 try ~ endtry
exception class 는
zcx 로 시작하게 만들수 있다.
예외가 나도록 실행하면 error 화면에 exception class 가 표시 되므로 이를 이용해서 사용 하는 방법도 있다.
사실 OOP로 프로그램을 작성한다면 .. Error로 인한 Exception 이 발생하기 전에 미리 처리를 해 두는 것이
옳은 판단일 것 같다. ->아마도 Exception에 관련된 예제들을 따로 찾아봐야 할 것 같다.(잊지 말고 정리하기)
4.
shared objects
우리가 이미 배웠던 내용이라고 한다.
프로그램에서 아주 빈번히 발생하는 공동사용 구간에 대한 접근 및 사용이다.
다수의 유저가 공유해야하고.. 다수의 유저는 변경된 사항에 대해서 알아챌 수 있어야 하므로...
한 메모리 영역을 모두가 참조하게 되면.. 그 다수의 유저중 누군가가 정보를 바꾸어도 다수의 유저들이 모두
공유 할 수 있을 것이다.
보통 System 의 properties 정보 등을 공통 영역의 Properties 파일로 만들어 WAS가 구동될 때 Singleton으로
올려놓았던 것이 생각난다.
다시 ABAP으로...
T-code
shma - memory 에 area를 만들수 있다.
shmm - memory 를 모니터링 할 수 있습니다.
shma 에서 만들어보자..
/nshma 로 접근.
1.'zcl08_kdn_area ' 라는 이름을 사용 description 도 채워준 후 create 버튼을 눌러준다.
2. Basic Properties에 Root Class 에 "ZCL08_KDN_ROOT " 라고 적어준다.
3. Client-Specific Area를 클릭해준다.
4. SE24의 "ZCL08_KDN_ROOT" 로 이동이 되었다.
5. Properties 에 General Data 에 "Shared Memory-Enabled" 를 클릭해준다.
6. Attribute 에 r_cat 를 associated type : ZCL08_KDN_CATALOGUE 인 instance 로 지정해준다.
7. ZCL08_KDN_CATALOGUE 를 DOUBLE CLICK 하여 SE24의 ZCL08_KDN_CATALOGUE 지정 화면으로 이동한다.
8. Properties 에 General Data 에 "Shared Memory-Enabled" 를 클릭해준다.
9. attribute 에 IT_SPFLI , instance , private , SPFLI_TAB 으로 지정해준다.
10. methods 에 set_data 와 get_data를 지정해 준다.
11. set_data ~
METHOD set_data.
SELECT * FROM spfli INTO TABLE it_spfli .
ENDMETHOD.
12. get_data
METHOD get_data.
DATA: wa_spfli TYPE spfli.
LOOP AT it_spfli INTO wa_spfli WHERE carrid = im_carrid.
WRITE: / wa_spfli-carrid, wa_spfli-connid,
wa_spfli-cityfrom, wa_spfli-cityto .
ENDLOOP.
ENDMETHOD.
13. parameter 지정 : IM_CARRID , importing , SPFLI-CARRID
14. zcl08_kdn_catalogue - 활성화 후 F3 -> zcl08_kdn_root - 활성화 후 F3 -> shma 화면에서 저장 버튼을 누른 후 F3 을 누른다.
15. ctrl+ F3 (genarate area class) 를 눌러준다.
16. SE38의 프로그램으로 접근...
*&---------------------------------------------------------------------*
*& Report Z08_KDN_OOP15
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT z08_kdn_oop15.
DATA: r_handle TYPE REF TO zcl08_kdn_area.
DATA: r_root TYPE REF TO zcl08_kdn_root,
r_catalogue TYPE REF TO zcl08_kdn_catalogue.
*TRY.
CALL METHOD zcl08_kdn_area=>attach_for_write
* EXPORTING
* CLIENT =
* INST_NAME = CL_SHM_AREA=>DEFAULT_INSTANCE
* ATTACH_MODE = CL_SHM_AREA=>ATTACH_MODE_DEFAULT
* WAIT_TIME = 0
RECEIVING
handle = r_handle.
CREATE OBJECT r_root AREA HANDLE r_handle.
CREATE OBJECT r_catalogue AREA HANDLE r_handle.
r_root->r_cat = r_catalogue.
r_handle->set_root( r_root ).
r_handle->root->r_cat->set_data( ).
r_handle->detach_commit( ).
* CATCH CX_SHM_EXCLUSIVE_LOCK_ACTIVE .
* CATCH CX_SHM_VERSION_LIMIT_EXCEEDED .
* CATCH CX_SHM_CHANGE_LOCK_ACTIVE .
* CATCH CX_SHM_PARAMETER_ERROR .
* CATCH CX_SHM_PENDING_LOCK_REMOVED .
*ENDTRY.
이렇게 만들어 주고 활성화.
17. t-code "SHMM " 로 접근하여 자신이 작성한 Area 가 올라가 있는지 확인하기.
(오후) page 323
프로그램을 만들어 봅니다.
SE38 에 접속 후 'Z08_KDN_OOP_WRITE' CREATE해줍니다.
오전에는 attach 를 해보았습니다.
이제 읽어볼텐데...
Z08_KDN_OOP_read
DATA : r_handle TYPE REF TO zcl08_kdn_area.
PARAMETERS: pa_carr TYPE spfli-carrid.
*TRY.
CALL METHOD zcl08_kdn_area=>attach_for_read
* EXPORTING
* CLIENT =
* INST_NAME = CL_SHM_AREA=>DEFAULT_INSTANCE
RECEIVING
handle = r_handle.
r_handle->root->r_cat->get_data( pa_carr ).
r_handle->detach( ).
* CATCH CX_SHM_INCONSISTENT .
* CATCH CX_SHM_NO_ACTIVE_VERSION .
* CATCH CX_SHM_READ_LOCK_ACTIVE .
* CATCH CX_SHM_EXCLUSIVE_LOCK_ACTIVE .
* CATCH CX_SHM_PARAMETER_ERROR .
* CATCH CX_SHM_CHANGE_LOCK_ACTIVE .
*ENDTRY.
fiend Symbols. - 대리자 역할을 한다.
REPORT z08_kdn_oop16.
DATA: int1 TYPE i VALUE 17.
FIELD-SYMBOLS: <int1> TYPE i.
ASSIGN int1 TO <int1>.
<int1> = <int1> + 1.
WRITE: / int1, <int1>.
CASTING SYMBOLS
예제 2
REPORT z08_kdn_oop16.
TYPES: BEGIN OF st_date,
year(4) TYPE n,
month(2) TYPE n,
day(2) TYPE n,
END OF st_date.
FIELD-SYMBOLS : <fs> TYPE st_date.
<fs> = sy-datum.
WRITE : / <fs>.
sy-datum 은 field 이고 <fs> 는 구조체(Struture) 이기 때문에 ERROR 가 남...
REPORT z08_kdn_oop16.
TYPES: BEGIN OF st_date,
year(4) TYPE n,
month(2) TYPE n,
day(2) TYPE n,
END OF st_date.
FIELD-SYMBOLS : <fs> TYPE st_date.
ASSIGN SY-DATUM TO <FS>.
"앞은 날짜 이고 뒤는 구조체이다. 이렇게 하면 에러가 나고
ASSIGN SY-DATUM TO <FS> CASTING.
"이렇게 하면 eRROR 이 나지 않는다.
WRITE : / <fs>.
예2 > 실제 코딩에선 이처럼 많이 쓰인다.
TYPES: BEGIN OF st_date,
year(4) TYPE n,
month(2) TYPE n,
day(2) TYPE n,
END OF st_date.
FIELD-SYMBOLS : <fs>, <fs_comp>.
ASSIGN sy-datum TO <fs> CASTING TYPE st_date.
"앞은 날짜 이고 뒤는 구조체이다ㅣ.
ASSIGN COMPONENT 1 OF STRUCTURE <fs> TO <fs_comp>.
WRITE : / <fs_comp>.
예3 번째 - 원래는 이렇게 사용 하면 안된다.
DATA: int1 TYPE i VALUE 17.
DATA: ref1 TYPE REF TO i.
GET REFERENCE OF int1 INTO ref1.
" INT1= DATAOBJECT REF1 = REFRANCE
ref1->* = ref1->* + 1.
WRITE: / int1, ref1->*.
예4 원래는 ref 를 바로 사용 하시는게 아니라 Symbols 를 넘겨서 사용 해야한다.
DATA: int1 TYPE i VALUE 17.
DATA: ref1 TYPE REF TO i.
FIELD-SYMBOLS: <fs> TYPE i.
GET REFERENCE OF int1 INTO ref1.
" INT1= DATAOBJECT REF1 = REFRANCE
GET REFERENCE OF int1 INTO ref1.
ASSIGN ref1->* TO <fs>.
<fs> = <fs> + 1.
WRITE: / int1, <fs>.
이건 예제이기 때문에 이렇게 사용 합니다.
Assigned 인지 Bound 인지...
IF <fs> IS ASSIGNED.
WRITE: / 'Yes'.
ELSE.
WRITE: / 'No...'.
ENDIF.
IF ref1 IS BOUND.
WRITE: / 'Yes'.
ELSE.
WRITE: / 'No...'.
ENDIF.
자기 자신을 참조할 수도 있다.
DATA: ref1 TYPE REF TO i.
CREATE DATA ref1.
ref1->* = 17.
WRITE: / ref1->*.
그럼 Symbol 은 안되느냐?
->이건 못 적었네요@_@;;
그럼 형 변환은 어찌 될가요?
DATA: ref1 TYPE REF TO data.
create DATA ref1 type spfli.
"이런 식으로 해볼수 있고~
create DATA ref1 type i.
"이런 식으로 요런식으로도 해볼 수 있습니다.
아마도 Abap에서의 data형은 Java에서의 Object 형 처럼 최상위 객체인가 봅니다.
이제는 조금 더 바꿔보자.
형변환을 하게 되는 예제.
DATA: ref1 TYPE REF TO data.
PARAMETERS : my_type(10).
CREATE DATA ref1 TYPE (my_type). " ( ) 안에 감싸면 value 를 넘겨주게 된다.
BREAK-POINT.
이렇게 상위 객체로 선언하고 하위의 객체로 적용하는 방식을 사용하면 추후 유지보수에 엄청나게 영향을 주겠죠...
직접 참조와 간접 참조...
동적 프로그래밍 예제
REPORT z08_kdn_oop17.
DATA: ref_itab TYPE REF TO data,
ref_wa TYPE REF TO data.
" refrence 의 특징이 주소만 가지고 있기 때문에 하나하나 쪼개져 있는
"필드 에 대한 접근이 불가능 하다 그래서 필드 심볼을 써라.
FIELD-SYMBOLS: <fs_itab> TYPE ANY TABLE, "기억하세요 ANY TABLE
<fs_wa> TYPE ANY,
<fs_comp> TYPE ANY.
PARAMETERS pa_tab TYPE dd02l-tabname DEFAULT 'SPFLI'.
START-OF-SELECTION.
CREATE DATA ref_itab TYPE STANDARD TABLE OF (pa_tab)
WITH NON-UNIQUE DEFAULT KEY.
ASSIGN ref_itab->* TO <fs_itab>." field Symbol 은 Self-Instantiate X
SELECT *
FROM (pa_tab)
INTO TABLE <fs_itab>
UP TO 100 ROWS.
CREATE DATA ref_wa LIKE LINE OF <fs_itab>.
ASSIGN ref_wa->* TO <fs_wa>.
LOOP AT <fs_itab> INTO <fs_wa>.
"assigning <fs_wa> 로 바꿔 주고 Create data ref_wa 를 삭제해도 됨
DO .
ASSIGN COMPONENT sy-index OF STRUCTURE <fs_wa> TO <fs_comp>.
IF sy-subrc NE 0.
NEW-LINE.
EXIT.
ENDIF.
WRITE <fs_comp>.
ENDDO.
ENDLOOP.
*
SE16처럼 동적으로 프로그램을 만드는 예제입니다.
*&---------------------------------------------------------------------*
*& Report Z08_KDN_OOP18
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT z08_kdn_oop18.
DATA: int TYPE i VALUE 15,
date TYPE d VALUE '20040101'.
DATA : ref_int TYPE REF TO i,
ref_date TYPE REF TO d,
ref_gen TYPE REF TO data.
GET REFERENCE OF int INTO ref_int.
ref_gen = ref_int.
WRITE: / ref_int->*.
ref_int ?= ref_gen.
WRITE: / ref_int->*.
GET REFERENCE OF date INTO ref_date.
ref_gen = ref_date.
TRY .
ref_int ?= ref_gen.
CATCH cx_sy_move_cast_error.
MESSAGE i002(z08_kdn) WITH 'ref_gen' .
ENDTRY.
WRITE: / ref_int->*.
**
TRY 부분에서 EXCEPTION 이 발생하게 되는데...
ref_gen. 은 DATE 타입이 되어버려서 ref_int 의 INTEGER 형으로 변환이 안 되기 때문입니다.
*&---------------------------------------------------------------------*
*& Report Z08_KDN_OOP18
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT z08_kdn_oop18.
DATA: int TYPE i VALUE 15,
date TYPE d VALUE '20040101'.
DATA : ref_int TYPE REF TO i,
ref_date TYPE REF TO d,
ref_gen TYPE REF TO data.
GET REFERENCE OF int INTO ref_int.
ref_gen = ref_int.
WRITE: / ref_int->*.
ref_int ?= ref_gen.
WRITE: / ref_int->*.
GET REFERENCE OF date INTO ref_date.
ref_gen = ref_date.
TRY .
ref_int ?= ref_gen.
CATCH cx_sy_move_cast_error.
MESSAGE i002(z08_kdn) WITH 'ref_gen' .
ENDTRY.
WRITE: / ref_int->*.
Runtime type services
RTTS Inheritance
SE80 으로 가서
DATA: gs TYPE spfli,
go_descr TYPE REF TO cl_abap_structdescr,
gs_comp TYPE abap_compdescr.
go_descr ?= cl_abap_typedescr=>describe_by_data( gs ).
LOOP AT go_descr->components INTO gs_comp.
WRITE: / gs_comp-name, gs_comp-type_kind,
gs_comp-length.
ENDLOOP.
RUNTIME 중에 CLASS 의 NAME 을 알아 내어 보아요.
REPORT z08_kdn_oop20.
DATA: go_vehicle TYPE REF TO zcl08_kdn_vehicle,
go_truck TYPE REF TO zcl08_kdn_truck,
go_descr TYPE REF TO cl_abap_classdescr.
DATA: find_name TYPE string.
CREATE OBJECT go_vehicle.
CREATE OBJECT go_truck.
go_descr ?= cl_abap_typedescr=>describe_by_object_ref( go_vehicle ).
find_name = go_descr->get_relative_name( ).
WRITE: / find_name.
* GENERATING AN INTERNAL TABLE WITH A DYNAMICALLY CREATE TYPE.
정말 쓰지 않는 방식이다.
4주차 2강..
적용 방식중에
MODIFICATION 은 사용하지 말기~!
enhancement = 추천 추천의 ( ADD ON ) 방식이다.
enhancement [inhǽnsmənt, en-] [-hɑ́ːns-]
1. U,C (가격·매력·가치 등의) 상승, 등귀;향상, 증대
8문제정도 나올듯 ㅋㅋㅋ
2PAGE
*enhancement
1. ABAP Dictionary ┌ TABLE ENHANSMENT ┌ APPEND STRUCTURE
| CI(CUSTOMER INCLUDE)
└ DATA ELEMENT
2. program exit ┌ 1. FUNCTION MODULE EXIT ~ 1 , 2, 3은 모두 FUNCTION MOEULE 이 BASE가 된다.
(customer exit) | 2. MENU EXIT
└ 3. SCREEN EXIT
3. Business Transaction Events (BTE)
4. Business Add-Ins