9.지나친 관여 Inappropriate Intimacy

[ 2017-08.30 작성 ]

1.
지나치게 친밀한 클래스는 옛날에 연인을 갈라 놓은 것처럼 서로 떼어 놓아야 한다.
Move Method와 Move Field를 사용하여 조각을 나누고, 친밀함을 줄여야 한다.
Change Bidirectional Association to Unidirectional이 적용 가능한지를 보라.
이들 클래스에 공통 관심사가 있다면 Extract Class를 사용하여 공통된 부분을 안전한 곳으로 빼내서, 별도의 클래스를 만들어라. 또는 Hide Delegate를 사용하여 다른 클래스가 중개하도록 하라.
서브클래스는 항상 그 부모클래스가 알려주고 싶은 것보다 많은 것을 알려고 한다. 만약 출가(?) 할 때라면, Replace Inheritance with Delegation을 적용하라.

출처: http://almighty.tistory.com/20

2.
클래스가 다른 클래스의 내부에 더 관심이있는 경우 이는 관련된 데이터와 동작이 한 곳에서 처리되지 않음을 나타낼 수 있습니다.
따라서 친숙한 클래스는 메소드와 필드를 관련 데이터와 동작을 함께 사용하는 방식으로 이동 시켜서 리팩토링해야하며 클래스가 다른 클래스의 내부를 조사 할 필요가 없습니다.
캡슐화와 정보 숨김을 위반하기 때문에 좋지 않습니다.

하위 클래스는 종종 부모 클래스와 매우 친밀하지만 객체 캡슐화를지지하는 사람이 적절하다고 주장합니다.

출처 : http://wiki3.cosc.canterbury.ac.nz/index.php/Inappropriate_intimacy_smell

sample code : old

StickerPrice
public class StickerPrice
{
  ProductCalcularPrice cp;
  int width = 0; // 넓이
  int height = 0; // 높이
  int sellUnit = 0; // 판매수량
  int selLineCount = 0; // 롤 1줄 개수
  public int getPrice { get; set; }

  public int GetPrice()  // 가격
  {
  return getPrice;
  }

  public int GetCalcularPrice() // 계산된 가격
  {
  return cp.GetCal_Price();
  }
}

Sticker Class에 ProductCalcularPrice Class의 GetCal_Price() 메서드를 가지고 있다.

ProductCalcularPrice
 public class ProductCalcularPrice
 {
   StickerPrice si;
   public int Cal_Price { get; set; }
   public int GetCal_Price()
   {
   return Cal_Price;
   }

  public int GetPrice()
  {
  return si.GetPrice();
  }
}

ProductCalcularPrice Class에 StickerPrice Class의 GetPrice() 메서드를 가지고 있다.

Program
 static void Main(string[] args)
 {
 #region InappropriateIntimacy
   // 가정 : sticker 제품에 1000엔 입력. 
   ConsoleApplication1.InappropriateIntimacy.BadCode.StickerPrice stickerP = new ConsoleApplication1.InappropriateIntimacy.BadCode.StickerPrice();
   stickerP.getPrice = 1000;
   int stickerPrice = stickerP.GetPrice();

  // 가정 : sticker제품 가격의 1000엔 추가 금액
  ProductCalcularPrice productP = new ProductCalcularPrice();
  productP.Cal_Price = productP.GetPrice() + 1000; // 스티커 가격에 + 1000 추가
  
  // stickerClass에서도 ProductCalcularPrice 클래스의 GetCalcularPrice() 호출가능
  stickerP.GetCalcularPrice();  
#endregion
 }

sticker Class와 ProductCalcularPrice Class에서 서로 간의 동작을 알 수 있는 코드들이 존재하고 있습니다.

sample code : new

StickerPrice
public class StickerPrice
{
  int width = 0; // 넓이
  int height = 0; // 높이
  int sellUnit = 0; // 판매수량
  int selLineCount = 0; // 롤 1줄 개수
  public int getPrice { get; set; }

  public int GetPrice()  // 가격
  {
  return getPrice;
  }
}
ProductCalcularPrice
public class ProductCalcularPrice
{
  public int Cal_Price { get; set; }
  public int GetCal_Price()
  {
  return Cal_Price;
   }
}
Program
ConsoleApplication1.InappropriateIntimacy.StickerPrice sp = new ConsoleApplication1.InappropriateIntimacy.StickerPrice();
sp.getPrice = 1000;

ProductCalcularPrice productP = new ProductCalcularPrice();
productP.Cal_Price = 1000;

sticker Class와 ProductCalcularPrice Class에서 서로 간의 동작을 알 수 있는 코드들을
remove method를 통해 독립적인 객체로 만듬.