2011-08-29 13 views
8

A menudo encuentro la necesidad de diseñar objetos con la funcionalidad configurable.configuración de java/diseño de paso de parámetro

Para ejemplificar, asuma que estoy creando un DateIterator. La (s) opción (es) configurable (s) pueden ser si iterar el intervalo cerrado [start, end] o el intervalo abierto [start, end).


  • (1) El, en mi opinión, una solución poco elegante - limitado a una sola opción de configuración verdadero/falso
new DateIterator(boolean openInterval); 
  • (2) El typesafe forma de enumeración - típicamente una poco voluminoso
new DateIterator(Interval.OPEN_END); 
  • (3) El unconv entional intento - agradable, pero no demasiado sencillo
new DateIterator().openEnd(); 
  • (4) El enfoque de la herencia - a menudo pasado por la ingeniería
new OpenEndedDateIterator(); 

A esto se agrega algunas alternativas que considero inferiores , como la configuración basada en enteros new DateIterator(Interval.OPEN_END); o la configuración basada en la propiedad.

¿Hay algún otro enfoque? ¿Qué enfoque prefieres?

Respuesta

6

yo diría que el Builder tiene sentido aquí:

DateIterator di = 
    DateIterator.builder() 
       .withStartDate(new Date()) 
       .withOpenEnd() 
       .build(); 

De esa manera su DateIterator real puede ser inmutable, mientras que el constructor devuelto por DateIterator.builder() hace el trabajo de configuración.

1

Si bien no hay una buena respuesta, y es en gran medida una cuestión de gusto, hago seguir la siguiente regla general, con gran espacio para las excepciones para evitar el exceso de ingeniería:

  1. Si la única configuración que tiene es un "parámetro", toma un conjunto fijo y altera el comportamiento (como en su ejemplo), vaya con las subclases. Si bien puede estar sobre-diseñado, si muchos métodos en su clase comienzan con un "if (this.parameter == x) ... else if (this.parameter == y) ..." hará que el código sea ilegible.
  2. Si su parámetro no es un conjunto fijo, sino una cadena o número, y NECESITA que la clase funcione correctamente, póngalo en el constructor; si no es obligatorio, me gusta el número de solución (3), el intento no convencional:)
  3. Si tiene más de un parámetro en un conjunto fijo (como START_OPEN_ENDED y STOP_OPEN_ENDED), crear subclases puede significar crear una subclase para cada permutación. En ese caso considere la encapsulación. Por ejemplo (no lo haría en este caso específico probablemente, pero es un buen ejemplo), cree una clase DateComparator, con una subclase para final abierto, y encapsule un DateComparator para el inicio y uno para el final, teniendo solo un DateIterator.

De nuevo, esta es la regla de oro que uso, de ninguna manera es obligatoria, y a menudo me encuentro que no los respeto al pie de la letra.

Cuestiones relacionadas