어떤 함수에 매개변수가 많을수록 함수의 역할을 이해하기 힘들다
함수는 한가지 일을 하는지, 불필요한 매개변수는 없는지, 레코드로 뭉칠 수 있는지
discountedPrice 메서드의 매개변수 discountLevel 을 질의 함수로 변경하여
매개변수에서 제거하고 함수를 직접 호출하도록 변경
class Refactoring {
private int quantity;
private double itemPrice;
public Order(int quantity, double itemPrice) {
this.quantity = quantity;
this.itemPrice = itemPrice;
}
public double finalPrice() {
double basePrice = this.quantity * this.itemPrice;
int discountLevel = this.quantity > 100 ? 2 : 1;
return this.discountedPrice(basePrice, discountLevel);
}
private double discountedPrice(double basePrice, int discountLevel) {
return discountLevel == 2 ? basePrice * 0.9 : basePrice * 0.95;
}
}
class Refactoring {
private int quantity;
private double itemPrice;
public Order(int quantity, double itemPrice) {
this.quantity = quantity;
this.itemPrice = itemPrice;
}
public double finalPrice() {
double basePrice = this.quantity * this.itemPrice;
return this.discountedPrice(basePrice);
}
private int discountLevel() {
return this.quantity > 100 ? 2 : 1;
}
private double discountedPrice(double basePrice) {
return discountLevel() == 2 ? basePrice * 0.9 : basePrice * 0.95;
}
}
긴 함수 냄새에서 사용한 조건문 분해하기로 true/false 에 대한 작업을 분해하여 메서드를 생성
테스트 코드에서 매개변수를 전달하여 사용하던 방식에서 플래그를 지우고 분해한 메서드를 직접 호출
class Refactoring {
public LocalDate deliveryDate(Order order, boolean isRush) {
if (isRush) {
int deliveryTime = switch (order.getDeliveryState()) {
case "WA", "CA", "OR" -> 1;
case "TX", "NY", "FL" -> 2;
default -> 3;
};
return order.getPlacedOn().plusDays(deliveryTime);
} else {
int deliveryTime = switch (order.getDeliveryState()) {
case "WA", "CA" -> 2;
case "OR", "TX", "NY" -> 3;
default -> 4;
};
return order.getPlacedOn().plusDays(deliveryTime);
}
}
}
class Refactoring {
public LocalDate regularDeliveryDate(Order order) {
int deliveryTime = switch (order.getDeliveryState()) {
case "WA", "CA" -> 2;
case "OR", "TX", "NY" -> 3;
default -> 4;
};
return order.getPlacedOn().plusDays(deliveryTime);
}
public LocalDate rushDeliveryDate(Order order) {
int deliveryTime = switch (order.getDeliveryState()) {
case "WA", "CA", "OR" -> 1;
case "TX", "NY", "FL" -> 2;
default -> 3;
};
return order.getPlacedOn().plusDays(deliveryTime);
}
}
before 를 확인해보면 메서드에 동일하게 자주 사용되는 매개변수가 있다
새로운 클래스를 생성하여 해당 메소드를 모아서 필드로 처리하여 매개변수를 줄이고
after 클래스는 새로운 클래스의 메서드를 호출 한다
class Refactoring {
private void print() throws IOException, InterruptedException { }
private String getMarkdownForParticipant(String username, Map<Integer, Boolean> homework) { }
private String checkMark(Map<Integer, Boolean> homework, int totalNumberOfParticipants) { }
private double getRate(Map<Integer, Boolean> homework) { }
private String header(int totalNumberOfParticipants) { }
}
class Refactoring {
private void print() throws IOException, InterruptedException {
new newAfter(매개변수).print();
}
private double getRate(Map<Integer, Boolean> homework) { }
private String getMarkdownForParticipant(String username, Map<Integer, Boolean> homework) { }
}
class NewRefactoring {
private int totalNumberOfParticipants;
newAfter(int totalNumberOfParticipants) {
this.totalNumberOfParticipants = totalNumberOfParticipants;
}
private void print() throws IOException, InterruptedException { }
private String checkMark(Map<Integer, Boolean> homework) { }
private String header() { }
}