[Refactoring] 거대한 클래스 (Large Class)

서준교·2023년 12월 31일
0

Refactoring

목록 보기
8/8
post-thumbnail

👉 이 게시글은 inflearn의 코딩으로 학습하는 리팩토링 강의 내용을 바탕으로 작성되었습니다.

어떠한 클래스가 너무 많은 행위를 담당하다 보면, 그에 따라 필드 또한 많아지고 중복 코드도 생기게 됩니다. 클라이언트가 해당 클래스가 제공하는 기능 중에서 일부만 사용한다면, 각각의 세부 기능을 별도의 클래스로 분리할 수 있게 됩니다.

클래스 추출하기를 통하여 관련있는 필드를 한 곳으로 모을 수 있고, 상속 구조를 만들 수 있다면 슈퍼클래스를 추출하여 리팩토링을 할 수 있습니다.

또한, 클래스 내부에 산재하는 중복 코드는 메소드를 추출하여 제거할 수 있습니다.

슈퍼클래스 추출하기 (Extract Superclass)

두 가지 클래스에서 비슷한 필드나 메소드들이 보인다면, 상속을 적용하고 슈퍼클래스로 필드를 올리기(Pull Up Field) 또는 메소드 올리기(Pull Up Method)를 사용합니다. 우선은 상속을 저

public class Department {

    private String name;

    private List<Employee> staff;

    public String getName() {
        return name;
    }

    public List<Employee> getStaff() {
        return staff;
    }

    public double totalMonthlyCost() {
        return this.staff.stream().mapToDouble(e -> e.getMonthlyCost()).sum();
    }

    public double totalAnnualCost() {
        return this.totalMonthlyCost() * 12;
    }

    public int headCount() {
        return this.staff.size();
    }
}

public class Employee {

    private Integer id;

    private String name;

    private double monthlyCost;

    public double annualCost() {
        return this.monthlyCost * 12;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public double getMonthlyCost() {
        return monthlyCost;
    }
}

기존의 Department, Employee 클래스에서 공통적으로 사용되는 필드(name)와 유사한 성격을 가지는 메소드들(totalMonthlyCost, totalAnnualCost, getMonthlyCost)을 슈퍼클래스를 생성하고 해당 클래스로 이동시키는 작업을 진행하도록 하겠습니다.

After Refactoring

public abstract class Party {
    protected String name;

    public Party(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public double annualCost() {
        return this.monthlyCost() * 12;
    }

    abstract protected double monthlyCost();
}
public class Department extends Party {

    private List<Employee> staff;

    public Department(String name) {
        super(name);
    }

    public List<Employee> getStaff() {
        return staff;
    }

    @Override
    public double monthlyCost() {
        return this.staff.stream().mapToDouble(e -> e.monthlyCost()).sum();
    }

    public int headCount() {
        return this.staff.size();
    }
}
public class Employee extends Party {

    private Integer id;

    private double monthlyCost;

    public Employee(String name) {
        super(name);
    }

    public Integer getId() {
        return id;
    }

    @Override
    public double monthlyCost() {
        return monthlyCost;
    }
}

Party라는 슈퍼클래스를 추상 클래스로 생성하여 두 클래스 모두 Party 클래스를 상속받도록 만들고, 이전의 두 클래스에서 유사한 역할을 하는 메소드를 추상 메소드로 만들어 하위 클래스에서 오버라이딩을 하는 구조로 변경하였습니다.

profile
매일 성장하는 개발자가 되고 싶습니다. 😊

0개의 댓글