2011-08-30 13 views
6

que he visto a varias personas sugieren que se debe encapsular los tipos genéricos con una clase más cerca de su dominio, por ejemplo Steve y Nat sugieren que en Growing Object-Oriented Software, Guided by Tests:¿Cuándo debería encapsular los tipos genéricos?

Nuestra regla de oro es que tratamos de limitar el paso de tipos con genéricos [...]. Particularmente cuando se aplica a colecciones, lo vemos como una forma de duplicación. Es una pista de que hay un concepto de dominio que debe extraerse en un tipo.

En general, cuando se trata de una buena idea para hacer algo como esto ..

class PersonList : List<Person> 

.. en vez de utilizar directamente List<Person>?

Respuesta

1

Porque dejar el parámetro de tipo tal como está no es realmente SECO. Considere esta clase:

class Muffin { 
    List<string> _peopleWhoLikeMuffins = new List<string>(); 

    public Muffin(List<string> peopleWhoLikeMuffins) { 
     _peopleWhoLikeMuffins = peopleWhoLikeMuffins); 
    } 

    public void AddMuffinLiker(string p) { 
     _peopleWhoLikeMuffins.Add(p); 
    } 
} 

Es muy corto y sólo contiene la funcionalidad básica, pero tenía que usar string - parámetro de tipo genertic - cuatro veces. Y siempre será lo mismo. Y si decido cambiar el tipo más tarde, tendré que reemplazar las cuatro ocurrencias.

En los escenarios del mundo real, hablamos de cientos, no de 4. Por lo tanto, no es obvio que siempre se debe encapsular, pero definitivamente vale la pena considerarlo.

Ahora, mi ejemplo no es muy bueno (y no solo por los nombres ridículos), pero se entiende la idea: tendrá mucha declaración de campo y variables e instanciación, y cada vez que tenga que pase un parámetro de tipo que siempre será el mismo a lo largo de su base de código a menos que sus otras clases también sean genéricas.

Otra ventaja de esto es que tendrá mucho menos trabajo si alguna vez necesita agregar algún estado/comportamiento adicional a su colección.

Dicho todo esto, yo mismo no uso este tipo de abstracción con mucha frecuencia.

+3

En el ejemplo que dio, que tendría más sentido para generalizar mollete a un genérico (y lo uso con cuerdas) que a codificar la lista , así que no veo como punto a favor de creando tipos específicos. – sinelaw

+0

@sinelaw: sí, señalé en mi edición que el ejemplo no es tan bueno y probablemente también debería ser genérico – Dyppl

2

No estoy de acuerdo con esa filosofía. List<Person> es un tipo como PersonList es. El concepto de dominio de una lista de personas también está encapsulado en él. Si me preguntas, es mejor usar genéricos tanto como sea posible, a menos que usarlos te limite (ver a continuación) o dificulte la comprensión del código. Por ejemplo, una función que funciona en PersonList será más difícil de generalizar que una que funcione en List<Person>, si se da cuenta de que está haciendo algo general.

Dicho esto, específicamente en Java existe una limitación en los genéricos que los hace mucho menos atractivos. Debido al borrado de tipos, no puede utilizar completamente los genéricos cuando están involucrados métodos/miembros estáticos de un tipo, y es posible que necesite extraer un tipo específico que no sea genérico para poder usarlo para ciertas cosas. En resumen, en Java necesitas extraer un tipo específico en muchos casos, si eso te permite mantenerte seguro.

3

Lo que está buscando es un operador typedef para Java o C#.

Desafortunadamente el enfoque de subclases no es un buen sustituto para typedef.

El siguiente artículo "Java theory and practice: The pseudo-typedef antipattern" explica por qué con todo detalle.

voy a copiar textualmente la conclusión de que el artículo aquí:

La motivación para el anti patrón pseudo-typedef es sencillo suficientes - los desarrolladores quieren una manera de definir el tipo más compactos identificadores, especialmente como genéricos make type identificadores más verbose. El problema es que este modismo crea un acoplamiento fuerte entre el código que lo emplea y los clientes del código, lo que inhibe la reutilización. Usted puede no gustarle la verbosidad de los identificadores de tipo genérico, pero esto es no es la manera de resolverlo.