Digamos, por exemplo, que você tenha um aplicativo com uma classe amplamente compartilhada chamada User
. Esta classe expõe todas as informações sobre o usuário, seu ID, nome, níveis de acesso a cada módulo, fuso horário etc.
Os dados do usuário são obviamente amplamente referenciados em todo o sistema, mas por qualquer motivo, o sistema é configurado para que, em vez de passar esse objeto de usuário para classes que dependem dele, apenas passemos propriedades individuais dele.
Uma classe que requer o ID do usuário exigirá simplesmente o GUID userId
como parâmetro, às vezes também podemos precisar do nome de usuário, para que seja transmitido como um parâmetro separado. Em alguns casos, isso é passado para métodos individuais, portanto, os valores não são mantidos no nível da classe.
Toda vez que preciso acessar informações diferentes da classe User, preciso fazer alterações adicionando parâmetros e, onde adicionar uma nova sobrecarga não é apropriado, também preciso alterar todas as referências ao método ou construtor de classe.
O usuário é apenas um exemplo. Isso é amplamente praticado em nosso código.
Estou certo ao pensar que isso é uma violação do princípio Aberto / Fechado? Não apenas o ato de alterar as classes existentes, mas configurá-las em primeiro lugar, para que mudanças generalizadas provavelmente sejam necessárias no futuro?
Se apenas passássemos no User
objeto, eu poderia fazer uma pequena alteração na classe com a qual estou trabalhando. Se eu precisar adicionar um parâmetro, talvez seja necessário fazer dezenas de alterações nas referências à classe.
Existem outros princípios quebrados por essa prática? Inversão de dependência, talvez? Embora não façamos referência a uma abstração, existe apenas um tipo de usuário; portanto, não há necessidade real de ter uma interface de usuário.
Existem outros princípios não SOLID sendo violados, como princípios básicos de programação defensiva?
Meu construtor deve ficar assim:
MyConstructor(GUID userid, String username)
Ou isto:
MyConstructor(User theUser)
Edição da postagem:
Foi sugerido que a pergunta seja respondida em "Pass ID or Object?". Isso não responde à questão de como a decisão de ir de qualquer maneira afeta uma tentativa de seguir os princípios do SOLID, que está no cerne desta questão.
I
em SOLID
? MyConstructor
basicamente diz agora "eu preciso de um Guid
e um string
". Então, por que não ter uma interface fornecendo a Guid
e a string
, vamos User
implementar essa interface e vamos MyConstructor
depender de uma instância implementando essa interface? E se as necessidades de MyConstructor
mudança, altere a interface. - Isso me ajudou muito a pensar nas interfaces para "pertencer" ao consumidor e não ao provedor . Então pense "como consumidor eu preciso de algo que faça isso e aquilo" em vez de "como provedor, eu posso fazer isso e aquilo".