[Refactoring] 데이터 체계화

데이터 체계화

필드 자체 캡슐화

수정 전

private int low , high;
boolean includes (int arg ) {
  return arg >= low && arg <= high;
}

수정 후

private int low , high;
boolean includes (int arg) {
  return arg >= getLow() && arg <= getHigh();
}
int getLow() {return low;}
int getHigh() {return high;}

데이터 값을 객체로 전환

데이터 값을 객체로 전환

수정 전

// 개발 초기 단계에서는 단순 정보를 간단한 데이터 항목으로 표현. Order 객체로 데이터 Get한다.
class Order {
  public Order (String customer) {
    customer = customer;
  }
  public String getCustomer() {
    return customer;
  }
  public void setCustomer (String arg) {
    customer = arg;
  }
  private String customer;
}

class OrderService ...
  private int numberOfOrdersFor(Collection orders, String customer) {
    int result = 0;
    Iterator iter = orders.iterator();
    while (iter.hasNext()) {
    Order each = (Order) iter.next();
    if (each.getCustomer().equals (customer)) result++;
    return result;
  }
...

수정 후

// 간단한 항목이 점점 복잡해진다(ex.형식화,지역번호 추출등). 항목객체(Customer)를 추가하여 항목들을 객체로 관리한다.

// Order 객체 수정.
class Order {
  public Order (String customer) {
    customer = new Customer(customer);
  }
  public String getCustomer() {
    return customer.getName();
  }
  private Customer customer;
  public void setCustomer (String arg) {
    customer = new Customer(arg );;
  }
}

// Customer 객체 추가
class Customer {
  public Customer (String name) {
    name = name;
  }
  public String getName() {
    return name;
  }
  private final String name;
}

class OrderService ...
  private int numberOfOrdersFor(Collection orders, String customer) {
    int result = 0;
    Iterator iter = orders.iterator();
    while (iter.hasNext()) {
    Order each = (Order) iter.next();
    if (each.getCustomer().equals (customer)) result++;
    return result;
  }
...

값을 참조로 전환

참조를 값으로 전환

배열을 객체로 전환

관측 데이터 복제

클래스의 단방향 연결을 양방향으로 전환

클래스의 양방향 연결을 단방향으로 전환

마법 숫자를 기호 상수로 전환

double potentialEnergy(double mass , double height) {
  return mass * 9.81 * height;
}

수정 후

static final double GRAVITATIONAL_CONSTANT = 9.81;

double potentialEnergy(double mass , double height) {
  return mass * GRAVITATIONAL_CONSTANT * height;
}

필드 캡슐화

수정 전

public String name;

수정 후

private String name;
public String getName() {return name;}
public void setName(String arg) {name = arg;}

컬렉션 캡슐화

수정 전

class Course...
  public Course (String name , boolean isAdvanced) {...};
  public boolean isAdvanced () {...};
...

class Person ...
  public Set getCourses () {
    return courses;
  }
  public void setCourses (Set arg ) {
    courses = arg;
  }
  private Set courses ;
...

// 컬렉션 사용 코드
Person kent = new Person();
Set s = new HashSet();
s.add (new Course("스몰토크 프로그래밍" false));
s.add(new Course ("싱글몰트 위스키 음미하기" true));
kent.setCourses(s);
Assert.equals (2, kent.getCourses().size());
Course refact = new Course ("리맥토링 true");
kent.getCourses().add(refact);
kent.getCourses().add(new Course ("지독한 빈 정 거림", false));
Assert.equals(4, kent.getCourses().size()) ;
kent.getCourses().remove(refact);
Assert.equals(3, kent.getCourses().size());

수정 후

class Person {
  private Set courses = new HashSet();

  public void addCourse(Course arg) (
    courses.add(arg);
  }
  public void removeCourse(Course arg) {
    courses.remove (arg );
  }
}

// 컬렉션 사용 코드
Person kent = new Person();
kent.addCourse(new Course ("스몰토크 프로그래밍’" fal se));
kent.addCourse(new Course ("싱글몰트 위스키 음미하기 true));
...

레코드를 데이터 클래스로 전환

분류 부호를 클래스로 전환

수정 전

public static final int 0 = 0;
public static final int A = 1;
public static final int B = 2;
public static final int AB = 3;
private int bloodGroup;

수정 후

public static final BloodGroup 0 = new BloodGroup(0);
public static final BloodGroup A = new BloodGroup(1);
public static final BloodGroup B = new BloodGroup(2);
public static final BloodGroup AB = new BloodGroup(3);
private static final BloodGroup[] values = {O, A, B, AB};

private final int code;
private BloodGroup (int code ) {
code = code;

분류 부호를 하위 클래스로 전환

분류 부호를 하위 클래스로 전환

분류 부호를 상태/전략 패턴으로 전환

분류 부호를 상태/전략 패턴으로 전환

하위클래스를 필드로 전환

하위클래스를 필드로 전환

수정 전

abstract class Person {
  abstract boolean isMale() ;
  abstract char getCode() ;
}
class Male extends Person {
  boolean isMale () {
    return true;
  }
  char getCode() {
    return "M";
  }
}

수정 후

class Person{
  private final boolean isMale ;
  private final char code;

  protected Person (boolean isMale , char code ) {
    isMale = isMale ;
    code = code;
  }

  static Person createMale () {
    return new Person (true, "M");
  }
}