¿Qué es un código de "envidia de características" y por qué se considera un olor de código?

46

Esta pregunta sobre SO habla sobre la corrección lo que el OP pensó es el código feature envy . Otro ejemplo en el que vi que esta frase ingeniosa se cita es en una respuesta dada recientemente aquí en programmers.SE. Aunque sí caí en un comente a esa respuesta, solicitando la información que pensé que sería de ayuda general para los programadores que siguen Q & A para comprender qué se entiende por el término feature-envy . Por favor, siéntase libre de editar etiquetas adicionales si lo considera adecuado.

    
pregunta Geek 21.09.2013 - 06:07

2 respuestas

79

Feature Envy es un término usado para describir una situación en la que un objeto se pone en los campos de otro objeto para realizar algún tipo de cálculo o tomar una decisión, en lugar de pedirle al objeto que realice el cálculo en sí mismo.

Como ejemplo trivial, considere una clase que representa un rectángulo. El usuario del rectángulo puede necesitar conocer su área. El programador podría exponer los campos width y height y luego realizar el cálculo fuera de la clase Rectangle . Alternativamente, Rectangle podría mantener los campos width y height privados y proporcionar un método getArea . Este es posiblemente un mejor enfoque.

El problema con la primera situación, y la razón por la que se considera un olor de código, es porque rompe la encapsulación.

Como regla general, cuando te encuentres haciendo un uso extensivo de los campos de otra clase para realizar cualquier tipo de lógica o cálculo, considera mover esa lógica a un método en la clase en sí.

    
respondido por el jhewlett 21.09.2013 - 06:35
0

Existe una posible situación en la que está bien usar otros métodos de clase / estructura extensivamente, cuando su clase / estructura es un contenedor de datos. Por lo general, es poco lo que puede hacer con estos datos sin contexto externo.

Estas clases aún pueden contener cierta lógica interna, pero más a menudo se usan como contenedores:

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 en su respuesta se refiere a este artículo para demostrar que no debe usar a otros miembros de la clase de forma extensiva, pero hay otra situación code smells descrita allí con los defensores de mi ejemplo:

  

Lista de parámetros larga. Limite el número de parámetros que necesita en un determinado   Método, o utilice un objeto para combinar los parámetros.

    
respondido por el Riga 23.09.2013 - 23:58

Lea otras preguntas en las etiquetas