어떤 한 변경 사항이 생겼을 때 여러 모듈을 수정해야 하는 경우
변경 사항이 여러곳에 흩어진다면 찾아서 고치기 어렵고 중요한 변경 사항을 놓칠 수 있다
Customer 레코드에 있는 discountRate 필드는 해당 레코드의 역할에 있기엔 타당하지 않다
역할에 맞도록 CustomerContract 레코드로 옮겨야 한다
class Customer {
private String name;
private double discountRate;
private CustomerContract contract;
public Customer(String name, double discountRate) {
this.name = name;
this.discountRate = discountRate;
this.contract = new CustomerContract(dateToday());
}
public double getDiscountRate() {
return discountRate;
}
public void becomePreferred() {
this.discountRate += 0.03;
}
public double applyDiscount(double amount) {
BigDecimal value = BigDecimal.valueOf(amount);
return value.subtract(value.multiply(BigDecimal.valueOf(this.discountRate))).doubleValue();
}
private LocalDate dateToday() {
return LocalDate.now();
}
}
class CustomerContract {
private LocalDate startDate;
public CustomerContract(LocalDate startDate) {
this.startDate = startDate;
}
}
class Customer {
private String name;
private CustomerContract contract;
public Customer(String name, double discountRate) {
this.name = name;
this.contract = new CustomerContract(dateToday(), discountRate);
}
public double getDiscountRate() {
return this.contract.getDiscountRate();
}
public void becomePreferred() {
this.contract.setDiscountRate(this.getDiscountRate() + 0.03);
}
public double applyDiscount(double amount) {
BigDecimal value = BigDecimal.valueOf(amount);
return value.subtract(value.multiply(BigDecimal.valueOf(this.getDiscountRate()))).doubleValue();
}
private LocalDate dateToday() {
return LocalDate.now();
}
}
class CustomerContract {
private LocalDate startDate;
private double discountRate;
// ...생성자, getter, setter
}
moreThanFiveLateDeliveries 메서드는 함수 추출하기에 의해 분할되어 있는 것 보다
함수 인라인 리팩토링에 더 적합한 케이스이므로 메서드 하나로 그 의미를 쉽게 이해할 수 있다
class Refactoring {
public int rating(Driver driver) {
return moreThanFiveLateDeliveries(driver) ? 2 : 1;
}
private boolean moreThanFiveLateDeliveries(Driver driver) {
return driver.getNumberOfLateDeliveries() > 5;
}
}
class Refactoring {
public int rating(Driver driver) {
return driver.getNumberOfLateDeliveries() > 5 ? 2 : 1;
}
}
TrackingInformation 의 필드들의 의미가 Shipment 클래스에 있을 때 더 타당한 케이스
클래스 인라인 리팩토링을 적용해 모든 필드 메서드들을 옮기고 불필요한 클래스는 삭제
class Shipment {
private TrackingInformation trackingInformation;
public Shipment(TrackingInformation trackingInformation) {
this.trackingInformation = trackingInformation;
}
public TrackingInformation getTrackingInformation() {
return trackingInformation;
}
public void setTrackingInformation(TrackingInformation trackingInformation) {
this.trackingInformation = trackingInformation;
}
public String getTrackingInfo() {
return this.trackingInformation.display();
}
}
class TrackingInformation {
private String shippingCompany;
private String trackingNumber;
public TrackingInformation(String shippingCompany, String trackingNumber) {
this.shippingCompany = shippingCompany;
this.trackingNumber = trackingNumber;
}
public String display() {
return this.shippingCompany + ": " + this.trackingNumber;
}
public String getShippingCompany() {
return shippingCompany;
}
public void setShippingCompany(String shippingCompany) {
this.shippingCompany = shippingCompany;
}
public String getTrackingNumber() {
return trackingNumber;
}
public void setTrackingNumber(String trackingNumber) {
this.trackingNumber = trackingNumber;
}
}
class Shipment {
private String shippingCompany;
private String trackingNumber;
public Shipment(String shippingCompany, String trackingNumber) {
this.shippingCompany = shippingCompany;
this.trackingNumber = trackingNumber;
}
public String getTrackingInfo() {
return this.shippingCompany + ": " + this.trackingNumber;
}
public String getShippingCompany() {
return shippingCompany;
}
public void setShippingCompany(String shippingCompany) {
this.shippingCompany = shippingCompany;
}
public String getTrackingNumber() {
return trackingNumber;
}
public void setTrackingNumber(String trackingNumber) {
this.trackingNumber = trackingNumber;
}
}