2010-04-11 17 views
7

Estoy aprendiendo mucho sobre los patrones de diseño cuando estoy construyendo mi propio sistema para mis proyectos. Y quiero preguntarle acerca de una pregunta de diseño a la que no puedo encontrar una respuesta.Dos objetos con dependencias entre ellos. ¿Es tan malo?

Actualmente estoy construyendo un pequeño servidor de chat usando sockets, con varios clientes. Ahora mismo tengo tres clases:

  1. persona de clase que contiene información como nick, edad y una habitación a objetos.
  2. Clase de habitación que contiene información como nombre de habitación, tema y una lista de personas actualmente en esa habitación.
  3. Clase de hotel que tienen una lista de personas y una lista de salas en el servidor.

He hecho un diagrama para ilustrarlo:

Tengo una lista de personas en el servidor de la clase del hotel, ya que sería bueno hacer un seguimiento de cuántos están online ahora (sin tener que iterar a través de todas las salas). Las personas viven en la clase Hotel porque me gustaría poder buscar una Persona específica sin buscar en las habitaciones.

¿Este diseño es malo? ¿Hay alguna otra forma de lograrlo?

Gracias.

Respuesta

4

La mutua dependencia problema entre las clases, en sentido estricto, se pueden resolver mediante el uso de las interfaces (clases abstractas, si su lenguaje es, por ejemplo, C++ o Python) IRoom y IPerson; en pseudocódigo

interface IPerson 
    IRoom getRoom() 
    // etc 

interface IRoom 
    iter<IPerson> iterPerson() 
    // etc 

esto hace que sólo las interfaces dependientes mutuamente el uno al otro - las actuales implementaciones de las interfaces sólo necesitan depender de las interfaces.

Esto también le da mucho margen de maniobra en términos de implementación, si desea evitar los círculos de referencia circulares (que pueden ser una molestia, p.en CPython reduciendo la velocidad de las recolecciones de basura): podría utilizar referencias débiles, una base de datos relacional subyacente con una tabla típica de "relación de uno a muchos", etc. Y para el primer prototipo simple puede usar lo más simple en el idioma elegido (probablemente simples, y alas necesariamente circulares, referencias [[punteros, en C++]] con un Person refiriéndose a un Room y un Room a un list<Person>).

+1

Veo "dependencia mutua" es la palabra que estaba buscando. Para el registro, estoy escribiendo esto en Java. El enfoque de interfaz parece interesante, pero no hace que la solución sea mucho más diferente, pero entiendo su punto. Gracias por tu comentario. –

+2

@Kasper, el punto es que no hay ningún problema real con tener dependencias en _interfaces_ (incluidas las mutuas); en su mayoría son dependencias del software _concrete_ las que realmente desea evitar (por ejemplo, en el caso de "bucles"). La libertad de comenzar con una implementación rápida y sucia y cambiar a una más sólida también acelera la creación de prototipos de software y la iteración en su evolución y mantenimiento. –

9

No me gusta. Un hotel contiene habitaciones y las habitaciones contienen personas. Las personas no tienen habitaciones, ellas les pertenecen.

No tiene que iterar necesariamente para obtener el conteo de sus invitados. Podrías mantener un conteo continuo ($ Hotel-> total_guests) y modificarlo a medida que cambie.

+0

Entiendo lo que dices, que hay un error en mi lógica, ¡gracias por señalarlo! Sin embargo, pensé que un HashMap que contenga el nombre de usuario y el objeto Persona sería mucho más rápido para buscar un usuario que iterar a través de Salas. –

+4

Agradezco profundamente su deseo por milisegundos, ya que comparto esa pasión, pero el OOP increíble se trata de una lectura y escritura de código más rápida/limpia, no un tiempo de ejecución más rápido. Yo sugeriría que lo intentes de ambas maneras y lo cronometraras: las diferencias probablemente no serán tan grandes como crees. (¡Si lo hace, publique sus resultados por nosotros!) –

+0

¡Me atrapó! Ese comentario sobre la lujuria por milisegundos es perfecto. Me has dado algo en qué pensar, gracias :) –

1

En un sistema más grande, sería malo, pero debido a lo que entiendo de sus aplicaciones, estas tres clases solo se usan juntas, no es un gran problema. Solo asegúrese de nombrar las variables de miembro de la persona de una manera que indique que contiene una referencia a una sala, en lugar de una instancia.

Además, a menos que sea por motivos de rendimiento (por ejemplo, tendrá un gran número de habitaciones), probablemente sería más limpio crear una propiedad o getter que recorra las salas y recopile las personas, en lugar de almacenarlas en caché el hotel.

+0

Para que conste en acta, acepto que almacenarlas en caché como propiedad del hotel probablemente no sea la mejor manera de hacerlo. Personalmente, repetiría también;) –

+0

¿Cómo denominarías las variables miembro en Persona, por lo que sería más como una referencia? Digamos que tengo una gran cantidad de usuarios y que necesito buscar un solo usuario. Cúal seria la mejor manera? Sé que conservo información redundante en las referencias. Estas clases solo se usan juntas (Hay un par de más, pero no muchas). –

0

La dependencia mutua no está mal por sí misma. A veces, el uso de datos lo requiere.

Lo pienso de una manera diferente. Será más fácil mantener un código que tenga menos relaciones en general, dependencia mutua o no. Solo mantenlo lo más simple posible. El único truco adicional con su situación es a veces que hay un problema de verificación y huevo, durante la creación y eliminación de secuencias. Tienes más enlaces para reservar.

Si está preguntando si necesita una lista de personas en un hotel en este caso, creo que hay dos respuestas. Comenzaría teniendo sus objetos (en la memoria) suministrando estas relaciones, pero NO necesita una tabla adicional de unión entre personas y hoteles en la base de datos. Si está utilizando Hibernate, generará automáticamente una unión eficiente para usted si lo solicita a las personas en un hotel (se unirá a los hoteles en rooms.hotel_id para usted).

Cuestiones relacionadas