sobre que puede programacion principales poo orientada objetos industria hacer ejemplos donde con aplicaciones aplica design oop

design - principales - que se puede hacer con programacion orientada a objetos



¿Es malo practicar OOP tener objetos que se refieran entre sí? (13)

Tengo un objeto para cada personaje. ¿Es malo para cada uno de esos objetos de carácter tener una matriz de todos los otros objetos de carácter para realizar estas interacciones? ¿Hay una mejor manera de hacer esto?

La interfaz en una palabra es la respuesta para esto. De lo contrario, terminarás en un lío actualizando todas las referencias en un punto del tiempo.

Disculpe mi noobness. Estoy haciendo un juego en el que varios personajes tienen relaciones entre ellos y necesitan poder interactuar entre ellos y almacenar algunos datos de relación sobre cómo se sienten el uno con el otro.

Tengo un objeto para cada personaje. ¿Es malo para cada uno de esos objetos de carácter tener una matriz de todos los otros objetos de carácter para realizar estas interacciones? ¿Hay una mejor manera de hacer esto?

EDITAR para responder preguntas: Mi idioma es C #.

Lo que estaba pensando es que la clase de configuración haría una matriz de todos los caracteres y luego pasaría esa matriz como un parámetro al constructor de cada personaje.

En cuanto a los tipos de relaciones, hay cinco personajes, pero me gustaría hacerlo extensible en caso de que se agreguen más tarde. Los personajes tienen conversaciones entre ellos. Lo que dicen se ve afectado por su estado de ánimo y cómo se sienten sobre el personaje. Además, lo que otro personaje les dice afecta su estado de ánimo y cómo se sienten con respecto al personaje. Pueden tener conversaciones uno a uno o hablar en grupos, por lo que el personaje A podría decir algo al personaje B, C, D, E y F a la vez.

Por cierto, estoy aprendiendo mucho de este hilo. ¡Muchísimas gracias a todos!


Tengo un objeto para cada personaje. ¿Es malo para cada uno de esos objetos de carácter tener una matriz de todos los otros objetos de carácter para realizar estas interacciones? ¿Hay una mejor manera de hacer esto?

Realmente depende de las interacciones entre los personajes, que se dividen en dos categorías:

1) Acciones - A muta un estado en B

En este caso, probablemente escribirías algo como:

class Player { Player[] players; ... public void ExchangeItem(Item item, string playerName) { Player target = players.First(x => x.Name = playerName); target.Items.Add(item); this.Items.Remove(item); } }

2) Reacciones - B escucha un cambio de estado en A

No escribirías:

public class Player { Player[] players; public void Die() { foreach(Player p in players) p.Mourn(); } }

Se trata de responsabilidad única. Los objetos solo deberían conocer y preocuparse por su propio estado y comportamiento, no deberían conocer a los demás. En este caso, el método Die parece saber demasiado sobre la forma en que otros jugadores lo manejan.

En cambio, puede volver a escribirlo como un evento:

class Player { public event EventHandler PlayerDied; public void Die() { if (PlayerDied != null) PlayerDied(this, EventArgs.Empty); } }

Otros objetos pueden engancharse al evento PlayerDied y reaccionar de la manera que deseen.


El problema que describes puede ser modelado de forma natural como un gráfico, donde los nodos son tus personajes del juego y las relaciones entre ellos son los bordes del gráfico. Los bordes pueden ser dirigidos o no dirigidos dependiendo de la naturaleza de las relaciones entre los personajes del juego. Podría considerar usar una base de datos de gráficos como Neo4j si le conviene a su problema.

En cuanto a mantener las referencias, creo que es importante tener en cuenta el principio de diseño de tener un acoplamiento flojo lo más posible en sus diseños.


En el diseño OO, un enfoque común para un problema como este es el Patrón del Mediador

Un problema con el enfoque que describe es ¿cómo se actualizarán las relaciones? Por ejemplo, si el personaje A se elimina del juego, ¿cómo se actualizan otros personajes para eliminar el personaje A de sus relaciones?

Sugeriría tener otro Objeto que maneje las relaciones. Este objeto puede ser responsable de actualizar las relaciones. Usando el mismo ejemplo, cuando se elimina el carácter A, el gestor de relaciones elimina todas las relaciones que involucran a ese personaje.


En general, es bueno evitar referencias innecesarias entre objetos, pero la determinación de lo innecesario es muy subjetiva y depende del problema.

Si cada personaje tiene un identificador único (por ejemplo, un nombre único), simplemente podría almacenar, para cada personaje, una colección de identificadores de caracteres y la "sensación" sobre ese personaje. Usando algún otro tipo de CharacterManager, puedes buscar un personaje basado en el identificador.

Otra opción (puede ser preferible si las opiniones son solo una faceta menor del juego) es tener una clase separada de "RelationshipManager", que pueda responder consultas tales como "¿Cómo se siente el carácter X sobre el personaje Y"? Este podría ser un mejor diseño, ya que esa responsabilidad se gestiona por separado de su personaje principal. Este administrador podría hacer referencia directa a los caracteres, o podría usar los identificadores.


Me he dado cuenta con el diseño orientado a objetos que si suena lógico para alguien que no codifica, entonces probablemente seas bueno.

Digamos que tienes un taxi ... el taxi debería saber para qué compañía trabaja, ¿verdad?

¿O un niño debería saber quién es el padre correcto?

Obviamente, mantenlo dentro de lo razonable.


No es una mala práctica que los objetos retengan referencias entre ellos: no es raro que los nodos en un gráfico de árbol guarden una referencia a sus nodos secundarios y que los nodos secundarios mantengan una referencia a su nodo padre.

Una cosa que podría convertirse en un problema es lo que usted describe como cada personaje manteniendo referencias a todos los demás personajes. Esa es una matriz NxN, y explotará el uso de tu memoria a medida que aumente el número de caracteres.

Una alternativa para almacenar una lista de todos los objetos de carácter en cada objeto de carácter podría ser configurar una lista asociativa o diccionario donde está la clave (carácter 1, carácter 2) y el contenido es la relación. Esta lista podría ser global y almacenar todas las relaciones entre todos los personajes. La ventaja aquí es que crece linealmente con el número de relaciones reales, no exponencialmente con la cantidad de caracteres en el sistema.


No necesariamente, pero depende de cómo esté definiendo y haciendo referencia a las relaciones. Por ejemplo, ¿qué sucede si quieres reemplazar un objeto de personaje por otro? ¿Tendrá que ir a actualizar todos los objetos que hacen referencia a ese?


No, esto no es una mala práctica en absoluto. Obviamente, puedes hacerlo de tal manera que sea difícil de mantener o comprender, pero no hay nada intrínsecamente incorrecto en las referencias entre objetos.

Aunque recomendaría cualquier tipo de colección que ofrezca tu idioma en lugar de una matriz, no hay nada de malo en lo que propones.


Puedo ver que este es un artículo antiguo, pero puedo ver que algunas personas dicen que no hay nada malo en la pareja bidireccional (es decir, dos objetos que se refieren entre sí). La pareja bidireccional, como las referencias circulares, presentan problemas, y si puede diseñar su software para evitar su uso, hace que el código sea más fácil de mantener y menos propenso a fallar.

Además, el software de desacoplamiento que está altamente acoplado requiere mucho esfuerzo, por lo que si existe la necesidad de este tipo de acoplamiento, lo mejor es hacerlo de corta duración.

Ahora, el siguiente ejemplo de C ++ parece un poco loco, y es una pieza de código acoplada bidireccionalmente que fallará dentro del destructor, pero en realidad este tipo de problema existe en el código heredado con millones de líneas de código, donde se vuelve cada vez más Es difícil hacer un seguimiento del tiempo de vida de sus punteros y referencias.

class B; class A { public: A(B* b = nullptr) : m_b(b) { } ~A() { delete m_b; } void setB(B* b) { delete m_b; m_b = b; } private: B* m_b; }; class B { public: B(A* a = nullptr) : m_a(a) { } ~B() { delete m_a; } void setA(A* a) { delete m_a; m_a = a; } private: A* m_a; }; int main() { A a(new B()); B b; b.setA(&a); }

Cuando se trata de lenguajes recolectados, estos se convierten en referencias, y aunque existe una referencia, los objetos dentro de sistemas altamente acoplados vivirán mucho tiempo, lo que puede llevar a un uso excesivo de memoria, los manejadores de archivos se dejan abiertos durante mucho tiempo y muchos otros tipos de problemas

Entonces, ¿es una mala práctica tener dos objetos que se refieran entre sí? Sí o no, dependiendo del problema que intente resolver, pero si puede encontrar una forma de resolver un problema de manera sensata sin el acoplamiento, va a ahorrar mucho dolor más adelante.

También recuerde que para cada combinación de clases, eso significa más posibilidades de que un cambio en una clase rompa la funcionalidad en otra clase.

También hay algo que algunas universidades están enseñando, conocido como: alta cohesión y bajo acoplamiento

Para su ejemplo de personajes, implicará el manejo de situaciones a medida que su software evolucione, como mantener múltiples listas actualizadas si se agregan o eliminan personas, notificar a cualquier persona que tenga la misma persona en su lista de cambios, etc. La sugerencia de administrarlos separadamente por una de las otras respuestas no es una mala idea, y podría tener una clase de Persona y Personas, por ejemplo, con una interfaz en Personas con métodos como People.chat (person1, person2), etc. Esto hará baje a su diseño y lo que está tratando de lograr.

Es un tema que genera muchos debates, y muchas voces a veces, pero solo me enfoco en las opciones reutilizables, fáciles de probar (pruebas unitarias, pruebas de componentes, etc.) y difíciles de romper (es un tema demasiado grande para comentar SO). Son temas en los que todos son expertos y en los que nadie puede ponerse de acuerdo, por lo que su pregunta es realmente subjetiva, y la experiencia le dará la respuesta que busca.


Si la relación es duradera, tendría sentido hacerlo. No sé cómo funciona tu juego, pero parece poco probable que todos los personajes puedan interactuar entre sí en cualquier momento. En situaciones más temporales, es posible que desee implementar una especie de "visita", donde el líder del juego distribuye referencias a las partes que se encuentran.

También puede optar por revelar diferentes niveles de detalles mediante el uso de interfaces: si un Ghoul encuentra a un Mago, podría obtener una referencia Humana al Mago, ya que el Ghoul no trata a diferentes tipos de humanos de manera diferente. Al utilizar esta ''base de necesidad de saber'', usted reduce la cantidad de acoplamiento en su código y puede reutilizar mejor el código: no necesita escribir ningún código nuevo si un Ghoul visita a un Agricultor.


Un enfoque, cuando tienes una docena de objetos diferentes que se referencian entre sí, es poner algo en el medio, un mediador, que contiene todas las referencias. Todos luego hacen referencia a otros personajes a través del mediador. Reduce su recuento de referencias de n ^ 2 a 2n; todos conocen al mediador y conocen a todos.


Una alternativa que podría considerar es la idea de un centro de mensajes. Usted tiene un objeto central cuyo trabajo es enviar mensajes a otros objetos. Otros objetos expresan su interés en recibir mensajes registrándose con el objeto de notificación. El beneficio de este enfoque es que desacopla objetos entre sí, y también evita problemas de memoria relacionados con la retención de referencia cíclica. Una desventaja puede ser un cuello de botella en el objeto de notificación si está enviando una tonelada de mensajes.