단일 책임 원칙
- Single Responsibility Principle
- 하나의 클래스나 모듈은 하나의 책임만을 가져야 한다.
- 책임을 나누는 중요한 기준은 변경으로 '해당 코드를 변경하려는 이유는 무엇인가?' 에 대한 질문에 단 하나의 이유만 존재해야함
책임을 분리하지 않을 경우의 문제점
@Service
@RequiredArgsConstructor
public class PaymentService {
private final PaymentRepository paymentRepository;
public void addHistory (long amount, AddProduct addProduct) {
// 할인 정책 적용
if (amount >= 100000) {
amount *= 0.8;
}
else if (amount >= 50000) {
amount *= 0.9;
}
// 추가 상품 구매 여부
if (AddProduct.TUMBLER.equals(addProduct)) {
amount += 30000L;
} else if (AddProduct.BAG.equals(addProduct)) {
amount += 10000L;
}
// 결제 내역 저장
paymentRepository.save(amount);
}
}
public enum AddProduct {
BAG, TUMBLER
}
- 위에 코드에서 addHistory 는 내부에 할인 정책에 따른 금액 계산과 추가 상품 구매시 추가 금액 계산까지 모두 처리하고 있다. 이는 요구사항이 추가 및 변경되었을 때 다음과 같은 문제를 발생시킬 수 있다.
- 요구사항이 추가되었을 경우 해당 코드처럼 작성한다면 하나의 메서드에 작성하는 코드가 길어짐
- 여러 작업이 작성되어있는 코드 중 일부를 변경해야 할 때 코드가 길어질 경우 변경 부분을 찾기 어려워질 수 있고 개발자의 실수로 잘못된 부분을 변경할 수 있음
책임을 분리하라!
@Service
@RequiredArgsConstructor
public class PaymentService {
private final PaymentRepository paymentRepository;
private final DiscountPolicy discountPolicy;
public void addHistory (long amount, AddProduct addProduct) {
// 할인 정책 적용
amount = discountPolicy.apply(amount);
// 추가 상품 구매 여부
if (addProduct != null) {
amount += addProduct.getValue();
}
// 결제 내역 저장
paymentRepository.save(amount);
}
}
public enum AddProduct {
BAG(30000), TUMBLER(10000);
private long value;
AddProduct(long value) {
this.value = value;
}
public long getValue() {
return value;
}
}
@Component
public class DiscountPolicy {
public long apply(long amount) {
if (amount >= 100000) {
return (long) (amount * 0.9);
} else if (amount >= 50000) {
return (long) (amount * 0.8);
}
return amount;
}
}
- 이전 코드를 수정하여 할인 정책 계산과 추가 상품 구매 금액 부분을 외부로 분리하여 위임하도록 변경하였다. 이를 통해 다음과 같은 장점을 얻을 수 있다.
- 변경사항이 발생할 경우 해당 변경사항을 책임지는 모듈만 변경하면 됨. 즉, 변경 포인트가 명확해짐
- 변경사항 외의 다른 부분을 건드리는 실수를 방지할 수 있다.
- 분리한 모듈을 다른 부분에서 재활용할 수 있다.
다음글
'OOP' 카테고리의 다른 글
객체지향 프로그래밍의 5가지 원칙(5) - 의존관계 역전 법칙 (0) | 2022.08.01 |
---|---|
객체지향 프로그래밍의 5가지 원칙(4) - 인터페이스 분리 원칙 (0) | 2022.08.01 |
객체지향 프로그래밍의 5가지 원칙(3) - 리스코프 치환 원칙 (0) | 2022.08.01 |
객체지향 프로그래밍의 5가지 원칙(2) - 개방-패쇄 원칙 (0) | 2022.08.01 |