본문 바로가기

Programming/리팩토링

[리팩토링 기술-6] 단계 쪼개기 / 클래스 추출하기

🙌  단계 쪼개기 (Split Phase)

 

- 서로 다른 일을 하는 코드를 각기 다른 모듈로 분리한다.

 : 그래야 어떤 것을 변경해야 할 때, 그것과 관련있는 것만 신경쓸 수 있다.

 

- 여러 일을 하는 함수의 처리과정을 각기 다른 단계로 구분할 수 있다.

  (예) 전처리 -> 주요작업 -> 후처리

  (예) 컴파일러 : 텍스트 읽어오기 -> 실행 가능한 형태로 변경

 

- 서로 다른 데이터를 사용한다면, 단계를 나누는데 있어 중요한 단서가 될 수 있다.

 

- 중간 데이터를 만들어 단계를 구분하고, 매개변수를 줄이는데 활용할 수 있다. 

 

 

[  Berfore  ]

 

priceOrder() 함수는 주문에 값을 매기는 일을 하지만

내부에서 할인가격과 할인된 가격을 구하는 두가지 일을 같이한다.

 

 

[  After 

 

- basePrice를 계산하는 부분과 ShippingPrice를 계산하는 부분을 분리한다.

 

- 중간에 넘겨야 할 파라미터가 많기 때문에

'priceData' record 클래스를 만들어 매개변수 개수를 줄인다. 

 

*  record 

- 불변(immutable) 데이터 객체를 쉽게 생성할 수 있도록 하는 새로운 유형의 클래스이다.

- 자동으로 생성자와 멤버를 가지는 클래스를 만들어준다.

 

 

 

 


🙌  클래스 추출하기 

 

- 클래스가 다루는 책임이 많아질수록 클래스가 점차 커진다.

 

- 클래스를 쪼개는 기준

 (1) 데이터나 메소드 중 일부가 매우 밀접한 관련이 있는 경우

 (2) 일부 데이터가 대부분 같이 바뀌는 경우

 (3) 데이터 또는 메소드 중 일부를 삭제한다면 어떻게 될 것인가?

 

- 하위 클래스를 만들어 책임을 분산 시킬 수도 있다.

 

 

 

[  Berfore  ]

 

- Person 클래스에서 officeAreaCode, officeNumber 필드가 밀접한 관계를 가지고 있어 책임을 분리 시켜줄 필요가 있다.

 

public class Person {

    private String name;

    private String officeAreaCode;

    private String officeNumber;

    public String telephoneNumber() {
        return this.officeAreaCode + " " + this.officeNumber;
    }

    public String name() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String officeAreaCode() {
        return officeAreaCode;
    }

    public void setOfficeAreaCode(String officeAreaCode) {
        this.officeAreaCode = officeAreaCode;
    }

    public String officeNumber() {
        return officeNumber;
    }

    public void setOfficeNumber(String officeNumber) {
        this.officeNumber = officeNumber;
    }
}

 

[  After 

 

- 새로운 클래스를 만들어 책임을 분산 시킬 수 있다.

- 밀접한 officeAreaCode, officeNumber 두 필드를 필드로 하는 클래스를 만들어 책임을 분리하였다.

 

public class Person {

    private TelePhoneNumber telePhoneNumber;
    private String name;

    public Person(TelePhoneNumber telePhoneNumber, String name) {
        this.telePhoneNumber = telePhoneNumber;
        this.name = name;
    }

    public String telephoneNumber() {
        return telePhoneNumber.toString();
    }

    public String name() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public TelePhoneNumber getTelePhoneNumber() {
        return telePhoneNumber;
    }
}

 

 

public class TelePhoneNumber {
    private String areaCode;
    private String number;

    public TelePhoneNumber(String areaCode, String number) {
        this.areaCode = areaCode;
        this.number = number;
    }

    public String getAreaCode() {
        return areaCode;
    }

    public void setAreaCode(String areaCode) {
        this.areaCode = areaCode;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    @Override
    public String toString() {
        return "TelePhoneNumber{" +
                "areaCode='" + areaCode + '\'' +
                ", number='" + number + '\'' +
                '}';
    }
}

 

 

 

출처 : 인프런 강의 (백기선 - 코딩으로 학습하는 리팩토링)