「機能がうらやましい」コードとは何ですか。なぜコードのにおいと見なされるのですか?


53

SOに関するこの質問は、OPが機能en望のコードだと考えているものを修正することについて語っています。この気の利いたフレーズが引用されているのを私が見た別の例は、ここでprogrammers.SEで最近与えられた答えです。私はその答えにコメントを入れて情報を求めましたが、Q&Aを読んでプログラマがfeature-envyという用語の意味を理解することは一般的な助けになると思いました。適切と思われる場合は、追加のタグを自由に編集してください。


回答:


88

機能en望とは、オブジェクト自体に計算を依頼するのではなく、あるオブジェクトが別のオブジェクトのフィールドに到達して何らかの計算を実行したり、決定を下したりする状況を表す用語です。

簡単な例として、長方形を表すクラスを考えてみましょう。長方形のユーザーは、その領域を知る必要があるかもしれません。プログラマはwidthheightフィールドを公開し、Rectangleクラスの外部で計算を実行できます。または、とフィールドを非公開にしてメソッドを提供するRectangleこともできます。これは間違いなくより良いアプローチです。widthheightgetArea

最初の状況の問題、およびコードのにおいと見なされる理由は、カプセル化が破られるためです。

経験則として、他のクラスのフィールドを広範囲に使用して何らかのロジックや計算を実行する場合は、そのロジックをクラス自体のメソッドに移動することを検討してください。


7
有用なRectangleクラスは通常、幅と高さのフィールドを公開するため、+ 1は現実的ではありません。
Doc Brown

2
そして、カプセル化の破壊は「機能環境」と一緒に発生するかもしれませんが、私がこれまで見たほとんどの実際の例では、おそらくそうではありませんでした。「ちょっと、そのオブジェクトを使用してコード内でいくつかのことを計算する必要があり、そのオブジェクトの実装に触れることができるかどうか、その計算の責任をオブジェクトに与えるべきかどうか」そして、すでに公開されているフィールド使用して計算を実装します(おそらく、オブジェクト内でよりクリーンな実装が可能になります)。
Doc Brown

2
@DocBrownトーラス、円錐または球の表面に描かれた長方形を想像してください。私の形状描画ライブラリが、そのようなコンテキストで正しい結果を生成できるオブジェクトを生成する場合、それらをコンテキストから離れて自分の面積を計算しないでください-任意のコンテキストで。
-itsbruce

1
@OskarN .:定義上必要な機能について話している。他のクラスが何度も何度もそれらを再実装している場合、それらは明らかに必要です。
アーロンノート

1
@OskarN .:それは依存します。決定が明確な場合もあれば、好みの問題である場合もあり、経験の問題である場合がほとんどです。あなたの記事には、スコット・マイヤーズが「時には少ないほど多い」と書いた理由があり、「メンバーをいつ機能させるかを決定するアルゴリズム」を適用しない場合を理解するのに何年もかかった。
ドックブラウン

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 Qは、「コード臭」と見なされる理由についてです。jhewlettは、コメントで質問されている一般的すぎる仮定をAに付けています。私の答えは、「コードのにおい」を通常の慣行と区別するために2セントです。
リガ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.