2011-05-17 19 views
6

Escribo un pequeño servidor web y toma un archivo de configuración con todo tipo de opciones diferentes: cuántos hilos ejecutar, qué clase trata cada extensión de archivo, qué archivo mostrar por defecto y así sucesivamente. Para representar esto, estoy analizando el archivo de configuración en un objeto Configuration que contiene todas estas configuraciones, y la clase principal contiene este objeto.
Sin embargo, los datos de configuración son necesarios en casi todos los niveles del servidor: clases dentro de las clases dentro de las clases ...Haciendo que la configuración esté disponible para todas las clases

Mi pregunta es, ¿cuál es la mejor práctica para usar aquí? ¿Debería dar la configuración como parámetro para muchas clases y pasarla de un lado a otro? ¿Debería convertirlo en singleton? ¿Hay alguna otra solución que no veo?

Respuesta

0

¡Definitivamente convertiría la clase del titular de configuración en Singleton! Soy el caso de uso clásico para una instancia de Singleton.

1

Convertirlo en singleton parece ser una solución razonable. Creo que sería un error pasar la configuración como un parámetro para otros constructores de clases o llamadas a métodos, ya que esto tiende a contaminar los argumentos del método y hacerlos innecesariamente complejos.

Si decide hacer un singleton, entonces le recomiendo que diseñe un mecanismo mediante el cual pueda inyectar nuevas instancias de la configuración en la clase singleton para que el singleton no haga que las pruebas de su unidad sean muy difíciles de ejecutar.

1

Pasar una instancia de Configuration agrega mucho desorden innecesario a su código. Un Singleton es una buena idea o agrega algún tipo de Manager clase que proporciona todos los recursos compartidos, como los datos de configuración.

Si vas para Singleton, considere implementar el patrón de enumeración:

public enum Config{ DATA; 

    private int value1; 
    private int value2; 
    private int value3; 
    public load(File configFile) { 
    // some magic to store the values 
    } 
    public int getValue1() {return value1;} 
    public int getValue2() {return value2;} 
    public int getValue3() {return value3;} 
} 

Usted puede usarlo en todas partes en el código:

int property = Config.DATA.getValue1(); 
1

Si usted está haciendo esto en Java, lo haría coloque toda la configuración en Spring y luego use Application Context para buscar las configuraciones o simplemente inyéctelas en sus beans. Spring sobresale en este tipo de cosas.

1

Tenemos sus propiedades establecidas como propiedades del sistema. Se accede a ellos a través de una clase SystemProperties.
Esta clase es final con un constructor privado, las propiedades se acceden solo mediante métodos estáticos, por lo que técnicamente es Singleton. Está en sí mismo contenido en un commons.jar cada otro proyecto depende de.

Así que no hay necesidad de pasar nada, ya que las configuraciones están disponibles directamente donde las necesita.

+0

Esto puede interrumpirse tan pronto como más de una sola aplicación web esté instalada en el servidor. –

+0

@Aaron Digulla - seguramente. Incluso puede romperse por sí mismo, si alguien establece una propiedad con un valor incorrecto. La única seguridad que uno tiene son nombres de propiedad bastante largos y específicos. Hay muchos tipos de propiedades en nuestra aplicación y el enfoque de propiedad del sistema se aplica a las más dinámicas. Luego hay propiedades desplegadas como XML enlazado, algunas propiedades en el Manifiesto y también algunas fuentes codificadas en las clases finales como miembros estáticos públicos. Y en mi humilde opinión hay razones válidas para usar cada uno de los enfoques. Simplemente no para todo – kostja

3

Use Guice! Guice es un marco de inyección de dependencia que efectivamente reemplaza el uso de la nueva palabra clave. Usted define sus fijaciones de objetos en un módulo de la siguiente manera:

Y entonces, en lugar de Newing hasta WebServer directamente, sólo hay que preguntar Guice que lo haga por usted:

WebServer ws = Guice.createInjector(yourModule).getInstance(WebServer.class); 

Qué mágicamente crear MySpecificWebServerImplementation para ti.Si se define de la siguiente manera MySpecificWebServerImplementation:

public class MySpecificWebServerImplementation { 
    @Inject 
    public MySpecificWebServerImplementation(Configuration configuration) { 
    } 
} 

Entonces MySpecificWebServerImplementation automáticamente obtendrá dada la configuración y usted no tiene que preocuparse acerca de pasar a su alrededor.

+0

+1 para esta solución, es el enfoque DI algo más moderno en comparación con el patrón Singleton de la vieja escuela – Frank

0

Configuración no, pero es bueno tener un objeto singleton ServerManager. Demasiados objetos accesibles a nivel mundial son un poco confusos. Por configuración debería propiedad de "componente":

ServerManager.getServerManager.getConfigurationComponent(Configuration.class); 

ServerManager debe crear y leer objeto de configuración en tiempo de inicio. Guárdalo y ciérralo antes de irte.

Si lo usa más de una vez en cualquier clase, almacénelo como campo final privado.

2

Aunque Singletons ya no son favorecidos por muchos profesionales por varias razones, creo que todavía hay un buen caso de uso para usar un Ssingleton`.

Sin embargo, pregúntese si los requisitos del servidor web realmente requieren una sola configuración común para todos los aspectos del servidor. Y si es así, ¿qué probabilidades hay de que cambien pronto? Por ejemplo, supongamos que su servidor aloja 3 sitios web. Y ahora le piden que ponga limitaciones de ancho de banda en una de ellas: ¿cómo va a configurar esto?

Realmente estoy a favor de un buen singleton, aunque debe tener en cuenta todo el problema de seguridad de subprocesos al inicializarlo en un entorno multiproceso (aunque parece que no tendrá este problema ya que no tendrá múltiples roscas antes de inicializarlo.

tenga en cuenta que solas se alojan dentro de un ClassLoader y si tiene varios ClassLoader s (por ejemplo, para cada .war que cargar), tendrá varias copias de este "Singleton".

considerar todas las los aspectos de su servidor, y si es realmente simple - A Singleton savé Usted tiene muchos dolores de cabeza y hará que el código sea mucho más fácil de mantener y leer. Como se mencionó anteriormente en una o dos de las respuestas, la inyección de dependencia es una buena alternativa a Singleton s; te ayudan a hacer tus JUnits más fáciles.

Una nota sobre JUnit, entiendo (no lo probamos aún) que puede Mockit permitirá reemplazar una implementación real durante una prueba de funcionamiento, por lo que aún puede crear diferentes casos de prueba JUnit para diferentes escenarios sin modificar su Singleton ser comprobable

+0

¿Podría explicar en su afirmación que "los Singleton ya no son favorecidos por muchos profesionales por varias razones"? No estoy seguro de seguirte ... – mre

+0

@stupahsmaht - Muchos desarrolladores se están refiriendo a un 'Singleton' como un' antipattern', que significa algo que no deberías hacer.Si googleas "antipattern singleton" puedes encontrar muchas referencias en muchos blogs. – RonK

Cuestiones relacionadas