¿Es la herencia de contexto, como se muestra en el ejemplo de Duck de Head First Design Patterns, irrelevante para el patrón de estrategia?

10

En Head First Design Patterns , enseña el patrón de estrategia mediante el uso de un ejemplo de Duck en el que a diferentes subclases de Duck se les puede asignar un comportamiento particular en tiempo de ejecución. Según tengo entendido, el propósito del patrón de estrategia es cambiar el comportamiento de un solo objeto en tiempo de ejecución, pero están utilizando la herencia de Duck para cambiar el comportamiento de varios tipos de Duck.

Patrón de estrategia

¿Relevancia?

¿La herencia de contexto de Duck es irrelevante para el patrón de estrategia o la variación de los tipos de Duck y la variación de sus comportamientos son una buena razón para emplear el patrón de estrategia? ¿Las situaciones en las que necesita variar constituyen una buena razón para usar el patrón de estrategia? ¿Por qué incluirían esto como ejemplo de patrón de estrategia?

Un ejemplo mas simple

¿Podría simplificar aún más este ejemplo simplemente teniendo una clase Duck (sin clases derivadas)? Luego, al implementar un objeto de pato, se le pueden asignar diferentes comportamientos en función de ciertas circunstancias que no dependen de su propio tipo de objeto. Por ejemplo: FlyBehavior cambia según el clima o QuackBehavior cambia según la hora del día o qué tan hambriento está un pato. Me doy cuenta de que esto resolvería un problema diferente al que está en el libro, pero lo que estoy buscando es un ejemplo de patrón de estrategia relevante al que recurrir.

¿Mi ejemplo anterior constituiría también el patrón estratégico?

Editar:

Tuve éxito en encontrar 2 ejemplos de patrones de estrategia más simples que se adhieren más estrictamente a ser solo patrones de estrategia sin herencia de contexto: Hunter.java y solver.py .

Korey Hinton
fuente

Respuestas:

7

Sí, creo que estás en el camino correcto. La clase que usa el patrón de estrategia no tiene que ser una subclase. El patrón de estrategia es una alternativa a la herencia para la reutilización de código. Esto vuelve a la comparación aún más amplia de herencia versus composición.

Desde Patrones de diseño: Elementos de OOP reutilizable , usaría un patrón de estrategia

  • Evite una explosión de subclases (debido a combinaciones de comportamientos)
  • Si necesita cambiar el comportamiento en tiempo de ejecución

Si utilizó la herencia para implementar comportamientos Quack y Fly, resultaría con todas estas subclases para representar todas las combinaciones de comportamientos.

  • FlyableQuackableDuck
  • FlyableSqeakableDuck
  • FlyableMuteDuck
  • NoFlyQuackableDuck
  • NoFlySqueakableDuck
  • NoFlyMuteDuck

Tener tantas subclases hace que sea más difícil de mantener, razón por la cual se prefiere el patrón de estrategia en este caso. Solo necesita dos propiedades que encapsulan Flyability y Quackability y puede mezclarlas y combinarlas sin crear nuevas clases.

También mencionó el beneficio de tiempo de ejecución de si el clima cambiara la propiedad Fly del pato podría reemplazarse con un objeto NoFly debido a las condiciones.

Esto es consistente con los consejos para favorecer la composición sobre la herencia cuando sea posible.

Despertar
fuente
1

¿Podría simplificar aún más este ejemplo simplemente teniendo una clase Duck (sin clases derivadas)? Luego, al implementar un objeto de pato, se le pueden asignar diferentes comportamientos en función de ciertas circunstancias que no dependen de su propio tipo de objeto.

Ciertamente. Para inspirarse, eche un vistazo a Head First Object-Oriented Analysis and Design . Hay una "Rick's Guitars" que muestra una explosión de subclases de instrumentos (musicales) . Para remediar esto, todo ese comportamiento variable está envuelto en una clase de "especificación", observando el principio de encapsular lo que varía .

Fábrica abstracta: construcción basada en el contexto

Aquí está el patrón . Por cierto, tenga en cuenta que utiliza la estrategia en sí.

Centrándose en el concepto, no en la implementación ... Es posible que tenga una "WeatherFactory" que construya objetos de especificación basados ​​en condiciones soleadas o lluviosas, etc.

Podrías tener "fábricas de fábricas" para construir esas cosas "NoFlyInFogQuackableMallard". Y de hecho, de esto se trata el patrón Abstract Factory. Entonces, tal vez una DuckFactory para hacer tipos de patos generales, luego una WeatherFactory para darle un comportamiento de niebla de clima específico de tipo de pato.

radarbob
fuente