public void setName(String name) {
this.name = name;
}
public String getPersonalAreaCode() {
return personalAreaCode;
}
public void setPersonalAreaCode(String personalAreaCode) {
this.personalAreaCode = personalAreaCode;
}
public String getPersonalNumber() {
return personalNumber;
}
public void setPersonalNumber(String personalNumber) {
this.personalNumber = personalNumber;
}
}
public class Office {
private String location;
private String officeArea;
private String officeNumber;
public Office(String location, String officeArea, String officeNumber) {
this.location = location;
this.officeArea = officeArea;
this.officeNumber = officeNumber;
}
public String officePhoneNumber() {
return officeArea + "-" + officeNumber;
}
public String getOfficeAreaCode() {
return officeArea;
}
public void setOfficeAreaCode(String officeArea) {
this.officeArea = officeArea;
}
public String getOfficeNumber() {
return officeNumber;
}
public void setOfficeNumber(String officeNumber) {
this.officeNumber = officeNumber;
}
}
변경 후
뭉쳐다니는 필드들을 묶어 TelephoneNumber라는 클래스로 추출했다.
(Office와 Employee 코드가 유사하기에 변경 후의 Office 코드만 첨부)
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 areaCode + "-" + number;
}
}
public class Office {
private String location;
private TelephoneNumber telephoneNumber;
public Office(String location, TelephoneNumber telephoneNumber) {
this.location = location;
this.telephoneNumber = telephoneNumber;
}
public String officePhoneNumber() {
return this.telephoneNumber.toString();
}
public TelephoneNumber getTelephoneNumber() {
return this.telephoneNumber;
}
public String getOfficeAreaCode() {
return this.telephoneNumber.getAreaCode();
}
public void setOfficeAreaCode(String officeArea) {
this.telephoneNumber.setAreaCode(officeArea);
}
public String getOfficeNumber() {
return this.telephoneNumber.getNumber();
}
public void setOfficeNumber(String officeNumber) {
this.telephoneNumber.setNumber(officeNumber);
}
}
예시 이지만, setter를 사용하는 것에 대해서는 다시, 한번 더 생각 해보아야 할 것 같다.
캡슐화를 저해하기 때문이다.
로직이 명확하지 않아 가독성을 낮춘다고 생각한다.
(만약에라도 private한 속성 값을 외부에서 굳이 꼭, 변경해야한다면 ...updateDto 등을 만들어 update(updateDto); 를 호출하는건 어떨까)
사실 getter도 마찬가지로 지양해야할 메소드로, DTO, VO와 같이 getter가 꼭 필요한 상황이 아닌 이상, getter로 가져온 상태값으로 수행하려던 행동을 그 상태값을 가진 객체가 하도록 행동의 주체를 변경하는 방법으로 사용을 피하는 것이 바람직하다고 생각한다.
Office에 남아있는 getter & setter 메소드를 다른 곳에서 사용하기 때문에 그대로 놔두기 위해 변경하지 않은 것에 대해 의문이 들었다.
getter, setter 메소드는 암묵적으로 그 네이밍만으로 필드에 존재하는 데이터를 유추할 수 있게 되는데, 혼선을 가져다주는 것이 아닌가? 왜 이렇게 끝났을까?
1) 뭉쳐있는 데이터를 분리해내는 리팩토링 후, 한 번에 메소드를 삭제하면 추후 IDE를 통해 리팩토링하기가 번거로워 지기 때문에 그럴 수도 있겠다.
2) 애초에 뭉쳐있는 데이터를 분리해내는 리팩토링을 한 예시 코드이고, 현재 예시에서는 리팩토링을 마친게 아닌 뭉쳐있는 데이터를 분리해낸 리팩토링만 사용했을 수 있겠다.
냄새 10. 데이터 뭉치 (Data Clumps)
클래스 추출하기 (Extract Class)
를 사용해 여러 필드를 하나의 객체나 클래스로 모을 수 있다.매개변수 객체 만들기 (Introduce Parameter Object)
또는객체 통째로 넘기기 (Preserve Whole Object)
를 사용해 메소드 매개변수를 개선할 수 있다예시
변경 전
클래스 추출하기
방법을 사용해 여러 필드들을 하나의 클래스로 모아 개선하는 것이 옳다고 판단된다.private String name;
private String personalAreaCode;
private String personalNumber;
public Employee(String name, String personalAreaCode, String personalNumber) { this.name = name; this.personalAreaCode = personalAreaCode; this.personalNumber = personalNumber; }
public String personalPhoneNumber() { return personalAreaCode + "-" + personalNumber; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPersonalAreaCode() { return personalAreaCode; }
public void setPersonalAreaCode(String personalAreaCode) { this.personalAreaCode = personalAreaCode; }
public String getPersonalNumber() { return personalNumber; }
public void setPersonalNumber(String personalNumber) { this.personalNumber = personalNumber; } }
리팩토링
을 한 예시 코드이고, 현재 예시에서는 리팩토링을 마친게 아닌 뭉쳐있는 데이터를 분리해낸 리팩토링만 사용했을 수 있겠다.