Digamos, por ejemplo, que tiene una aplicación con una clase ampliamente compartida llamada User
. Esta clase expone toda la información sobre el usuario, su ID, nombre, niveles de acceso a cada módulo, zona horaria, etc.
Obviamente, los datos de usuario están ampliamente referenciados en todo el sistema, pero por cualquier razón, el sistema está configurado de modo que en lugar de pasar este objeto de usuario a clases que dependen de él, solo estamos pasando propiedades individuales de él.
Una clase que requiere la identificación del usuario, simplemente requerirá el GUID userId
como parámetro, a veces también podríamos necesitar el nombre de usuario, por lo que se pasa como un parámetro separado. En algunos casos, esto se pasa a métodos individuales, por lo que los valores no se mantienen a nivel de clase.
Cada vez que necesito acceso a una información diferente de la clase Usuario, tengo que hacer cambios agregando parámetros y cuando agregar una nueva sobrecarga no es apropiado, también tengo que cambiar cada referencia al método o al constructor de la clase.
El usuario es solo un ejemplo. Esto se practica ampliamente en nuestro código.
¿Estoy en lo cierto al pensar que esto es una violación del principio Abierto / Cerrado? ¿No solo el acto de cambiar las clases existentes, sino establecerlas en primer lugar para que sea muy probable que se requieran cambios generalizados en el futuro?
Si acabamos de pasar el User
objeto, podría hacer un pequeño cambio en la clase con la que estoy trabajando. Si tengo que agregar un parámetro, podría tener que hacer docenas de cambios en las referencias a la clase.
¿Hay otros principios quebrantados por esta práctica? ¿Inversión de dependencia quizás? Aunque no estamos haciendo referencia a una abstracción, solo hay un tipo de usuario, por lo que no hay ninguna necesidad real de tener una interfaz de usuario.
¿Se están violando otros principios no SÓLIDOS, como los principios básicos de programación defensiva?
Mi constructor debería verse así:
MyConstructor(GUID userid, String username)
O esto:
MyConstructor(User theUser)
Publicado:
Se ha sugerido que la pregunta se responda en "¿Id. De paso u objeto?". Esto no responde a la pregunta de cómo la decisión de ir de cualquier manera afecta un intento de seguir los principios SÓLIDOS, que es el núcleo de esta pregunta.
I
en SOLID
? MyConstructor
Básicamente dice ahora "Necesito una Guid
y una string
". Entonces, ¿por qué no tener una interfaz que proporcione ay Guid
a string
, dejar User
que implemente esa interfaz y MyConstructor
depender de una instancia que implemente esa interfaz? Y si las necesidades de MyConstructor
cambio, cambiar la interfaz. - Me ayudó mucho pensar en interfaces para "pertenecer" al consumidor en lugar del proveedor . Así que piense "como consumidor , necesito algo que haga esto y aquello" en lugar de "como proveedor puedo hacer esto y aquello".