tonykang22 / study

0 stars 0 forks source link

[Refactoring] 냄새 20. 거대한 클래스 #45

Open tonykang22 opened 2 years ago

tonykang22 commented 2 years ago

냄새 20. 거대한 클래스 (Large Class)


리팩토링 41. 슈퍼클래스 추출하기 (Extract Superclass)


예시 코드

Before

두 코드가 하는 일이 비슷하다. 중복 코드로 여겨질 만한 것들을 제거하기 위해 슈퍼클래스 추출하기를 사용해보자.

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 Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public double getMonthlyCost() {
        return monthlyCost;
    }

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


After

Party라는 슈퍼클래스를 만들어 공통된 책임과 필드를 추출해낸다. monthlyCost()는 각 로직이 다르므로 abstract method를 사용해 해결한다.

public abstract class Party {

    protected String name;

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

    public String getName() {
        return name;
    }

    public double annualCost() {
        return 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
    protected 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
    protected double monthlyCost() {
        return monthlyCost;
    }
}