¿Por qué deberíamos usar preferiblemente colecciones de primera clase?

15

De acuerdo con la regla número 4 de Object Calisthenics de Jeff Bay (RTF) en The ThoughtWorks Anthology, se recomienda que uno debe " Usar colecciones de primera clase ".

Regla 4: colecciones de primera clase

La aplicación de esta regla es simple: cualquier clase que contenga una colección no debe contener otras variables miembro. Cada colección se envuelve en su propia clase, por lo que ahora los comportamientos relacionados con la colección tienen un hogar. Es posible que los filtros se conviertan en parte de esta nueva clase. Además, su nueva clase puede manejar actividades como unir dos grupos o aplicar una regla a cada elemento del grupo.

Lo que pude entender de esto fue que deberíamos usar una clase separada para concluir la colección y con métodos para agregar, eliminar, modificar datos de esa colección.

y Necesitamos esto para estar seguros de qué tipo de datos entra en la colección y qué sale.

En caso de que usemos una colección genérica (en los idiomas donde sea aplicable), ¿debemos seguir esta regla?

Si me falta un significado importante, por favor aclare.

Amogh Talpallikar
fuente
1
Amogh Talpallikar He cambiado la regla 8 a la regla 4, ya que la regla 8 en realidad es "No hay clases con más de dos variables de instancia".
Yannis
Parece decir la Regla 8 en la tabla de contenido, y luego llamarla Regla 4 en el cuerpo.
Inútil
66
¿Soy solo yo o esta regla no se puede implementar tal como está escrita? Quiero decir, tienes una clase con una colección, así que sacas todo lo demás. Ahora tu clase es una colección. Entonces, si tienes otra clase, con esa clase en ella, tiene una colección y ... haz espuma, enjuaga, repite.
mjfgates
@mjfgates: hmm ... ¡Gran punto! algo en lo que realmente pensar!
Amogh Talpallikar

Respuestas:

12

La seguridad de tipos es una razón muy pequeña para usar colecciones de primera clase. Desde tu enlace:

Regla 4: Colecciones de primera clase La aplicación de esta regla es simple: cualquier clase que contenga una colección no debe contener otras variables miembro. Cada colección se envuelve en su propia clase, por lo que ahora los comportamientos relacionados con la colección tienen un hogar. Es posible que los filtros se conviertan en parte de esta nueva clase. Además, su nueva clase puede manejar actividades como unir dos grupos o aplicar una regla a cada elemento del grupo.

La idea aquí es que si se encuentra buscando, filtrando, validando o cualquier cosa más allá de agregar / eliminar / iterar semántica en una colección, el código le pide que la coloque en su propia clase. Si necesita actualizar solo un valor (después de una búsqueda), eso probablemente va en la clase de colección.

El razonamiento para esto es bastante simple, las colecciones tienden a pasarse. Muy pronto, 4 clases diferentes tienen su propio SearchByID()método. O puede obtener valores de retorno como Map<Integer, String>con el contexto de lo que está almacenado en ese mapa eliminado. Una colección de primera clase es una solución simple que cuesta un solo archivo fuente. En la práctica, una vez que están en su lugar (también son muy fáciles de escribir pruebas unitarias), cualquier cambio relacionado con la colección es fácil de manejar, como cuando es SearchByIDnecesario tomar un GUID en lugar de un int.

Steve Jackson
fuente
8

... use una clase separada que finalice la colección y con métodos para agregar, eliminar, modificar datos de esa colección

Sin embargo, esto hace mucho más que garantizar el tipo de objetos almacenados en las colecciones, también garantiza cualquier invariante de colección.

Los árboles (rojo-negro, AVL, etc.) son sensibles a los pedidos y su comportamiento depende del reequilibrio cuando sea apropiado. El rendimiento de la tabla hash también dependerá de un nuevo hash apropiado. ¿Desea recordar comprobar el factor de carga cada vez que inserte en un mapa hash?

FWIW, el texto es bastante claro sobre esto (y editaré todo en su pregunta, por lo que nadie más necesita descargar ese RTF):

Cada colección se envuelve en su propia clase, por lo que ahora los comportamientos relacionados con la colección tienen un hogar

Nada que ver con los tipos (o, por lo tanto, genéricos), todo que ver con asociar el comportamiento de la colección con sus datos.

Inútil
fuente
1

La respuesta simple es "No" si está utilizando un lenguaje que admite Genéricos. Debido a que no hay necesidad de verificar el tipo, ya que la función de lenguaje en sí misma hace un trabajo bastante bueno en esto (desde mi experiencia genérica en Java).

Pero si tiene alguna situación en la que desea personalizar la estructura de datos dada por el lenguaje, puede crear una clase de envoltura alrededor de la estructura de datos original y exponer sus propias API y aún usar la implementación subyacente de la estructura de datos original.

java_mouse
fuente
También estoy pensando en líneas similares. pero debería haber algo, los ejemplos que vi para esto estaban en Java y C # y ambos admiten colecciones genéricas.
Amogh Talpallikar
@AmoghTalpallikar: Mi punto era mantenerlo simple. A menos que no necesite anular ningún comportamiento específico de la estructura de datos, no lo personalizaré.
java_mouse