2010-09-30 20 views
7

Si estoy programando un juego en el que hay un trabajador que corta madera (de árboles), ¿dónde pondría el método "cortar madera" en la clase de trabajadores o en la clase de árbol?Problema de diseño orientado a objetos

EDIT: El primer ejemplo que leí en OOD fue sobre un círculo (una clase llamada círculo) que tiene un método llamado "calcular área". Ahora, efectivamente, un círculo no calcula su propia área. La única forma de pensar es que el área de cálculo es una operación relevante para el círculo (una operación realizada en el círculo)

Por lo tanto, el método de corte es relevante tanto para el trabajador como para el árbol.

+1

¿quién corta la madera? – Cristian

+0

¡Quién cortó el queso! – Secko

+0

¿Un círculo no calcula su propia área? Hmmm. Creo que puede haber leído mal el ejemplo: hacer algo para lo que no se necesita ningún otro objeto, y para el cual la clase tiene más conocimiento (es decir, el radio), es EXACTAMENTE lo que debería ir en una clase. ¿Dónde se puede debatir es cosas como circle.draw (ScreenObject) - debe una clase independiente saber sobre los detalles de un sistema de gráficos en particular? –

Respuesta

4

Pregúntese: ¿Los trabajadores cortan madera o cortan árboles?

+2

Pero el árbol se corta , podría ser CutMe (Worker whichWorker), que podría decir si el árbol tenía suficiente madera para cortar. - Pero sí, el trabajador debería cortar el árbol – PostMan

+1

Si el estado interno del árbol necesita saber quién lo cortó, y si se cortó o no, entonces el método de corte de los trabajadores llamará a los métodos que expone el Árbol para actualizar su estado. – codelark

+0

¿Y el trabajador extiende WoodChuck, o viceversa? : p –

4

Básicamente lo respondió en su pregunta: "un trabajador que corta madera". Deberías ponerlo en la clase trabajadora.

+0

¿Qué pasa si luego quieres que el trabajador también vaya a trabajar, hornee pan, arregle autos, fume marihuana, lo que sea? Ese trabajador se convertirá en un objeto divino. –

+0

@Mark H: No te entiendo muy bien aquí. Un objeto de dios es un objeto que tiene demasiada responsabilidad. Este trabajador de la madera nunca arreglará autos ni horneará pan. El trabajador probablemente tendrá más métodos, por ejemplo, takePause(), pero siempre que estén relacionados con el objetivo principal del trabajador, no hay problema con eso. –

+0

Has asumido que el trabajador nunca arreglará los automóviles, pero no lo sabes, o no sabes si cambiará en el futuro. Si la responsabilidad del trabajador cambia, se hinchará su objeto. Sin embargo, no importa si la responsabilidad de un trabajador cambia, cortar un árbol siempre actuará sobre un árbol y, por lo tanto, debe ser parte del árbol. Realmente no hay muchas posibilidades de que un árbol cambie las responsabilidades de todos modos. –

0

Dado que un solo trabajador puede cortar más de un árbol, parece más probable que desee poner cutWood() en la clase de trabajador.

3

crear un método

cut(Material m)

para el trabajador para el suplemento objeto orientación hacia.

+5

A menos que el trabajador corte alguna otra cosa, este sería un buen ejemplo de sobre-abstracción ;-) – codelark

+1

// TODO: insertar la broma EmoWorker – STW

+0

@codelark Si la descripción decía leñador, estoy de acuerdo, pero un trabajador puede significar cualquier cosa/sarcasmo – Hans

1

Puede tener un método cutWood en la clase de trabajador y un método cutted en la clase de árbol. Obviamente, worker.cutWood llama al tree.cutted, lo que puede devolver la cantidad de madera cosechada. tree.cutted haría todas las cosas necesarias para que el árbol muera.

Si considera las llamadas de método como "mensajes enviados de un objeto a otro", tiene mucho más sentido decir que "el jugador envía un mensaje de 'cortar madera' al trabajador que a su vez envía un mensaje de 'corte' al árbol ".

2

¿tiene que modificar el árbol mientras se corta?

¿tiene que modificar al trabajador mientras corta un árbol?

me imagino que terminarías con un servicio WoodCutting, que controla el evento posiblemente modificaciones a ambos, o llamando a su vez worker.cutWood() Y tree.woodCut()

ahah qué pregunta;)

8

no lo hago ver cualquier cohesión para tener un método de corte de madera en el trabajador. El corte se realiza en el árbol y, por lo tanto, debe formar parte de la clase de árbol. Presumiblemente, cortar la madera también implicará cambiar algún estado interno de la clase de madera.

Un trabajador debe llamar al el método de corte en cualquier árbol que desee, en lugar de que el árbol le diga al trabajador que debe cortarlo. Si desea abstraer esto como Hans ha insinuado, podría hacer una interfaz ICuttable para el método Cut, y hacer que su árbol lo implemente.

Considere algo con lo que esté familiarizado, un String. Cuando quiere cortar una cuerda (división), no define un método splitString en cada objeto que vaya a hacer esto.Cualquiera que sea el objeto que decida dividir la cadena, ocurre lo mismo, y generalmente necesitará conocer las partes internas del objeto objetivo (la cadena) para poder hacerlo. Muchos otros objetos simplemente llaman al método de división de la cadena. El objeto de cadena tiene una alta cohesión, porque sus métodos contribuyen a una tarea común: manipular cadenas.

No veo cómo el corte de la madera contribuye mucho al objeto del trabajador en sí.

0

¿El método cut() no va en el objeto Saw?

Más en serio, pienso en el objetivo de la llamada al método como el "sujeto", el método en sí mismo como un "verbo" y sus parámetros (si el verbo es transitivo) como "objetos directos". Entonces, en este ejemplo, sería worker.cut(tree).

2

Suena como un candidato para el patrón de estrategia para mí. Es posible que necesite una clase abstracta WorkerAction con un método performAction. Luego, las subclases de la clase WorkerAction implementarán los detalles, como cortar un árbol, excavar en busca de oro y otras acciones de los trabajadores. Entonces, la subclase conoce los detalles del árbol y puede invocar los métodos necesarios en el árbol para afectar al árbol a medida que se corta.

La clase de trabajador solo necesita una referencia a una instancia de una WorkerAction concreta a la que llama performAction(). El trabajador no conoce los detalles del Árbol o del Oro, etc. De esta manera el trabajador puede realizar la acción, pero usted no está limitando al trabajador a una sola acción. De hecho, ya no necesita modificar la clase de trabajadores si desea que su trabajador haga más acciones en el futuro.

+0

Acepto que este es el enfoque a seguir, pero mi opinión diferiría sobre las responsabilidades de las subclases de WorkerAction. Digamos que dada una clase TreeCuttingAction, simplemente me gustaría tener su método performAction llamar a un método .cut del árbol (por las razones dadas en mi respuesta anterior) - TreeCuttingAction no necesariamente conoce los detalles del árbol que está cortando, solo que él está cortándolo. –

+0

@Mark H Hmm. Parece que simplemente empujé la decisión a un nivel diferente de abstracción aquí sin responder realmente la pregunta. Aunque creo que estoy de acuerdo con tu respuesta en que los detalles de cortar el árbol deberían residir en el Árbol. Entonces sí. El performAction solo debe llamar a cut() en el Árbol. –

0

Esta pregunta solo puede ser realmente respondida si explica lo que cutWood hace.

Si cutWood sólo afecta el estado de un Tree entonces pertenece en Tree por ejemplo,

public void cutWood() { 
    this.height = 0; 
} 

En el caso de calculateArea sólo necesita el radio de un círculo (suponiendo pi es constante) para hacer este cálculo - nada más. Es por eso que pertenece a Circle.

Deja de tratar de modelar el mundo real muy de cerca y mira lo que tu método realmente necesita hacer.

1

El diseño de objetos tiene que ver con la asignación de responsabilidades a sus clases. Eso significa que realmente no hay una buena respuesta a esta pregunta. Como todo depende de cómo usted modelo las responsabilidades en su diseño. (Ver: Larman)

Así que necesidad de decidir qué objeto/clase es responsable de qué. Esto lo llevará a corregir las respuestas a la pregunta sobre dónde colocar qué tipo de métodos.

Por lo tanto, pregúntese a usted mismo preguntas como: ¿el trabajador decide por su cuenta cortar madera? Si lo hace, probablemente no necesite que lo ordenen, por lo que no necesitará un método cut (tree). Pero si el usuario puede ordenarle que haga eso, necesitará un método de corte (árbol) . Otro ejemplo: ¿el árbol tiene que saber que está cortado? Bueno, si un árbol cortado conduce a su eliminación del bosque, es posible que no tenga la necesidad de un método tree.cut().Pero si asigna al árbol la responsabilidad de (re) dibujarse durante el corte, es posible que necesite un método tree.cut(). Incluso se puede modelar el árbol con un ancho y que puede calcular cuántos cortes se necesitan antes de colapsar.

0

Este es un tema interesante. Pensé en un escenario similar a veces a veces. Creo que un buen camino a seguir es poner el método en la clase con la mayor cohesión. Por lo tanto, la clase Tree sería la primera opción. Por otro lado, si intentas hacer coincidir un modelo del mundo real, diría que la clase Trabajadora tiene que poder realizar algún tipo de acciones que incluya cortar un Árbol. A menudo me encuentro en este tipo de situaciones y me pregunto dónde está el lugar correcto para poner este método. Otro enfoque sería una clase que sepa sobre el trabajador y el árbol, y por lo tanto maneja el corte del árbol del mecantismo. De esta forma, las dos clases (árbol, trabajador) no sabrían nada al respecto.

Cuestiones relacionadas