| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- JPA
- Web
- 스프링 부트
- Spring
- MSA
- DI
- Spring Data JPA
- @ComponentScan
- JdbcTemplate
- CORS
- docker compose
- DLQ
- AWS
- redis
- dockerhub
- 지연 로딩
- 쿠버네티스
- Routing Key
- Dead Letter Queue
- 컨테이너
- JPQL
- JWT
- docker
- kafka
- 페이징
- securitycontextholderfilter
- mybatis
- 서블릿 컨테이너
- @Transactional
- Spring Container
- Today
- Total
look-forest
Refactoring 본문
Refactoring 책에 나오는 기법 중, 평소 잘 사용하지 않던 refactoring 기법만 정리
캡슐화
Encapsulate Collection 패턴
컬렉션을 일급클래스로 감싸서 필요한 기능만 제공해서 외부에서 함부로 조작하지 못한다.

장점
1. 외부에서 조작 못하게 필요한 기능만 오픈할 수 있다.
- add, set, remove, sort 등
2. 도메인 규칙을 모을 수 있다.
- course에 대한 규칙이 추가될 경우 (ex. 수강과목은 7개를 넘지않는다)
3. 메서드 이름으로 의도를 명확히 드러낼 수 있다.
4. 변경에는 닫혀있고, 확장에는 열려있다. (OCP)
List를 Set이나 Map으로 바꿔도, 사용하는 클라이언트 코드는 변경할 필요가 없게된다.
조건부 로직 간소화
Decompose Conditional: 조건문을 보기 좋게 함수로 분리

Replace Conditional with Polymorphism: 조건부 로직을 다형성으로 대체

1. 조건문을 제거하여 클래스별 책임 분리(각 객체가 자기 행동을 알고 담당하게 한)
기존에는 fly() 행동이 분산되었다.
"bird가 날다"라는 행동은 Bird 클래스가 알아야 할 책임인데, 모든 행동이 조건문 안에 모여버렸다.
리팩토링 후에는 행동이 자신의 클래스 안으로 모여 응집도↑
2. 기존 로직을 안건드리고 객체만 추가하면 된다.
구현체가 많지 않다면 아래와 같이 enum을 활용할 수도 있다.

새 타입 추가하려면 기존 switch 문을 항상 수정해야 해서 OCP를 위반했다.
오른쪽과 같이 변경하면 Enum만 추가해주면 된다!
Introduce Assertion: 가정문을 추가하여 코드의 가독성 향상
메소드 이름 자체가 의도를 명확히 드러낸다.

에러 응답을 커스텀하고 싶으면 위와 같은 assert 객체를 만들면 된다.
상속
Replace Subclass with Delegate, Replace Superclass with Delegate: Strategy 패턴
전략 패턴을 활용하여 행동을 알고리즘 객체에 위임한다.

기존 한계
기존에는 행동을 바꾸려면 항상 상속이 필요하고,
공통 기능이 있더라도 조합이 불가하므로 서브 클래스가 너무 많아질 수 있다.
리팩토링 핵심
- drive() 동작 → DrivingAlgorithm로 위임
- repair() 동작 → RepairAlgorithm로 위임
- Bus, Taxi는 “어떤 알고리즘을 쓸지 선택만 하는 래퍼” 역할에 가까워짐
장점
1. 상속보다 조합(Composition) → 유연성 폭증
상속 구조를 바꾸지 않고도 행동만 바꿔 끼우는 게 가능해짐.
결과적으로 도메인 클래스 수가 덜 늘어나고, 설계가 더 납작해진다.
DrivingAlgorithm normalDriving = () -> "Bus is driving";
DrivingAlgorithm sportDriving = () -> "Taxi is driving fast";
RepairAlgorithm internalRepair = () -> { /* 사내 정비 */ };
RepairAlgorithm externalRepair = () -> { /* 외주 정비 */ };
Car bus = new Bus(normalDriving, internalRepair);
Car fastTaxi = new Taxi(sportDriving, externalRepair);
2. 전략 패턴(Strategy Pattern) 구조 → 행동 교체/재사용 쉬움
같은 알고리즘을 여러 차종에 재사용 가능 (예: SelfDrivingAlgorithm → Bus, Taxi 모두 사용)
런타임에 행동 변경도 가능
전략 패턴(Strategy Pattern)
특정 행동(알고리즘)을 인터페이스로 추상화하고,
여러 구현(strategy)을 상황에 따라 선택적으로 사용하도록 만드는 패턴.
참고 자료 & 이미지 출처
Refactoring (마틴 파울러)
https://github.com/rolroralra/hello-refactoring