리팩토링 - 냄새 4. 긴 매개변수 목록
들어가기
해당 포스팅은 인프런 백기선님의 '리팩토링'을 학습 후 정리한 내용입니다.
냄새 4. 긴 매개변수 목록
Long Parameter List
- 어떤 함수에 매개변수가 많을수록 함수의 역할을 이해하기 어려워진다.
- 과연 그 함수는 한가지 일을 하고 있는게 맞는가?
- 불필요한 매개변수는 없는가?
- 하나의 레코드로 뭉칠 수 있는 매개변수 목록은 없는가?
- 어떤 매개변수를 다른 매개변수를 통해 알아낼 수 있다면, “매개변수를 질의 함수로 바꾸기 (Replace Parameter with Query)”를 사용할 수 있다.
- 기존 자료구조에서 세부적인 데이터를 가져와서 여러 매개변수로 넘기는 대신, “객체 통째로 넘기기 (Preserve Whole Object)”를 사용할 수 있다.
- 일부 매개변수들이 대부분 같이 넘겨진다면, “매개변수 객체 만들기 (Introduce Parameter Object)”를 적용할 수 있다.
- 매개변수가 플래그로 사용된다면, “플래그 인수 제거하기 (Remove Flag Argument)”를 사용할 수 있다.
- 여러 함수가 일부 매개변수를 공통적으로 사용한다면 “여러 함수를 클래스로 묶기 (Combine Functions into Class)”를 통해 매개변수를 해당 클
래스의 필드로 만들고 매서드에 전달해야 할 매개변수 목록을 줄일 수 있다.
매개변수를 질의 함수로 바꾸기
Replace Parameter with Query
- 함수의 매개변수 목록은 함수의 다양성을 대변하며, 짧을수록 이해하기 좋다.
- 어떤 한 매개변수를 다른 매개변수를 통해 알아낼 수 있다면 “중복 매개변수”라 생각할 수 있다.
- 매개변수에 값을 전달하는 것은 “함수를 호출하는 쪽”의 책임이다. 가능하면 함수를 호출하는 쪽의 책임을 줄이고 함수 내부에서 책임지도록 노력한다.
- “임시 변수를 질의 함수로 바꾸기”와 “함수 선언 변경하기”를 통해 이 리팩토링을 적용한다.
예제 코드
public class Order {
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.90 : basePrice * 0.95;
}
}
냄새
discountedPrice() 함수의 파라미터 discountLevel 은 다른 파라미터를 통해 값을 유츄할 수 있다.
해결
함수로 추출하자!
리팩토링 후
package me.whiteship.refactoring._04_long_parameter_list.practice._01;
public class Order {
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 getDiscountLevel() {
return this.quantity > 100 ? 2 : 1;
}
private double discountedPrice(double basePrice) {
return getDiscountLevel() == 2 ? basePrice * 0.9 : basePrice * 0.95;
}
}
설명
- getDiscountLevel() 이라는 함수로 추출하여 discountedPrice() 함수 내부에서 호출하여 사용한다.
- 따라서 discountedPrice() 함수의 매개변수를 줄일 수 있다.
플래그 인수 제거하기
Remove Flag Argument
- 플래그는 보통 함수에 매개변수로 전달해서, 함수 내부의 로직을 분기하는데 사용한다.
- 플래그를 사용한 함수는 차이를 파악하기 어렵다.
- bookConcert(customer, false), bookConcert(customer, true)
- bookConcert(customer), premiumBookConcert(customer)
- 조건문 분해하기 (Decompose Condition)를 활용할 수 있다.
예제 코드
public class Shipment {
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);
}
}
}
냄새
deliveryDate() 함수 내부에서 급 배송을 의미하는 isRush 에 따라 배송 날짜를 계산해주는 함수이다. 하지만 함수 매개변수에 플래그가 있으면 함수가 많은 일을 하고있는 것이다.
해결
함수를 분리하자!
리팩토링 후
public class Shipment {
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);
}
}
설명
조건에 맞는 함수로 분리하여 필요한 함수를 호출해 사용하였다.
여러 함수를 클래스로 묶기
Combine Functions into Class
- 비슷한 매개변수 목록을 여러 함수에서 사용하고 있다면 해당 메소드를 모아서 클래스를 만들 수 있다.
- 클래스 내부로 메소드를 옮기고, 데이터를 필드로 만들면 메소드에 전달해야 하는 매개변수 목록도 줄일 수 있다.
예제 코드
예제 코드는 이전 포스팅을 참조하자. 보러 가기
냄새
각 함수에서 totalNumberOfEvents, participants 와 같은 비슷한 매개변수를 여러 함수에서 사용하고 있다.
해결
필요한 데이터와 메서드를 옮겨 클래스로 만들어 해결할 수 있다.
리팩토링 후
리팩토링 후 코드는 이전 포스팅을 참조하자. 보러가기
설명
- 관련 있는 매개변수들이 여기저기 흩어져 있어 관련있는 매개변수를 클래스로 만들었다.
- 가급적이면 관련있는 데이터를 한곳으로 옮기고 메서드를 옮기다 보면 메서드에 전달되는 매개변수를 줄일 수 있다.
Author And Source
이 문제에 관하여(리팩토링 - 냄새 4. 긴 매개변수 목록), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@coconenne/리팩토링-냄새-4.-긴-매개변수-목록
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
해당 포스팅은 인프런 백기선님의 '리팩토링'을 학습 후 정리한 내용입니다.
Long Parameter List
- 어떤 함수에 매개변수가 많을수록 함수의 역할을 이해하기 어려워진다.
- 과연 그 함수는 한가지 일을 하고 있는게 맞는가?
- 불필요한 매개변수는 없는가?
- 하나의 레코드로 뭉칠 수 있는 매개변수 목록은 없는가?
- 어떤 매개변수를 다른 매개변수를 통해 알아낼 수 있다면, “매개변수를 질의 함수로 바꾸기 (Replace Parameter with Query)”를 사용할 수 있다.
- 기존 자료구조에서 세부적인 데이터를 가져와서 여러 매개변수로 넘기는 대신, “객체 통째로 넘기기 (Preserve Whole Object)”를 사용할 수 있다.
- 일부 매개변수들이 대부분 같이 넘겨진다면, “매개변수 객체 만들기 (Introduce Parameter Object)”를 적용할 수 있다.
- 매개변수가 플래그로 사용된다면, “플래그 인수 제거하기 (Remove Flag Argument)”를 사용할 수 있다.
- 여러 함수가 일부 매개변수를 공통적으로 사용한다면 “여러 함수를 클래스로 묶기 (Combine Functions into Class)”를 통해 매개변수를 해당 클
래스의 필드로 만들고 매서드에 전달해야 할 매개변수 목록을 줄일 수 있다.
매개변수를 질의 함수로 바꾸기
Replace Parameter with Query
- 함수의 매개변수 목록은 함수의 다양성을 대변하며, 짧을수록 이해하기 좋다.
- 어떤 한 매개변수를 다른 매개변수를 통해 알아낼 수 있다면 “중복 매개변수”라 생각할 수 있다.
- 매개변수에 값을 전달하는 것은 “함수를 호출하는 쪽”의 책임이다. 가능하면 함수를 호출하는 쪽의 책임을 줄이고 함수 내부에서 책임지도록 노력한다.
- “임시 변수를 질의 함수로 바꾸기”와 “함수 선언 변경하기”를 통해 이 리팩토링을 적용한다.
예제 코드
public class Order {
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.90 : basePrice * 0.95;
}
}
냄새
discountedPrice() 함수의 파라미터 discountLevel 은 다른 파라미터를 통해 값을 유츄할 수 있다.
해결
함수로 추출하자!
리팩토링 후
package me.whiteship.refactoring._04_long_parameter_list.practice._01;
public class Order {
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 getDiscountLevel() {
return this.quantity > 100 ? 2 : 1;
}
private double discountedPrice(double basePrice) {
return getDiscountLevel() == 2 ? basePrice * 0.9 : basePrice * 0.95;
}
}
설명
- getDiscountLevel() 이라는 함수로 추출하여 discountedPrice() 함수 내부에서 호출하여 사용한다.
- 따라서 discountedPrice() 함수의 매개변수를 줄일 수 있다.
플래그 인수 제거하기
Remove Flag Argument
- 플래그는 보통 함수에 매개변수로 전달해서, 함수 내부의 로직을 분기하는데 사용한다.
- 플래그를 사용한 함수는 차이를 파악하기 어렵다.
- bookConcert(customer, false), bookConcert(customer, true)
- bookConcert(customer), premiumBookConcert(customer)
- 조건문 분해하기 (Decompose Condition)를 활용할 수 있다.
예제 코드
public class Shipment {
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);
}
}
}
냄새
deliveryDate() 함수 내부에서 급 배송을 의미하는 isRush 에 따라 배송 날짜를 계산해주는 함수이다. 하지만 함수 매개변수에 플래그가 있으면 함수가 많은 일을 하고있는 것이다.
해결
함수를 분리하자!
리팩토링 후
public class Shipment {
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);
}
}
설명
조건에 맞는 함수로 분리하여 필요한 함수를 호출해 사용하였다.
여러 함수를 클래스로 묶기
Combine Functions into Class
- 비슷한 매개변수 목록을 여러 함수에서 사용하고 있다면 해당 메소드를 모아서 클래스를 만들 수 있다.
- 클래스 내부로 메소드를 옮기고, 데이터를 필드로 만들면 메소드에 전달해야 하는 매개변수 목록도 줄일 수 있다.
예제 코드
예제 코드는 이전 포스팅을 참조하자. 보러 가기
냄새
각 함수에서 totalNumberOfEvents, participants 와 같은 비슷한 매개변수를 여러 함수에서 사용하고 있다.
해결
필요한 데이터와 메서드를 옮겨 클래스로 만들어 해결할 수 있다.
리팩토링 후
리팩토링 후 코드는 이전 포스팅을 참조하자. 보러가기
설명
- 관련 있는 매개변수들이 여기저기 흩어져 있어 관련있는 매개변수를 클래스로 만들었다.
- 가급적이면 관련있는 데이터를 한곳으로 옮기고 메서드를 옮기다 보면 메서드에 전달되는 매개변수를 줄일 수 있다.
Author And Source
이 문제에 관하여(리팩토링 - 냄새 4. 긴 매개변수 목록), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@coconenne/리팩토링-냄새-4.-긴-매개변수-목록
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public class Order {
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.90 : basePrice * 0.95;
}
}
discountedPrice() 함수의 파라미터 discountLevel 은 다른 파라미터를 통해 값을 유츄할 수 있다.
함수로 추출하자!
package me.whiteship.refactoring._04_long_parameter_list.practice._01;
public class Order {
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 getDiscountLevel() {
return this.quantity > 100 ? 2 : 1;
}
private double discountedPrice(double basePrice) {
return getDiscountLevel() == 2 ? basePrice * 0.9 : basePrice * 0.95;
}
}
- getDiscountLevel() 이라는 함수로 추출하여 discountedPrice() 함수 내부에서 호출하여 사용한다.
- 따라서 discountedPrice() 함수의 매개변수를 줄일 수 있다.
Remove Flag Argument
- 플래그는 보통 함수에 매개변수로 전달해서, 함수 내부의 로직을 분기하는데 사용한다.
- 플래그를 사용한 함수는 차이를 파악하기 어렵다.
- bookConcert(customer, false), bookConcert(customer, true)
- bookConcert(customer), premiumBookConcert(customer)
- 조건문 분해하기 (Decompose Condition)를 활용할 수 있다.
예제 코드
public class Shipment {
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);
}
}
}
냄새
deliveryDate() 함수 내부에서 급 배송을 의미하는 isRush 에 따라 배송 날짜를 계산해주는 함수이다. 하지만 함수 매개변수에 플래그가 있으면 함수가 많은 일을 하고있는 것이다.
해결
함수를 분리하자!
리팩토링 후
public class Shipment {
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);
}
}
설명
조건에 맞는 함수로 분리하여 필요한 함수를 호출해 사용하였다.
여러 함수를 클래스로 묶기
Combine Functions into Class
- 비슷한 매개변수 목록을 여러 함수에서 사용하고 있다면 해당 메소드를 모아서 클래스를 만들 수 있다.
- 클래스 내부로 메소드를 옮기고, 데이터를 필드로 만들면 메소드에 전달해야 하는 매개변수 목록도 줄일 수 있다.
예제 코드
예제 코드는 이전 포스팅을 참조하자. 보러 가기
냄새
각 함수에서 totalNumberOfEvents, participants 와 같은 비슷한 매개변수를 여러 함수에서 사용하고 있다.
해결
필요한 데이터와 메서드를 옮겨 클래스로 만들어 해결할 수 있다.
리팩토링 후
리팩토링 후 코드는 이전 포스팅을 참조하자. 보러가기
설명
- 관련 있는 매개변수들이 여기저기 흩어져 있어 관련있는 매개변수를 클래스로 만들었다.
- 가급적이면 관련있는 데이터를 한곳으로 옮기고 메서드를 옮기다 보면 메서드에 전달되는 매개변수를 줄일 수 있다.
Author And Source
이 문제에 관하여(리팩토링 - 냄새 4. 긴 매개변수 목록), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@coconenne/리팩토링-냄새-4.-긴-매개변수-목록
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
예제 코드는 이전 포스팅을 참조하자. 보러 가기
각 함수에서 totalNumberOfEvents, participants 와 같은 비슷한 매개변수를 여러 함수에서 사용하고 있다.
필요한 데이터와 메서드를 옮겨 클래스로 만들어 해결할 수 있다.
리팩토링 후 코드는 이전 포스팅을 참조하자. 보러가기
Author And Source
이 문제에 관하여(리팩토링 - 냄새 4. 긴 매개변수 목록), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@coconenne/리팩토링-냄새-4.-긴-매개변수-목록저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)