Lo primero es asegurarse de que el usuario proporcione la dependencia del registrador en ambos casos. Presumiblemente en el primer caso, el constructor de FileNameLoader toma un parámetro Logger&
?
En ningún caso, bajo ningún concepto haré que el Registrador sea Singleton. Nunca, nunca, ni manera, ni cómo. Es una dependencia inyectada, o bien tiene una función gratuita Log
, o si es absolutamente necesario, utilice una referencia global a un objeto std::ostream
como su registrador predeterminado universal. Una clase de Singleton Logger es una forma de crear obstáculos para las pruebas, para absolutamente ningún beneficio práctico. Entonces, ¿qué pasa si algún programa crea dos objetos Logger? ¿Por qué es eso incluso malo, y menos vale la pena crear problemas para ti mismo para prevenir? Una de las primeras cosas que me encuentro haciendo, en cualquier sistema de registro sofisticado, es crear un PrefixLogger que implementa la interfaz Logger pero imprime una cadena especificada al inicio de todos los mensajes, para mostrar algún contexto. Singleton es incompatible con este tipo de flexibilidad dinámica.
Lo segundo, entonces, es preguntar si los usuarios van a querer tener un único FileNameLoader y llamar a LoadFileNames varias veces, con un registrador la primera vez y otro registrador la segunda vez.
Si es así, definitivamente desea un parámetro Logger para la llamada de función, porque un acceso para cambiar el Logger actual es (a) no una gran API, y (b) imposible con un miembro de referencia de todos modos: tiene que cambiar a un puntero. Sin embargo, es posible que el parámetro logger sea un puntero con un valor predeterminado de 0
, con 0
que significa "usar la variable miembro". Eso permitiría usos donde el código de configuración inicial de los usuarios conoce y se preocupa por el registro, pero luego ese código transfiere el objeto FileNameLoader a otro código que llamará a LoadFileNames, pero no sabe o no le preocupa el registro.
Si no es así, entonces la dependencia del Registrador es una constante para cada instancia de la clase, y usar una variable miembro está bien. Siempre me preocupan un poco las variables de los miembros de referencia, pero por razones que no están relacionadas con esta elección.
[Editar en relación con el generador: Creo que puede buscar y reemplazar en mi respuesta y todavía se mantiene. La diferencia crucial es si "el Constructor utilizado por este objeto FileNameLoader" es invariante para un objeto dado, o si "el Constructor utilizado en la llamada" es algo que las personas que llaman a LoadFileNames necesitan configurar por llamada.
Podría ser un poco menos firme que el Creador no debería ser un Singleton. Ligeramente. Podría.]
¿Por qué no quería cambiar su registrador?Úselo con método estático, sin firma de función incorrecta y sin objeto adicional en todas sus clases. –
Quizás para mayor claridad, edite en el primer ejemplo cómo entró el registrador. ¿Se pasó durante la construcción FileNameLoader? Si es así, consideraría mejor el # 1. – sdg