4.잘못된 소속(Feature Envy

[ 2017-07.25 작성 ]

자기가 속한 클래스보다 다른 클래스에 관심을 가지고 있는 경우이다.
(다른 클래스를 자신의 것보다 더 많이 사용하면 그 메서드는 feature Envy로 인해 어려움을 겪습니다.)

Code Fells and Feature Envy의 발명가 인 Martin Fowler는 다음과 같이 말합니다.
"객체의 요점은 데이터에서 사용되는 프로세스로 데이터를 패키징하는 기술이라는 것입니다. 고전적인 냄새는 그것이 있는 클래스 이외의 클래스에 더 관심이 있는 방법입니다. 부러움의 가장 공통적인 초첨은 데이터입니다"

예시 : 다이어그램

feature-envy-1.jpg

Feature Envy Diagram - 메서드의 의존성 표시. 두꺼운 화살표는 같은 기능을  많이 사용함을 의미합니다.

굵은 화살표는 사용 빈도가 적은 얇은 화살표 모양의 기능보다 많이 사용함을 의미합니다.

어떻게처리할까?

feature-envy-2.jpg

원하는 클래스로 이동하면 녹색 화살표  두께가 다른 클래스를 초과하게 됩니다. 이제  이상 Feature  Envy 없게 됩니다.

원하는대로 다른 클래스에게 줌으로써, 클래스의 사이의 결합(빨간화살표)을 줄이고 클래스 내에서 응집력(녹색화살)를 높였습니다.

sample code : 간단한 소스 코드로 예제를 들어 보겠습니다.

public class Phone {
   private final String unformattedNumber;
   public Phone(String unformattedNumber) {
      this.unformattedNumber = unformattedNumber;
   }
   public String getAreaCode() {
      return unformattedNumber.substring(0,3);
   }
   public String getPrefix() {
      return unformattedNumber.substring(3,6);
   }
   public String getNumber() {
      return unformattedNumber.substring(6,10);
   }
}
public class Customer
   private Phone mobilePhone;
   public String getMobilePhoneNumber() {
      return "(" + 
         mobilePhone.getAreaCode() + ") " +
         mobilePhone.getPrefix() + "-" +
         mobilePhone.getNumber();
   }
public class Phone {
   private final String unformattedNumber;
   public Phone(String unformattedNumber) {
      this.unformattedNumber = unformattedNumber;
   }
   private String getAreaCode() {
      return unformattedNumber.substring(0,3);
   }
   private String getPrefix() {
      return unformattedNumber.substring(3,6);
   }
   private String getNumber() {
      return unformattedNumber.substring(6,10);
   }
   public String toFormattedString() {
      return "(" + getAreaCode() + ") " + getPrefix() + "-" + getNumber();
   }  
}
public class Customer
   private Phone mobilePhone;
   public String getMobilePhoneNumber() {
      return mobilePhone.toFormattedString();
   }