2011-05-30 20 views
9

¿Debe una clase que es una estrategia de "pandilla de cuatro" ser completamente apátrida (es decir, sin campos) o puede contener un estado inmutable (es decir, campos finales)?¿Debería el patrón de estrategia ser apátrida?

+0

¿por qué el patrón de estrategia requiere estado? Su función es devolver alguna funcionalidad 'conectable' –

Respuesta

4

No, ¿por qué debería ser apátrida? La estrategia podría ser cualquier cosa, simplemente representa alguna unidad de funcionalidad conectable en tiempo de ejecución que le permite extender la modificación del comportamiento de la clase consumidora. No hay nada, hasta donde yo sé, que sugiera el requisito de la apatridia, ni la inmutabilidad.

+0

¿Está diciendo que una estrategia es simplemente un delegado, entonces? – murungu

+1

Ahora estamos en la semántica. Sí, en el sentido más amplio del significado de la palabra "delegado", no en el sentido concreto de .NET. – MalcomTucker

3

La intención del patrón de estrategia es trabajar en el método de estrategia suministrado directamente en el alcance local del método. La clase de estrategia en sí puede, por supuesto, contener algunos campos siempre que sea necesario, pero los argumentos del método no deben asignarse de ninguna manera a esos campos, ya que puede presentar problemas de seguridad de subprocesos ya que la clase de estrategia se puede reutilizar más de una vez.

1

Sí, ya que este es el algoritmo más elegido. Algoritmo concreto puede tener estado, pero no el selector.

Por cierto en esta estrategia no tenemos una clase. ¿A qué clase concreta te refieres? ¿En qué papel?

3

Apatridia se refiere al hecho de que no se conservan datos entre ejecuciones de una estrategia; es decir, si ejecuta la misma estrategia dos veces, nada de la ejecución anterior de la estrategia se mantendría. Esto es beneficioso porque le ahorra el problema de tener que "reiniciar" las implementaciones de su estrategia cuando sea necesario.

Tenga en cuenta que en la descripción de la implementación del patrón de estrategia hacen referencia a un contexto (@ página 317 en mi libro) que contiene los datos que la estrategia necesita para ejecutar. Todo el 'estado' requerido por las implementaciones debería ir probablemente en estos objetos de contexto.

Esto significa que las implementaciones de la estrategia en sí son apátridas, pero el patrón como un todo tiene estado ya que los datos requeridos se pasan en un contexto.

Por ejemplo, si tiene implementaciones de estrategia para operaciones matemáticas, existen al menos 2 formas de hacerlo. El primero sería establecer arg1 y arg2 (y 3, y 4 ...) en las implementaciones de estrategia cuando las construyes. Luego, cuando ejecute la implementación, tomará sus campos y realizará la operación. El problema es que si ejecuta nuevamente la misma implementación, debe restablecer todos sus campos (o crear una nueva implementación).

La segunda forma sería crear un contexto que contenga todos los argumentos. Las implementaciones de estrategias tomarían los valores que necesita fuera del contexto. Luego, podría reutilizar cada instancia de la implementación de su estrategia, simplemente pasando un nuevo contexto cada vez. No se preocupe por volver a crear nuevas instancias de las implementaciones u olvidar reiniciar la instancia de implementación. Por supuesto, aún necesita administrar los contextos correctamente.

16

Una clase de estrategia encapsula una acción, nada. Así que, aunque podrías si realmente tuvieras que hacerlo, no tendría mucho sentido mantener el estado. Piénselo como un verbo, no como un sustantivo. O al menos como sustantivo que describe una acción. Por otro lado, siempre se puede parametrizar la estrategia y pasarle el estado del objeto del cliente mediante una llamada a un método o similar.

Además, si una clase es stateless o statefull realmente no depende de la palabra clave final en sus campos. Ejemplos:

  • Cuando se usa en los objetos final solo significa que la referencia a un objeto no se puede cambiar.Todavía puede cambiar el contenido de ese objeto, al igual que sus campos. En ese caso, su clase es statefull aunque su campo es final.
  • Si el campo es realmente una constante, para la mayoría de los propósitos puede considerarlo sin estado. Por ejemplo, puede declarar un campo private static final y luego asegurarse de que nunca hace nada para cambiar el estado del objeto al que se hace referencia.

EDITAR: Tratemos de distinguir entre los parámetros de la estrategia en sí y los parámetros de una ejecución particular de esa estrategia. Si la clase de estrategia es apátrida, no tiene sentido tener más de una instancia de esa clase, lo que hace que el objeto, no la clase, represente la acción en sí y una ejecución de método represente una ejecución particular de esa estrategia.

Ahora, si tenemos un parámetro de la estrategia en sí, solo tiene sentido que el parámetro tenga el mismo valor para todas las ejecuciones de esa estrategia. Por lo tanto, se puede colocar en una llamada a método constante que devuelve una constante (si no queremos cosas estáticas), o incluso codificada. Como se explicó anteriormente, eso se puede implementar de forma apátrida.

Por otro lado, si el parámetro describe una ejecución particular de la estrategia, simplemente páselo como un parámetro al método. Hará.

Nota adicional: hay una buena razón para usar objetos de acción con 'adverbios' empaquetados en su estado si queremos, por ejemplo, tener algún tipo de acción cola de ejecución con retraso, programación ... Hay un patrón para eso también - Comando.

+0

No estoy en desacuerdo con usted (por el contrario, de hecho ... ¡+1!), Pero creo que es significativo observar que incluso los verbos/acciones tienen descriptores. Si estás pensando en un objeto con estado como sustantivo, entonces esencialmente tiene adjetivos. Del mismo modo, incluso si su clase de estrategia encapsula una acción o un verbo, puede utilizar hipotéticamente "adverbios" para detallar los detalles de esa acción. – JMTyler

+0

@JMTyler: Nunca pensé en los parámetros de acción como adverbios. Gracias por esa analogía! Ver mi edición para la respuesta. –

+0

¡Genial! No he oído hablar del patrón de Comando antes, ¡gracias por señalarlo! – JMTyler

Cuestiones relacionadas