반응형
“하나의 메서드는 한 가지만을 수행하라“는 객체지향 설계에서 단일 책임 원칙(Single Responsibility Principle, SRP)을 강조하는 지침입니다. 이 원칙은 메서드가 단 하나의 명확한 책임을 가져야 하며, 하나의 작업만을 수행해야 한다는 것을 의미합니다. 이는 코드의 가독성, 유지보수성, 테스트 용이성을 향상시키기 위해 중요한 원칙입니다.
단일 책임 원칙(SRP)의 중요성
1. 가독성 향상
- 메서드가 하나의 작업만 수행하면, 메서드의 목적이 명확해지고 코드가 더 읽기 쉬워집니다. 이는 코드 작성자뿐만 아니라, 다른 개발자가 코드를 이해하고 수정하는 데에도 큰 도움이 됩니다.
2. 유지보수 용이성
- 책임이 명확한 메서드는 변경이 필요할 때 수정 범위를 좁게 유지할 수 있습니다. 한 가지 일을 하는 메서드는 특정 요구사항에 맞춰 쉽게 변경될 수 있으며, 이로 인해 코드의 다른 부분에 미치는 영향을 최소화할 수 있습니다.
3. 테스트 용이성
- 하나의 작업만 수행하는 메서드는 테스트하기 쉽습니다. 단일 책임을 가진 메서드는 테스트 시 특정 입력에 대해 예상 가능한 출력이 나오므로, 테스트 시나리오를 단순화할 수 있습니다.
4. 재사용성 증가
- 메서드가 명확하게 정의된 단일 작업만 수행하면, 다른 곳에서 재사용하기가 더 쉬워집니다. 재사용 가능한 코드 조각을 만들어 코드 중복을 줄이고, 전체 시스템의 일관성을 유지할 수 있습니다.
메서드는 다음과 같은 경우 한 가지 작업을 수행할 수 있습니다.
- 입력 매개변수가 적은경우
- Boolean 파라미터를 포함하지 않는 경우
- 정확히 하나의 출력 파라미터가 있는 경우
- 메서드가 작은 경우
- 한 단계의 추상화 레벨만을 가지는 경우
- 하나의 예외 처리만을 가지는 경우
- 의미 있는 다른 방법을 추출할 수 없는 경우
- 문장을 섹션으로 의미 있게 그룹화할 수 없는 경우
“HAPPY-PATH 혹은 에러 처리 둘 중 하나에 집중하라“는 메서드나 함수 작성 시, 정상적인 흐름(Happy Path)과 에러 처리(Error Handling)를 명확하게 구분하여 하나의 흐름에만 집중하라는 코딩 지침입니다. 이 지침은 코드의 가독성과 유지보수성을 높이고, 명확한 로직을 구현하기 위해 중요합니다.
용어 설명
HAPPY-PATH란?
- 코드가 정상적으로 동작하는 경로입니다. 모든 조건이 예상대로 맞아떨어지고, 오류 없이 작업이 완료되는 경우를 가리킵니다.
- 이 경로는 코드의 주요 작업이 성공적으로 완료되는 경로이며, 대부분의 비즈니스 로직이 이 안에 포함됩니다.
에러 처리(Error Handling)란?
- 예상하지 못한 상황이나 오류가 발생했을 때, 이를 처리하기 위한 경로입니다.
- 이 경로에서는 예외를 처리하고, 오류 상황에 맞는 대처를 수행합니다.
혼합된 처리의 단점
1. 가독성 저하
- HAPPY-PATH와 에러 처리가 혼합되어 있으면, 코드를 읽는 사람이 정상적인 흐름과 오류 처리를 구분하기 어렵습니다. 이렇게 되면 코드의 의도가 불명확해지고, 이해하는 데 시간이 걸립니다.
2. 유지보수 어려움
- HAPPY-PATH와 에러 처리 로직이 혼재된 코드는 수정 시 영향 범위를 파악하기 어렵고, 오류를 처리하는 로직이 주요 비즈니스 로직에 끼어들어 유지보수가 복잡해집니다.
3. 테스트 복잡성 증가
- 정상적인 흐름과 에러 처리 로직이 한 메서드나 함수에 혼합되어 있으면, 테스트 케이스도 복잡해집니다. 다양한 시나리오에 대해 테스트해야 하므로, 테스트 코드가 많아지고 관리가 어려워집니다.
* HAPPY-PATH
METHOD process_order.
* 유효성 검사 (별도의 메서드로 분리)
validate_order( iv_order ).
* 정상적인 주문 처리 로직
process_payment( iv_order ).
update_order_status( iv_order ).
ENDMETHOD.
METHOD validate_order.
IF NOT is_valid_order( iv_order ).
RAISE EXCEPTION TYPE zcx_invalid_order.
ENDIF.
ENDMETHOD.
* 에러 처리
METHOD handle_payment_error.
TRY.
process_payment( iv_order ).
CATCH zcx_payment_failure INTO lx_error.
handle_error( lx_error ).
ENDTRY.
ENDMETHOD.
METHOD handle_error.
* 에러 처리 로직
ENDMETHOD.
“HAPPY-PATH 혹은 에러 처리 둘 중 하나에 집중하라“는 메서드나 함수에서 정상적인 흐름과 에러 처리를 명확하게 구분하여, 하나의 흐름에만 집중하라는 의미입니다.
“한 단계의 추상화 레벨만을 가져라“는 객체지향 설계와 코드 작성에서 중요한 원칙으로, 하나의 메서드 또는 함수 내에서 일관된 추상화 수준을 유지하라는 의미입니다. 이 원칙은 코드의 가독성, 유지보수성, 이해 용이성을 높이는 데 도움이 됩니다.
추상화 레벨이란?
- 추상화 레벨은 코드가 표현하는 개념의 구체성 또는 추상성의 정도를 의미합니다.
- 높은 추상화 레벨: 코드가 개념적으로 더 높은 수준의 작업을 표현합니다. 예를 들어, “데이터베이스에 연결한다” 또는 “사용자를 인증한다”와 같은 작업이 여기에 해당됩니다.
- 낮은 추상화 레벨: 코드가 매우 구체적이고 세부적인 작업을 표현합니다. 예를 들어, “SQL 쿼리를 실행한다” 또는 “비밀번호 해시 값을 비교한다”와 같은 작업이 여기에 해당됩니다.
원칙의 중요성
- 이 원칙은 하나의 메서드나 함수가 너무 구체적이거나 너무 추상적인 작업을 혼합하지 않고, 일관된 수준에서 작업을 수행하도록 권장합니다. 이를 통해 코드가 읽기 쉽고, 이해하기 쉬우며, 유지보수하기 쉬워집니다.
여러 단계의 추상화 혼합
- 하나의 메서드나 함수가 서로 다른 추상화 수준의 작업을 동시에 수행할 때, 코드가 혼란스러워지고 가독성이 떨어지며, 코드의 목적이 불명확해질 수 있습니다.
* 추상화 레벨 혼합
METHOD process_order.
* 높은 추상화 레벨: 주문을 처리한다
validate_order( iv_order ).
* 낮은 추상화 레벨: SQL을 실행해 주문 상태를 업데이트한다
EXEC SQL.
UPDATE orders
SET status = 'PROCESSED'
WHERE order_id = iv_order-id.
ENDEXEC.
* 높은 추상화 레벨: 결제를 처리한다
process_payment( iv_order ).
* 낮은 추상화 레벨: 로그를 파일에 쓴다
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
IF sy-subrc = 0.
TRANSFER 'Order processed successfully' TO lv_file.
CLOSE DATASET lv_file.
ENDIF.
ENDMETHOD.
추상화 레벨 분리
- 하나의 메서드나 함수는 일관된 추상화 레벨의 작업만 수행하도록 설계해야 합니다. 높은 추상화 레벨의 메서드에서는 높은 레벨의 작업만, 낮은 레벨의 메서드에서는 구체적인 작업만 수행하도록 코드를 분리해야 합니다.
* 추상화 레벨 분리
METHOD process_order.
* 높은 추상화 레벨: 주문 처리 과정
validate_order( iv_order ).
* 상태 업데이트를 위한 별도 메서드 호출
update_order_status( iv_order ).
process_payment( iv_order ).
* 로그 기록을 위한 별도 메서드 호출
log_order_processed( iv_order ).
ENDMETHOD.
METHOD update_order_status.
* 낮은 추상화 레벨: SQL 실행
EXEC SQL.
UPDATE orders
SET status = 'PROCESSED'
WHERE order_id = iv_order-id.
ENDEXEC.
ENDMETHOD.
METHOD log_order_processed.
* 낮은 추상화 레벨: 파일에 로그 기록
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
IF sy-subrc = 0.
TRANSFER 'Order processed successfully' TO lv_file.
CLOSE DATASET lv_file.
ENDIF.
ENDMETHOD.
“한 단계의 추상화 레벨만을 가져라“는 메서드나 함수가 일관된 추상화 수준에서 작업을 수행하도록 설계하라는 의미입니다. 이를 통해 코드가 더 읽기 쉬워지고, 유지보수와 테스트가 용이해집니다. 코드 작성 시 각 메서드가 어떤 추상화 수준에서 작업을 수행해야 하는지 명확히 구분하고, 높은 수준과 낮은 수준의 작업을 혼합하지 않는 것이 중요합니다.
“메서드를 작게 유지하라“는 객체지향 설계에서 중요한 원칙으로, 각 메서드가 작은 크기를 유지하도록 설계하라는 의미입니다. 이는 코드의 가독성, 유지보수성, 테스트 용이성을 높이는 데 중요한 역할을 합니다.
* 잘못된 패턴 긴 메서드
METHOD process_order.
IF is_express_order( iv_order ).
process_express_order( iv_order ).
ELSE.
process_regular_order( iv_order ).
ENDIF.
IF is_international_order( iv_order ).
process_international_shipping( iv_order ).
ELSE.
process_domestic_shipping( iv_order ).
ENDIF.
finalize_order( iv_order ).
ENDMETHOD.
* 올바른 패턴 조건문 분리
METHOD process_order.
IF is_express_order( iv_order ).
process_express_order( iv_order ).
ELSE.
process_regular_order( iv_order ).
ENDIF.
process_shipping( iv_order ).
finalize_order( iv_order ).
ENDMETHOD.
METHOD process_shipping.
IF is_international_order( iv_order ).
process_international_shipping( iv_order ).
ELSE.
process_domestic_shipping( iv_order ).
ENDIF.
ENDMETHOD.
* 잘못된 패턴 반복문 안에 긴 로직
LOOP AT lt_orders INTO lv_order.
* 긴 처리 로직
perform_order_processing( lv_order ).
ENDLOOP.
* 올바른 패턴 반복문 분리
LOOP AT lt_orders INTO lv_order.
process_single_order( lv_order ).
ENDLOOP.
METHOD process_single_order.
* 처리 로직을 이 메서드에서 처리
perform_order_processing( lv_order ).
ENDMETHOD.
“메서드를 작게 유지하라“는 각 메서드가 작고 명확한 책임을 가지도록 설계하라는 의미입니다. 이를 통해 코드의 가독성, 유지보수성, 재사용성이 향상되고, 테스트와 디버깅이 더 쉬워집니다. 메서드를 작성할 때는 항상 메서드의 크기와 책임을 신중하게 고려하여, 코드가 단순하고 이해하기 쉬운 상태를 유지하는 것이 중요합니다.
반응형
'ABAP Clean Code' 카테고리의 다른 글
| ABAP 클린 코드 - METHOD 메서드 (파라미터 초기화) [10-5] (3) | 2024.08.28 |
|---|---|
| ABAP 클린 코드 - METHOD 메서드 (파라미터 유형) [10-4] (1) | 2024.08.27 |
| ABAP 클린 코드 - METHOD 메서드 (파라미터 개수) [10-3] (0) | 2024.08.26 |
| ABAP 클린 코드 - METHOD 메서드 (객체 지향 메서드) [10-2] (0) | 2024.08.25 |
| ABAP 클린 코드 - METHOD 메서드 (호출) [10-1] (0) | 2024.08.24 |