Problema
Recentemente, li muito sobre Singletons serem ruins e como a injeção de dependência (que entendo como "usando interfaces") é melhor. Quando implementei parte disso com retornos de chamada / interfaces / DI e aderindo ao princípio de segregação de interface, acabei com uma bagunça.
As dependências de um pai da interface do usuário em que basicamente as de todos os seus filhos eram combinadas; portanto, quanto mais alto a hierarquia era um elemento da interface do usuário, mais inchado era o construtor.
No topo da hierarquia da interface do usuário, havia uma classe Application, contendo as informações sobre a seleção atual e uma referência a um modelo 3d que precisa refletir as alterações. A classe de aplicação estava implementando 8 interfaces, e isso era apenas a rotunda de um quinto dos produtos (/ interfaces) por vir!
Atualmente, trabalho com um singleton segurando a seleção atual e os elementos da interface do usuário com uma função para atualizar-se. Essa função desativa a árvore da interface do usuário e os elementos da interface do usuário e, em seguida, acessa o singleton da seleção atual conforme necessário. O código parece mais limpo para mim dessa maneira.
Pergunta
Um singleton pode ser apropriado para este projeto?
Se não, existe uma falha fundamental no meu pensamento e / ou implementação da DI que a torna tão complicada?
Informações adicionais sobre o projeto
Tipo: Cesto de compras para apartamentos, com sinos e assobios
Tamanho: 2 homens-mês para código e interface do usuário
Manutenção: Nenhuma atualização em execução, mas talvez a "versão 2.0" posterior
Ambiente: Usando C # no Unity, que usa uma Entidade Sistema de componentes
Em quase todos os casos, a interação do usuário aciona várias ações. Por exemplo, quando o usuário seleciona um item
- a parte da interface do usuário que mostra esse item e sua descrição precisa ser atualizada. Para isso, ele também precisa obter algumas informações de um modelo 3d para calcular o preço.
- na interface do usuário, o preço total geral precisa ser atualizado
- uma função correspondente em uma classe em um modelo 3d precisa ser chamada para exibir as alterações lá
fonte
Respostas:
Eu acho que a pergunta é um sintoma, não uma solução.
Uma solução procurando um problema; isso e mal-entendido provavelmente está corrompendo seu design. Você já leu esta pergunta sobre o DI vs Singleton, conceitos diferentes ou não? Eu li isso simplesmente envolvendo um singleton para que o cliente não precise lidar com um singleton. É apenas um bom encapsulamento antigo. Eu acho que é no local.
Construa os bits menores primeiro e depois passe-os para o construtor da coisa a que pertencem e passe essa coisa maior para o construtor da próxima coisa maior ...
Se você tiver problemas complexos de construção, use o padrão de fábrica ou construtor. Resumindo, existe uma construção complexa inserida em sua própria classe para manter outras classes organizadas, limpas, compreensíveis etc.
Isso soa como a ausência de capacidade de extensão. O design do núcleo está ausente e tudo está sendo amontoado a partir do topo. Deveria haver mais construção, composição e herança de baixo para cima.
Gostaria de saber se o seu design é "top pesado". Parece que estamos tentando fazer com que uma classe seja tudo ou qualquer coisa que possa ser. E o fato de ser uma classe de interface do usuário, não uma classe de domínio comercial, que realmente me faz pensar sobre a separação de preocupações.
Revise seu design desde o início e verifique se há uma abstração sólida e básica do produto que pode ser construída para criar produções de categoria mais complexas ou diferentes. Então é melhor você ter coleções personalizadas dessas coisas para ter um lugar para colocar a funcionalidade "nível de coleção" - como o "terceiro modelo" mencionado.
Muito disso pode caber em classes de coleção personalizadas. Também pode ser uma estrutura de classe independente devido à profundidade e complexidade. Essas duas coisas não são mutuamente exclusivas.
Leia sobre o padrão de visitantes. É a idéia de ter um monte de funcionalidades conectadas abstratamente a diferentes tipos.
Design e DI
90% de toda a injeção de dependência que você fará é a passagem de parâmetro do construtor. É o que diz o quy que escreveu o livro . Crie bem suas aulas e evite poluir esse processo de pensamento com alguma noção vaga sobre a necessidade de usar um recipiente de DI. Se você precisar, seu design o sugerirá, por assim dizer.
Concentre-se na modelagem do domínio de compras de apartamentos.
Evite a abordagem de Jessica Simpson ao design : "Não sei o que isso significa, mas quero isso".
O seguinte está errado:
fonte
"Hierarquia de classe" é um pouco de bandeira vermelha. Hipotético: uma página da web com 5 widgets. A página não é um ancestral de nenhum dos widgets. Pode conter uma referência a esses widgets. Mas não é um ancestral. Em vez da hierarquia de classes, considere usar a composição. Cada um dos 5 widgets pode ser construído por conta própria, sem referência aos outros widgets ou à página inicial. A página superior é então construída com informações suficientes para criar uma página básica e distribuir os objetos do widget (Coleção) que são passados para ela. A página é responsável pelo layout, etc., mas não pela construção e lógica dos widgets.
Depois de usar a composição, DI é seu melhor amigo. O DI permite trocar cada widget por qualquer versão ou tipo de widget que você definir no DI. A construção dos widgets é capturada na DI e é separada da página superior. Talvez até a composição da coleção possa ser definida no seu DI. A página superior executa o layout com base nos widgets passados para ela, como deveria. Não são necessárias alterações no construtor da página superior. A página superior precisa apenas da lógica para executar o layout dos widgets e transmitir informações de / para o widget com base nas interfaces definidas.
Em vez de passar os ouvintes para cima e para baixo na cadeia de composição, injete uma coleção de ouvintes nos widgets que precisam. Injete a coleção em um editor para que eles possam publicar na coleção. Injete a coleção nos ouvintes para que eles possam se adicionar à coleção. A coleção atravessa todos os objetos na cadeia de composição.
fonte