2010-11-25 12 views
10

¿Es deficiente diseño tener una clase que contenga una colección de sí mismo como en una lista <> para C#? ¿Por qué es esto y qué es un mejor enfoque y por qué?¿Debería una clase contener una colección de sí mismo?

EDITAR: Más específicamente, tengo una clase llamada Producto y un método en la clase llamada GetProducts() que devuelve una colección de Lista. Está bien agarrar los productos de una base de datos, un archivo plano o xml ... todavía no estoy seguro.

Gracias!

+0

OK, tengo una clase llamada producto y un método dentro llamado GetProducts que devuelve una lista y no estaba seguro de si este era el enfoque correcto. – user204588

+0

Quizás consideraría escribir una clase 'ProductCollection' que proporcionaría métodos relacionados con las colecciones, pero no me molestaría demasiado al respecto. Quizás sea suficiente hacer este método 'GetProducts' para su clase' Product'. De esta forma, su clase 'Producto' se comportaría de alguna manera como una fachada de producto, si podemos decirlo. –

Respuesta

10

Con la actualización del Producto y GetProducts() creo que esto podría no ser tan bueno.

Utilizo una regla de oro como un principio aquí que se basa en la lógica que es el dominio, no el lenguaje, específico. Entonces, en su caso, me preguntaría: "¿Mi producto contiene otros productos reales?" Si la respuesta es afirmativa, la colección de productos es perfectamente legítima en la clase de Producto. Si no, pregunte qué contiene realmente estos productos. Una tienda tal vez?

Existe una excepción a esta regla con métodos estáticos. Si GetProducts() es estático, entonces el razonamiento superior no se aplica y, por lo general, está perfectamente bien tenerlo en la clase Producto.

+0

+1 para el enfoque explicado. =) –

+0

¿por qué el método estático no se aplica en su ejemplo? Sólo curioso. – user204588

+1

La forma en que veo los métodos estáticos para los modelos de datos (cómo suena esto) es que usan que tienen algo que ver con esa clase pero que están subiendo de nivel. No estoy seguro de estar explicando esto correctamente. Lo entiendo en mi cabeza, pero escribirlo no es tan simple para mí :) Pero, por ejemplo, los métodos de Parse() son algo típico. 'int.Parse (somestring)' es un método estático y mejor que 'a.Parse (somestring)' (a obtiene el valor analizado) porque puede usarlo en una expresión como 'int c = 24 + int.Parse (somestring) '. Espero confiar en esto correctamente – gligoran

0

Puede ser pobre y bueno, dependiendo del problema que resuelva, y si es un objeto generalizado o no. Muchos factores pueden influir en tales decisiones de diseño. Al final, no se trata de un diseño bueno o malo, pero si este es el camino correcto, eliges cruzar el río.

editar # 1

bien, tengo una llamada producto de clase y un método en el interior llamados GetProducts que devuelve una lista y yo no estaba seguro de si este era el enfoque correcto.

Bajo esta circunstancia, haría el método Product.GetProducts estático. Como tal, cuando se desea cargar los productos, simplemente la dirección de su clase Product así:

IList<Product> products = Product.GetProducts(); 

una lista de por sí sería suponer que un producto puede estar compuesto de diferentes otros productos, como los productos de componentes. Sin embargo, con un método estático, la clase Product se convertiría en la fábrica para el negocio relacionado con el producto.

+0

¿Estás hablando del patrón de fábrica aquí o solo en general como el objeto que crea los productos? – user204588

0

Claro que generalmente está bien. Esa es generalmente la forma más sensata de implementar un árbol de manera OOP-y; un TreeNode debe contener un campo List<TreeNode> m_Children, de modo que el nodo sepa cuáles son sus elementos secundarios para el cruce de árboles.

1

Esto está bien. Ha surgido un tree o un graph

0

Siempre y cuando no entre en conflicto con el principio de responsabilidad única, supongo que no sería un problema.

2

En lo personal, me gustaría usar el patrón de repositorio:

public class IProductRepository 
{ 
    IEnumerable<Product> GetAll(); 
} 

luego escribir una implementación:

public class ProductRepository 
{ 
    public IEnumerable<Product> GetAll() 
    { 
     // Database logic or read from an xml file... etc. 
    } 
} 

pasar una IProductRepository a la persona que llama (usando un contenedor IoC como Ninject o el Castillo de Windsor) . Luego, si es necesario, puede simular fácilmente IProductRepository para probar con la persona que llama.

De esta forma, mantiene el modelo real (Product) separado de "lo que puede hacer" con los productos.

Pero, si Product s también necesitaba tener Products (ejemplo: SubProducts), usted podría tener un ICollection<Product> en Product también.

Cuestiones relacionadas