반응형
“IMPORTING 파라미터를 3개 이하로 조정하라“는 메서드나 함수의 IMPORTING 파라미터 개수를 가급적 3개 이하로 유지하라는 코딩 스타일 지침입니다. 이는 메서드나 함수가 너무 많은 인수를 받지 않도록 제한하여, 코드의 가독성과 유지보수성을 높이고, 더 나은 설계를 추구하는 것을 목표로 합니다.
왜 IMPORTING 파라미터를 3개 이하로 제한해야 하는가?
1. 가독성
- 너무 많은 파라미터를 전달하면 메서드의 목적이 모호해질 수 있고, 메서드 호출부가 복잡해지며 이해하기 어려워집니다. 3개 이하의 파라미터로 제한하면 메서드가 수행하는 작업의 범위가 더 명확해지고, 코드가 더 직관적으로 보일 수 있습니다.
2. 유지보수성
- 많은 파라미터를 가진 메서드는 변경에 취약할 수 있습니다. 파라미터가 많아지면, 메서드의 인터페이스가 변경될 때마다 이를 사용하는 모든 곳에서 수정이 필요할 수 있습니다. 파라미터를 줄이면 변경의 영향을 줄일 수 있습니다.
3. 단일 책임 원칙(Single Responsibility Principle, SRP)
- 메서드가 너무 많은 파라미터를 받는 경우, 이 메서드가 여러 가지 책임을 지고 있을 가능성이 큽니다. 파라미터를 3개 이하로 제한하면 메서드의 책임을 명확하게 정의할 수 있으며, 단일 책임 원칙을 더 잘 준수할 수 있습니다.
4. 테스트 용이성
- 파라미터가 많으면 테스트가 복잡해지고, 다양한 조합의 파라미터를 모두 테스트하기가 어려워집니다. 파라미터 수를 줄이면 테스트 범위가 좁아지며, 테스트 시나리오를 더 쉽게 관리할 수 있습니다.
5. 메서드의 응집도 향상
- 적절한 파라미터 수로 메서드를 설계하면 메서드의 응집도가 높아집니다. 즉, 메서드가 하나의 명확한 작업을 수행하고, 이를 위해 필요한 최소한의 정보를 받게 됩니다. 이는 코드의 품질을 높이고, 이해하기 쉽게 만듭니다.
* 파라미터가 많은 경우
METHOD do_something.
IMPORTING
iv_name TYPE string
iv_age TYPE i
iv_address TYPE string.
ENDMETHOD.
* 개선된 방법: 구조체나 클래스를 사용해 파라미터 그룹화
TYPES: BEGIN OF ty_person,
name TYPE string,
age TYPE i,
address TYPE string,
END OF ty_person.
METHOD do_something.
IMPORTING
is_person TYPE ty_person.
ENDMETHOD.
“IMPORTING 파라미터를 3개 이하로 조정하라“는 메서드나 함수가 너무 많은 파라미터를 받지 않도록, 파라미터 수를 줄여 코드의 가독성, 유지보수성, 응집도를 높이자는 지침입니다. 파라미터를 그룹화하거나 객체를 활용하여 여러 파라미터를 묶고, 불필요한 파라미터를 제거함으로써 메서드의 인터페이스를 단순하게 만들 수 있습니다. 이를 통해 더 직관적이고 관리하기 쉬운 코드를 작성할 수 있습니다.
“옵션 파라미터를 추가하는 대신 메서드를 분할하라“는 메서드에 불필요하게 많은 선택적(옵션) 파라미터를 추가하기보다는, 메서드를 명확하게 분리하여 각각의 역할을 더욱 구체적으로 정의하라는 객체지향 설계 원칙입니다. 이는 단일 책임 원칙(Single Responsibility Principle, SRP)을 따르고, 코드의 가독성과 유지보수성을 향상시키기 위한 지침입니다.
* 잘못된 패턴 옵션 파라미터 사용
CLASS lcl_report DEFINITION.
PUBLIC SECTION.
METHODS: generate_report IMPORTING iv_report_type TYPE string OPTIONAL
iv_with_header TYPE abap_bool OPTIONAL
iv_with_footer TYPE abap_bool OPTIONAL.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD generate_report.
IF iv_with_header = abap_true.
* 헤더 추가
ENDIF.
* 리포트 본문 생성
IF iv_with_footer = abap_true.
* 푸터 추가
ENDIF.
ENDMETHOD.
ENDCLASS.
* 올바른 패턴 메서드 분할
CLASS lcl_report DEFINITION.
PUBLIC SECTION.
METHODS: generate_basic_report,
generate_report_with_header,
generate_report_with_footer,
generate_full_report.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD generate_basic_report.
* 리포트 본문 생성
ENDMETHOD.
METHOD generate_report_with_header.
* 헤더 추가
generate_basic_report( ).
ENDMETHOD.
METHOD generate_report_with_footer.
generate_basic_report( ).
* 푸터 추가
ENDMETHOD.
METHOD generate_full_report.
generate_report_with_header( ).
generate_report_with_footer( ).
ENDMETHOD.
ENDCLASS.
메서드 분할의 이점
1. 명확한 책임 할당
- 각 메서드는 자신이 수행할 작업에만 집중하며, 이를 통해 더 높은 응집도와 명확한 역할 분담을 달성할 수 있습니다.
2. 코드 재사용성
- 분할된 메서드를 서로 조합하거나 독립적으로 사용할 수 있어 코드 재사용성이 높아집니다. 예를 들어, generate_basic_report 메서드는 여러 다른 메서드에서 재사용될 수 있습니다.
3. 확장성
- 새로운 요구사항이 생기더라도, 기존 메서드에 옵션 파라미터를 추가하는 대신 새로운 메서드를 추가할 수 있어 더 쉽게 확장할 수 있습니다. 이렇게 하면 기존 메서드를 건드리지 않고도 새로운 기능을 추가할 수 있습니다.
4. 유닛 테스트의 용이성
- 각 메서드가 독립적으로 동작하기 때문에 테스트 케이스를 더 간단하게 작성할 수 있으며, 각 기능에 대한 테스트가 보다 명확해집니다.
“옵션 파라미터를 추가하는 대신 메서드를 분할하라“는 하나의 메서드에 여러 옵션 파라미터를 추가하는 것보다, 메서드를 분리하여 각각의 역할을 명확히 정의하라는 의미입니다. 이를 통해 단일 책임 원칙을 준수하고, 코드의 가독성, 유지보수성, 재사용성, 테스트 용이성을 크게 향상시킬 수 있습니다. 메서드가 너무 많은 일을 하거나 복잡해지는 것을 방지하기 위해, 작은 역할을 수행하는 여러 메서드로 나누는 것이 더 바람직한 설계입니다.
“우선적 파라미터를 남용하지 마라“는 코딩 스타일과 설계 원칙에 관한 지침으로, 우선적 파라미터(priority parameters)를 지나치게 많이 사용하지 말라는 의미입니다. 이는 메서드나 함수에서 중요한 파라미터를 지나치게 강조하거나 여러 개의 선택적/우선적 파라미터를 사용함으로써 코드가 복잡해지고, 가독성과 유지보수성이 저하되는 상황을 피하기 위한 권장 사항입니다.
우선적 파라미터란?
우선적 파라미터는 메서드나 함수에서 중요한 역할을 하는 파라미터로, 특정 조건에 따라 메서드의 동작을 결정하는 데 사용됩니다. 종종 선택적 파라미터(optional parameters)와 함께 사용되며, 특정 파라미터의 값이 우선시되어 메서드의 로직이 달라지는 경우가 많습니다.
* 잘못된 패턴
METHOD generate_report.
IMPORTING iv_format TYPE string DEFAULT 'PDF'
iv_priority TYPE i DEFAULT 0.
IF iv_priority = 1.
* 중요한 로직 1
ELSEIF iv_priority = 2.
* 중요한 로직 2
ELSE.
* 기본 로직
ENDIF.
ENDMETHOD.
우선적 파라미터 남용을 피하는 방법
1. 메서드 분할
- 메서드가 우선적 파라미터에 따라 다른 동작을 수행해야 한다면, 이를 여러 개의 작은 메서드로 분리하는 것이 좋습니다. 이렇게 하면 각 메서드가 하나의 명확한 역할을 수행하게 되어 코드가 더 간결해지고, 유지보수성이 향상됩니다.
2. 클래스나 객체로 캡슐화
- 여러 우선적 파라미터로 인해 메서드가 복잡해지는 경우, 해당 로직을 클래스로 캡슐화할 수 있습니다. 클래스를 통해 상태를 관리하고, 각 상태에 맞는 메서드를 제공하면 코드가 더 명확해지고 재사용성이 높아집니다.
3. 전략 패턴 사용
- 전략 패턴(Strategy Pattern)을 사용해 우선적 파라미터에 따른 다양한 동작을 클래스로 분리할 수 있습니다. 이를 통해 각 우선순위에 맞는 전략을 독립적으로 구현하고, 코드의 유연성을 높일 수 있습니다.
4. 조건문 최소화
- 우선적 파라미터로 인한 조건문을 최소화하고, 더 명확한 로직을 작성하는 것이 중요합니다. 각 조건문이 메서드의 동작을 지나치게 변경하지 않도록, 필요한 경우만 우선적 파라미터를 사용하도록 제한합니다.
“우선적 파라미터를 남용하지 마라“는 코드에서 우선적 파라미터를 지나치게 사용하여 메서드가 복잡해지는 것을 피하고, 대신 메서드를 분리하거나 다른 설계 패턴을 활용하라는 지침입니다. 우선적 파라미터가 많아지면 코드의 가독성과 유지보수성이 저하되므로, 이를 피하기 위해 더 나은 구조로 코드를 리팩토링하는 것이 중요합니다. 메서드를 분할하거나 캡슐화, 디자인 패턴을 활용해 코드의 복잡성을 줄이고, 더 명확하고 유지보수하기 쉬운 코드를 작성할 수 있습니다.
“RETURN이나 EXPORT나 CHANGE 중에 하나만 사용하라“는 메서드나 함수의 설계에서 반환값(Return Value), Exporting 파라미터, 그리고 Changing 파라미터를 혼합해서 사용하지 말고, 하나의 방식만 사용하라는 객체지향 설계 원칙입니다. 이는 코드의 일관성과 가독성을 높이고, 예측 가능한 동작을 만들기 위해 중요한 지침입니다.
* 잘못된 패턴
METHOD calculate_values.
EXPORTING
ev_sum TYPE i.
CHANGING
cv_difference TYPE i.
RETURNING
VALUE(rv_product) TYPE i.
ev_sum = iv_num1 + iv_num2.
cv_difference = iv_num1 - iv_num2.
rv_product = iv_num1 * iv_num2.
ENDMETHOD.
세 가지 방식의 차이점
1. RETURNING
- 메서드나 함수에서 단일 값을 반환할 때 사용됩니다. 반환값은 호출하는 쪽에서 바로 할당되어 사용됩니다.
- 보통 메서드의 주요 결과를 반환할 때 사용되며, 단일 값을 반환하는 경우 선호됩니다.
* RETURNING
METHOD calculate_sum.
RETURNING VALUE(rv_sum) TYPE i.
rv_sum = iv_num1 + iv_num2.
ENDMETHOD.
DATA(lv_sum) = calculate_sum( 5, 10 ).
2. EXPORTING
- 메서드나 함수에서 하나 이상의 값을 호출자에게 전달할 때 사용됩니다. 여러 값을 반환할 때 유용하며, RETURNING과 달리 복수의 값을 전달할 수 있습니다.
- 이 방식은 상태를 변경하지 않는 함수형 스타일로 설계할 때는 부적절할 수 있습니다.
* EXPORTING
METHOD calculate.
EXPORTING
ev_sum TYPE i
ev_diff TYPE i.
ev_sum = iv_num1 + iv_num2.
ev_diff = iv_num1 - iv_num2.
ENDMETHOD.
CALL METHOD calculate
EXPORTING
ev_sum = lv_sum
ev_diff = lv_diff.
3. CHANGING
- 메서드나 함수가 호출된 후 호출자에게 인수로 전달된 값을 변경해서 반환할 때 사용됩니다. 보통 객체의 상태를 수정하거나, 복수의 값을 수정하고 싶을 때 사용됩니다.
- 이 방식은 가독성을 해칠 수 있으며, 코드의 예측 가능성을 떨어뜨릴 수 있습니다. 호출한 쪽에서 전달된 값이 변경되는 것을 쉽게 놓칠 수 있기 때문입니다.
* CHANGING
METHOD update_values.
CHANGING
cv_value1 TYPE i
cv_value2 TYPE i.
cv_value1 = cv_value1 + 10.
cv_value2 = cv_value2 - 5.
ENDMETHOD.
DATA(lv_val1) = 20.
DATA(lv_val2) = 30.
CALL METHOD update_values
CHANGING
cv_value1 = lv_val1
cv_value2 = lv_val2.
왜 하나의 방식만 사용해야 하는가?
1. 일관성
- 메서드나 함수가 하나의 방식으로만 값을 반환하면 코드의 일관성이 유지됩니다. 클라이언트 코드가 함수나 메서드의 동작 방식을 예측할 수 있게 하여, 코드 작성 및 사용 시 혼동을 줄입니다.
- 반환값이 있을 때는 RETURNING을, 복수의 값을 전달해야 할 때는 EXPORTING을 사용하는 식으로 일관된 설계를 유지하는 것이 중요합니다.
2. 가독성 향상
- 서로 다른 반환 방식을 혼용하면 코드의 가독성이 떨어집니다. 예를 들어, 반환값(RETURNING)과 변경된 값(CHANGING)을 혼합해서 사용하면, 어떤 값이 반환되었고 어떤 값이 변경되었는지 파악하기 어렵습니다.
- 하나의 방식을 사용하면 메서드나 함수의 동작 방식을 쉽게 이해할 수 있어 코드의 가독성이 높아집니다.
3. 유지보수 용이성
- 하나의 방식을 사용하면, 코드 수정 시 영향을 받는 부분이 명확해집니다. 예를 들어, RETURNING 방식을 사용한 메서드를 수정할 때는 반환값만 신경 쓰면 되지만, 여러 방식을 혼용하면 수정의 영향 범위가 커져 유지보수가 어려워집니다.
4. 명확한 의도 전달
- 메서드가 값을 반환하는 방식이 하나로 통일되면, 메서드의 의도가 더 명확하게 전달됩니다. 메서드를 호출하는 사람은 해당 메서드가 어떤 방식으로 결과를 반환할지 명확히 알 수 있습니다.
“RETURN이나 EXPORT나 CHANGE 중에 하나만 사용하라“는 메서드나 함수가 값을 반환할 때 일관된 방식을 사용하라는 의미입니다. 반환 방식을 혼합해서 사용하면 코드가 복잡해지고, 가독성과 유지보수성이 떨어지기 때문에, 하나의 방식을 선택하여 코드의 일관성과 명확성을 유지하는 것이 중요합니다. 반환할 값의 개수나 목적에 따라 적절한 방식(RETURNING, EXPORTING, CHANGING)을 선택하고, 이를 일관되게 사용하는 것이 좋은 설계의 핵심입니다.
반응형
'ABAP Clean Code' 카테고리의 다른 글
ABAP 클린 코드 - METHOD 메서드 (파라미터 초기화) [10-5] (3) | 2024.08.28 |
---|---|
ABAP 클린 코드 - METHOD 메서드 (파라미터 유형) [10-4] (1) | 2024.08.27 |
ABAP 클린 코드 - METHOD 메서드 (객체 지향 메서드) [10-2] (0) | 2024.08.25 |
ABAP 클린 코드 - METHOD 메서드 (호출) [10-1] (0) | 2024.08.24 |
ABAP 클린 코드 - Class 클래스 (생성자) [9-3] (0) | 2024.08.23 |