2008-12-08 18 views
9

Si un objeto tiene una propiedad que es una colección, ¿debe el objeto crear el objeto de colección o realizar una comprobación del consumidor para nulo? Sé que el consumidor no debería asumirlo, solo se pregunta si la mayoría de las personas crea el objeto de colección si nunca se agrega.¿Inicializar una colección dentro de un objeto?

Respuesta

7

También puede usar el patrón "Lazy initailizer" donde la colección no se inicializa hasta (y salvo) que alguien acceda al getter de la propiedad para ello ... Esto evita la sobrecarga de crearlo en aquellos casos donde el objeto principal es instanciado para algún otro propósito que no requiere la colección ...

public class Division 
    { 
     private int divId; 
     public int DivisionId { get; set; } 

     private Collection<Employee> emps; 
     public Collection<Employee> Employees 
     { get {return emps?? (emps = new Collection<Employee>(DivisionId));}} 
    } 

EDIT: Este patrón de aplicación es, en general, no hilo de seguridad ... emps podría ser leído por dos hilos diferentes como nulo antes del primer hilo termina de modificarlo. En este caso, probablemente no importe ya que DivisionId es inmutable y aunque ambos hilos obtendrían colecciones diferentes, ambos serían válidos. Por lo tanto, cuando el segundo hilo se cierre, por lo tanto, los emps serían una colección válida. El 'probablemente' es porque podría ser posible que el primer subproceso empiece a usar emps antes de que el segundo subproceso lo reinicie. Eso no sería seguro para hilos. Otra implementación un poco más compleja de Jon SKeet es segura para subprocesos (ver This article on SIngletons para su ejemplo/discusión sobre cómo solucionar esto.

+0

Sucede que me gusta de esta manera ... se adapta a mis necesidades .. – CSharpAtl

+0

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Es mi estilo de hacer las cosas también !! Vote + 1 – Perpetualcoder

+0

Aceptar pero (1) tenga en cuenta que esta implementación de inicialización lenta no es segura para subprocesos, lo cual está bien siempre que esté documentado como tal (2) la dependencia de los empleados en la propiedad de lectura/escritura DivisionId significa la orden de establecer propiedades es significativo, contrariamente a las pautas de MS. – Joe

1

Creo una colección vacía. Claro, tiene un pequeño costo de memoria, pero no lo suficientemente grande como para preocuparse por ello.

1

IMO, aquí es donde IEnumerable entra muy bien.

Personalmente, me gusta que mis propiedades de "colección" se inicialicen en listas vacías.

3

Esto depende del contrato que tenga entre su API y el usuario.

Personalmente, me gusta un contrato que hace que el Object administre sus colecciones, es decir, crear instancias de creación y asegurarse de que no se pueden establecer como nulas a través de un setter, posiblemente proporcionando métodos para administrar la colección en lugar de configurando la colección en sí.

es decir, addFoo (Foo toAdd) en lugar de setFooSet (Set set), y así sucesivamente.

Pero depende de usted.

2

Normalmente crearé la colección y luego proporcionaré métodos para agregar/eliminar elementos de la colección interna en lugar de que el consumidor de la clase se preocupe por la comprobación de nulos. Esto también le da la capacidad de controlar mejor lo que sucede con la colección. En última instancia, depende de para qué sirve, pero lo más probable es que si su clase tiene una colección no es solo para que el consumidor de la clase pueda tener una colección de esos objetos. De lo contrario, ¿por qué usarían su clase?

2

Si bien lo que digo aquí no es universal de ninguna manera, creo que las colecciones son principalmente adecuadas como propiedades privadas a las que se debe acceder mediante métodos públicos en el objeto mismo. Por lo tanto, el objeto es responsable de crearlos y destruirlos según sea necesario. De esta forma, no será posible configurarlo como nulo desde un código externo.

1

Si la colección es una parte intrínseca del objeto, entonces el objeto generalmente debe crearlo (y no permitir que el usuario lo configure en una instancia de colección diferente).

1

Lo he intentado de ambas maneras y normalmente estoy contento cuando encuentro que ya lo he instanciado. Alternativamente, podría ocultar la implementación del consumidor detrás de un conjunto de métodos que pueden manejar el cheque por usted.

2

Prefiero crear la colección al crear instancias, proporcionar métodos de agregar/eliminar en el objeto contenedor y, si es necesario, proporcionar métodos addAll/removeAll para agregar y eliminar colecciones externas enteras. Nunca permito que la persona que llama obtenga o acceda al objeto de colección; sin embargo, puedo proporcionar un getter que devuelva una copia (posiblemente inmutable) de la colección.

También he tenido implementaciones de copia sobre escritura que proporcionan una vista envolvente inmutable, ya que cualquier mutación creará una nueva colección subyacente.

0

Como regla general, creo que el objeto debe crear la colección y proporcionar métodos para manipularla; add/get/remove. Al seguir esta regla, no debe proporcionar los métodos para establecer la colección directamente. Si desea un método como setSomeCollection (Collection someCollection) por conveniencia, la implementación de este método no debe establecer la referencia dentro del objeto. pero copie los valores de la colección de parámetros del método en la colección dentro del objeto;

public void setSomeCollection(Collection someCollection) { 
    this.someCollection.clear(); 
    this.someCollection.addAll(someCollection); 
} 

Debería hacer esto, para que los clientes de su API no puedan acceder a la colección que mantiene su clase. Si lo hacen, pueden manipularlo sin usar objetos de su clase y violar las restricciones que garantiza su clase.

Lo mismo es cierto si proporciona un getter; debe devolver una copia de su colección interna, o una versión de solo lectura de la misma. Las colecciones comunes y colecciones de google de Apache proporcionan métodos para crear envoltorios inmutables alrededor de una colección, así como los que vienen con Java en el paquete java.util; java.util.Collections.unmodifiable *.

Cuestiones relacionadas