“기능 부러움”코드 란 무엇이며 왜 코드 냄새로 간주됩니까?


52

SO 에 대한 이 질문 에서는 OP가 생각하는 기능 부러움 코드를 수정하는 방법에 대해 설명합니다 . 이 멋진 문구가 인용 된 또 다른 예는 최근 프로그래머가 여기주어진 대답에 있습니다 . 나는 그 대답에 대한 정보를 묻는 의견 을 들었지만 Q & A를 따르는 프로그래머가 feature-envy 라는 용어의 의미를 이해하는 것이 일반적으로 도움이 될 것이라고 생각했습니다 . 적절하다고 생각되면 추가 태그를 자유롭게 편집하십시오.


답변:


87

기능 부러움 은 객체 자체에 계산을 요구하지 않고 일종의 계산을 수행하거나 결정을하기 위해 한 객체가 다른 객체의 필드에 도달하는 상황을 설명하는 데 사용되는 용어입니다.

사소한 예로서 직사각형을 나타내는 클래스를 생각해보십시오. 사각형의 사용자는 해당 영역을 알아야합니다. 프로그래머는 필드 widthheight필드를 노출 한 다음 Rectangle클래스 외부에서 계산을 수행 할 수 있습니다. 또는 및 필드를 비공개로 Rectangle유지하고 방법을 제공 할 수 있습니다. 이것은 아마도 더 나은 접근법 일 것입니다.widthheightgetArea

첫 번째 상황의 문제점과 그것이 코드 냄새로 간주되는 이유는 캡슐화가 깨지기 때문입니다.

일반적으로 다른 클래스의 필드를 광범위하게 사용하여 모든 종류의 논리 또는 계산을 수행 할 때마다 해당 논리를 클래스 자체의 메서드로 이동하는 것이 좋습니다.


7
유용한 Rectangle 클래스는 일반적으로 너비 및 높이 필드를 노출하므로 예제는 현실적이지 않지만 +1입니다.
Doc Brown

2
그리고 캡슐화의 파괴는 "특징 환경"과 함께 발생할 있지만, 지금까지 본 대부분의 실제 사례에서는 그렇지 않았을 것입니다. "이봐, 나는 그 객체를 사용하여 코드에서 단지 무언가를 계산해야하고, 그 객체의 구현을 만질 수 있는지 / 객체에 그 계산에 대한 책임을 주어야하는지 확실하지 않다"는 상황에서 더 많이 발생합니다. 그런 다음 이미 노출 된 필드 사용하여 계산을 구현합니다 (물론 훨씬 더 깨끗한 구현이 객체 내에서 가능할 수도 있음).
Doc Brown

2
@DocBrown 원환 체, 원뿔 또는 구의 표면에 그려진 사각형을 상상해보십시오. 모양 그리기 라이브러리가 이러한 상황에서 올바른 결과를 생성 할 수있는 객체를 생성하는 경우 어떤 상황에서도 자신의 영역을 계산하도록 두지 않는 것이 어리 석습니다.
itsbruce

1
@OskarN .: 정의 따라 필요한 기능에 대해 이야기하고 있습니다 . 다른 클래스가 반복해서 다시 구현하는 경우 분명히 필요합니다.
Aaronaught

1
@OskarN .: 그것은 달려있다; 때로는 결정이 분명하고 때로는 맛의 문제, 가장 흔히 경험의 문제가되기도합니다. 이 기사에는 Scott Meyers가 " 때로는 더 적을수록 좋다 "고 쓰는 데는 충분한 이유 가 있으며 " 가족 구성원 기능을 수행 할시기를 결정하기위한 알고리즘"을 적용 하지 않을 때 이해하는 데 몇 년이 걸렸습니다 .
Doc Brown

1

클래스 / 구조체가 데이터의 컨테이너 인 경우 다른 클래스 / 구조체 메소드를 광범위하게 사용하는 것이 가능한 상황이있을 수 있습니다. 일반적으로 외부 컨텍스트없이이 데이터로 수행 할 수있는 작업이 조금 있습니다.

이러한 클래스는 여전히 일부 내부 논리를 보유 할 수 있지만 컨테이너로 사용되는 경우가 더 많습니다.

class YourUid {
 public:
  YourUid(int id_in_workplace_, int id_in_living_place_, DB* FBI_database, int id_in_FBI_database);
  bool IsInvalidWorker() const { return id_in_workplace == consts::invalid_id_in_workplace; }
  bool CanMessWith() const { return !FBI_database_.is_cool(id_in_FBI_database_); }
  int id_in_workplace;
  int id_in_living_place;
 private:
  int id_in_FBI_database_;
  const DB* FBI_database_;
};

@jhewlett은 그의 답변에서 다른 기사를 광범위하게 사용해서는 안된다는 것을 증명하기 위해이 기사를 언급하지만 다른 예제가 내 예제를 옹호하는 상황을 냄새 맡고 있습니다.

긴 매개 변수 목록. 주어진 방법에 필요한 매개 변수의 수를 제한하거나 개체를 사용하여 매개 변수를 결합하십시오.


1
이것은 질문에 어떻게 대답합니까?
gnat

@gnat Q는 "코드 냄새"로 간주되는 이유입니다. jhewlett은 의견에 의문을 제기하는 너무 일반적인 가정을 A에게 제공합니다. 내 대답은 "코드 냄새"를 일반적인 연습과 구별하기 위해 2 센트입니다.
리가
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.