¿Es apropiado que una clase sea solo una colección de información sin lógica?

8

Decir que tengo una clase Personque tiene variables de instancia age, weighty height, y otra clase Fruitque tiene variables de instancia sugarContenty texture. La Personclase no tiene métodos, excepto setters y getters, mientras que la Fruitclase tiene setters y getters y métodos lógicos como calculateSweetness. ¿Es la Fruitclase el tipo de clase que es mejor práctica que la Personclase? Lo que quiero decir con esto es que la Personclase parece que no tiene mucho propósito; existe únicamente para organizar datos, mientras que la Fruitclase organiza datos y en realidad contiene métodos para la lógica.

pasawaya
fuente
Entonces, una persona tiene setters para altura, peso y / o altura, ¿verdad? Los establecedores no tendrían sentido a menos que haya una lógica que manipule estos atributos en alguna parte. ¿Es esa lógica en una clase correcta?
VENIDO del
@COMEFROM: tiene razón, esa es la pregunta que debe hacerse aquí. Sin embargo, en los sistemas de información no es infrecuente que el propósito de algunos atributos sea que se almacenen, muestren e informen en ese sistema, sin ninguna lógica real (los procesos comerciales que realmente usan esos atributos pueden existir fuera del sistema de información).
Doc Brown
@ Doc Brown: Lo sé y estoy de acuerdo. No veo nada malo con las clases sin lógica, pero tener setters en esa clase es algo sospechoso. Verificaría dónde se necesitan estos setters. Como escribió: agregue funcionalidades a una clase cuando sea necesario. Un setter es una funcionalidad.
VENIDO del

Respuestas:

8

Si su persona realmente no está haciendo nada, entonces no hay necesidad de realizar ninguna acción al respecto. Es posible tener clases que solo recopilan datos y luego habrá clases que operan con estos datos. En su caso, es posible que no tenga ninguna acción sobre una sola persona, pero puede haber acción sobre un grupo de personas, como CalculateAverageHeight (). En este caso, tiene sentido tener solo Persona sin acción y luego tener otra clase (puede ser amiga) que trabaje en esto.

Manoj R
fuente
1
No diría que era "común" dividir sus datos y su lógica en diferentes clases en un sistema OOP diseñado adecuadamente. Para su ejemplo, esperaría CalculateAverageHeight()ser un método estático en el Personque se toma una colección de Personobjetos. De esa manera, aunque CalculateAverageHeight()no es aplicable a una instancia individual de Person, aún lo mantiene cerca de los datos en los que opera.
TMN
1
@ TMN - Perdón por la palabra común. No es común, pero posible. No estoy de acuerdo con que el cálculo de la altura promedio esté estrechamente relacionado con la clase de persona. Considere otra función HighDensityArea (), que descubre cuál es el área en la que reside la mayoría de la población. Esta función solo necesita el campo de dirección de la persona. No hay necesidad de vincular esto estrechamente con la clase Persona.
Manoj R
4

Es difícil llegar con una regla que diga que todas las clases deben tener cierta lógica. En general, las clases sin ninguna lógica se consideran AnemicDomainModel .

Incluso entonces, es mejor organizar los datos si la información relacionada se está volviendo grande. Por ejemplo, en este caso aún puede necesitar una colección de Persona que muchas colecciones no relacionadas.

Jayan
fuente
3
No creo que esto (AnemicDomainModel) sea siempre cierto solo porque no tienes lógica. De hecho, creo que muchos tipos básicos de Entidades son solo esto: una recopilación de información relacionada con un objeto en particular, pero sin ninguna lógica particular relacionada con él. Una persona simplemente ... es, sin embargo, sería difícil argumentar que no debería tener una clase para representar a una persona.
Peter Rowell
@ Peter Rowell: La entidad (bean) de J2EE recibe una mención especial en el artículo.
Jayan
1
También podría haber implementado el patrón de diseño de comando
Eoin
Una buena definición de trabajo del modelo de dominio anémico es un dominio en el que deben existir reglas comerciales para imponer la integridad de los datos dentro de un objeto, pero esas reglas no están encapsuladas dentro del mismo objeto . Si un objeto no necesita lógica para mantener un estado interno consistente, como un patrón de Money, entonces no debería haber dicho lógica. Sin embargo, si una factura tiene una propiedad de datos de subtotal que siempre debe ser la suma de los costos extendidos de sus elementos de línea (cada uno de los cuales es a su vez precio unitario * cantidad), esas propiedades deben calcularse y no configurarse directamente.
KeithS
Si tienes muchas clases como esta, tienes un problema. Sin embargo, a veces simplemente desea organizar algunos elementos de datos, pero no hay métodos que no tengan más sentido en otros lugares.
Loren Pechtel
3

El DataTransferObject es un buen ejemplo de una clase que no tiene lógica, sólo los datos. Sin embargo, ese es su propósito; Es explícitamente una excepción a la regla general que todas las clases deben implementar la lógica de negocios que afecta su estado interno. Tener una clase cuyo estado interno es cambiado por la lógica externa es a menudo un olor de diseño. No siempre está mal, pero casi siempre es algo que debería considerar refactorizar.

TMN
fuente
3

Invierta la pregunta, mire el otro extremo. Si tiene una colección de información que obviamente pertenece, ¿debería mantenerla separada solo porque no hay métodos que pueda agregar a esa clase? ¿Debería verse obligado a inventar métodos arbitrarios solo para justificar la clase?

MSalters
fuente
2

Los modelos no tienen fin en sí mismos: debe agregar funcionalidades a una clase cuando realmente las necesite en su programa, no suponiendo que las necesitará probablemente en el futuro. Entonces, es natural que en un momento dado tengas clases sin métodos "reales", y luego, cuando determines que tiene sentido agregar métodos a la clase, haces exactamente eso. La calidad de un modelo no se mide con "¿tengo métodos aquí y no hay métodos allí?", La calidad se mide con "tengo todos los métodos que mi aplicación realmente necesita allí".

Por ejemplo, cuando su aplicación en la versión 1.0 necesita algo como calculateSweetnesspara un Fruit, pero no realiza ninguna operación en Personexcepto obtener y establecer los atributos, entonces su modelo debe reflejar exactamente eso al no tener ninguna lógica en la clase Person. En la versión 2.0, puede tener sentido agregar algo de lógica a una Person, así que cuando esté en ese punto, agregue los métodos en cuestión.

Doc Brown
fuente
1

Creo que esto depende del idioma y de cómo lo esté utilizando.

En el caso trivial, algunos idiomas insisten en que todo esté en una clase, por lo que, por ejemplo, las colecciones de constantes deben ir a una clase que luego puede o no tener lógica, en otros idiomas pueden terminar en un espacio de nombres.

En lenguajes de paradigmas múltiples, también puede depender de a qué paradigma desea que se adhiera su diseño. Tomando prestado el ejemplo de CalculateAverageHeight (), ya que probablemente debería residir en una clase PersonCollection, sin embargo, eso presupone una solución OOP. en un diseño más funcional, puede usar una función de orden superior con una colección genérica, por ejemplo, en C #

List<Person> personList = GetListOfPeople();
personlist.Average(p => p.Height);

y luego la lógica no está en PersonCollection o incluso estáticamente en Person. De hecho, las funciones de orden superior y los tipos de datos genéricos en general significan que es más probable que termines con objetos que son solo bolsas de datos, ya que la lógica funciona a un nivel de abstracción más alto que tu modelo de datos específico .

jk.
fuente
1

Parece que de lo que estás hablando es de un POD (datos antiguos simples). Los diferentes lenguajes pueden representarlos de diferentes maneras: podría ser una clase con miembros públicos, por ejemplo, o una estructura con solo miembros públicos en C ++.

La organización de datos es una razón perfectamente válida para que exista una clase: a menudo puede hacer que el código sea más limpio y fácil de leer. std::pairen STL de C ++ es un buen ejemplo de una estructura que existe únicamente para organizar datos, simplemente una estructura que contiene dos valores de cualquier tipo llamado firsty second. Probablemente una de las clases más útiles en todo el STL (en mi opinión de todos modos :))

Bok McDonagh
fuente