300x250
✍️ 악취 10 : 데이터 뭉치 여러 클래스에 동일한 혹은 유사한 필드가 반복적으로 등장하거나, 메서드에 전달하는 매개변수 목록이 유사한 경우 이렇게 뭉쳐 다니는 데이터는 한곳으로 모아두는 것이 좋다. 여기 데이터 뭉치를 해결하기 위한 두 가지 리팩토링 기법이 있다. 1. "클래스 추출하기" 동일한, 유사한 필드를 하나의 클래스로 2. "매개변수 객체 만들기" 동일한, 유사한 매개변수를 하나의 클래스로 🍊 클래스 추출하기 아래 두 클래스 모두 학년과 반 번호라는 공통된 필드를 사용 중이라면, 두 필드를 하나의 클래스로 추출할 수 있다. @AllArgsConstructor @Getter public class Student { private String name; private int grade; priv..
✍️ 악취 9 : 기능 편애 어떤 메서드가 자신이 속한 클래스보다 다른 클래스를 더 많이 참조한다면 이를 '기능 편애'라고 한다. 기능 편애 현상이 나타나는 가장 큰 이유는 올바르지 못한 데이터 구조에서 기인한다. 한 클래스가 너무 많은 기능을 담당하거나, 필드와 메서드가 서로 다른 클래스에 분리된 경우가 그 대표적인 예시이다. 여기 기능 편애를 해결하기 위한 리팩토링 기법이 있다. 1. "함수 옮기기" 올바른 책임을 위해 🍊 함수 옮기기 전기 사용량과 가스 사용량을 표현하는 두 클래스가 있고 @AllArgsConstructor @Getter public class ElectricityUsage { private double amount; private double pricePerUnit; } @AllA..
✍️ 악취 8 : 산탄총 수술 코드에 변경이 생겼을 때 관련 있는 여러 모듈 혹은 클래스 혹은 메서드를 수정해야 한다면 코드의 응집도는 낮고 결합도는 높은 상황일 가능성이 높다. 따라서 이런 현상이 발견된다면 관련 있는 데이터를 한 곳으로 옮겨서 응집도를 높이고 책임을 명확히 분리해서 결합도를 낮출 필요가 있다. 여기 낮은 응집도와 높은 결합도의 산탄총 악취를 해결하기 위한 세 가지 리팩토링 기법이 있다. 1. "함수 옮기기, 필드 옮기기" 필요한 변경 내역을 하나의 클래스로 모으기 2. "단계 쪼개기" 공통으로 사용되는 메서드의 결과물을 하나로 묶기 3. "함수 인라인, 클래스 인라인" 흩어진 로직을 한 곳으로 🍊 필드 옮기기 좋은 데이터 구조를 가지고 있다면, 해당 데이터를 기반한 행위를 메서드로 작..
✍️ 악취 7 : 뒤엉킨 변경 좋은 코드는 응집도는 높고 결합도는 낮아야 한다. 응집도는 관련 있는 데이터 혹은 기능이 한 곳에 잘 밀집되어 있는가를 말하고, 결합도는 상호간 의존하는 정도를 의미한다. 가령 서로 연관이 없는 A, B 모듈이 수정됐을 때, 양쪽에서 모두 C 모듈의 수정을 요구한다면 응집도가 낮고 결합도는 높다고 할 수 있다. 이처럼 한 모듈이 여러 가지 이유로 수정되어야 한다면 역할이 제대로 나눠지지 않았을 수 있다. 서로 다른 문제는 서로 다른 모듈에서 해결해야 한다. 뒤엉킨 변경을 해결하기 위한 세 가지 리팩토링 기법이 있다. 1. "단계 쪼개기" 서로 다른 문맥의 코드를 분리 2. "함수 옮기기" 적절한 모듈로 함수를 옮기기 3. "클래스 추출하기" 모듈이 클래스 단위라면 🍊 단계 ..
✍️ 서론 논리적으로 연관된 상수를 정의할 때 사용하는 자료형 enum. enum은 심볼릭하게 그 자체로도 의미를 가지지만 필요에 따라 필드를 추가하거나 메서드를 추상화해서 enum이 책임질 수 있는 코드를 구현할 수 있다. 🍊 simple enum enum의 가장 단순한 사용법으로 보통 상태 값이나, 분기를 위한 플래그로 사용된다. public enum Operator { PLUS, MINUS, MULTIPLY, DIVIDE; } public class Calculator { public double calculate(double a, double b, Operator op) { if (op == Operator.PLUS) { return a + b; } else if (op == Operator.MI..
✍️ 서론 이벤트의 콜백 메서드를 인터페이스의 추상 메서드로 정의하고, 이벤트에 관심 있는 클래스는 콜백 인터페이스를 구현함으로써 간단한 Listener를 만들 수 있다. 예제 코드로 이해해 보자. 여기 Member의 가입 로직이 포함된 MemberService가 있고, @Service public class MemberServiceImpl implements MemberService { @Autowired private MemberDao memberDao; @Override public void join(int memberId, String name) { Member exist = memberDao.get(memberId); if (exist != null) throw new RuntimeExcepti..