Devo usar um grande delegante para manter meu código desacoplado?

5

Atualmente estou aprendendo a aplicar o SRP e desvincular o código. Mas descobri que ter um monte de turmas pequenas explode os construtores das minhas aulas. E parece que o código que usa outro módulo do meu aplicativo precisa saber mais sobre esse módulo do que eu gostaria de conhecê-lo.
Descobri que muitos livros mencionam que as classes devem ser muito pequenas, mas não como gerenciar essa quantidade de turmas pequenas.

Vamos supor que eu tenha um módulo em meu aplicativo relacionado à transmissão de conteúdo para um dispositivo remoto (como o Chromecast). Agora tentei separar minhas responsabilidades o máximo que pude.

Existe um CastErrorEventDispatcher , CastSessionHelper , CastRequestSender , CastConnectivityHelper e muitos mais.

Agora, as outras partes do meu aplicativo precisam acessar diferentes objetos do meu módulo de transmissão. Alguns precisam apenas de uma classe que outra possa precisar 4. Isso definitivamente destrói os construtores.

assim:

public class ExpandedControlsPresenter(){
    public ExpandedControlsPresenter(CastRequestSender castRequestSender,
                                     CastConnectivitySender castConnectivitySender,
                                     CastBreakEventDispatcher castBreakEventDispatcher, ...){
    ...
    }

    public void setUp(){
        castBreakEventDispatcher.addListener(...);
        castRequestSender.addListener(...);
    }
}

Isso me preocupa porque agora meu apresentador tem que saber muita coisa sobre as aulas de elenco. Então, pergunto-me se seria melhor esconder todo o módulo de elenco atrás de um grande delegador.

public class CastManager {
    //Constructor with all relevant cast classes


    public void addBreakEventListener(CastBreakEventListener listener){
        castBreakEventDispatcher.addListener(listener);
    }
}

E então é só isso no meu apresentador

public class ExpandedControlsPresenter(){
    public ExpandedControlsPresenter(CastManager castManager, ...){
    ...
    }

    public void setUp(){
        castManager.addBreakEventListener(...);
        castManager.addRequestSenderListener(...);
    }
}

Isso tem a vantagem de obter construtores menores e eu posso ativar e desativar o recurso de transmissão apenas interagindo com o CastManager . Mas se claro que o CastManager se tornaria incrivelmente enorme.

Existe uma boa maneira de lidar com esse problema?

Editar: Eu desenhei um diagrama rápido para esclarecer minhas intenções. Também quero dizer que sei manager não é um bom nome.

    
por Altoyr 27.10.2016 / 22:57
fonte

2 respostas

1

Esta é realmente uma situação em que você foi longe demais! Acho que quando acabo com uma tonelada de classes de configurações (como os nomes CastRequestSender e CastConnectivitySender me levam a acreditar que eles são), eu gosto de envolvê-los em um grande objeto chamado Container para me manter sã.

Então, se você se encontrar com tudo isso, talvez queira adicionar algo assim:

public class CastSettingsContainer{
    CastRequestSender requestSender;
    CastConnectivitySender connectivitySender;
    //And so on...
}

Isso significa que agora você tem um objeto com todo o propósito de conter um conjunto inteiro de configurações de transmissão. Isso também ajuda a dissociar o código, porque agora as outras classes não precisam necessariamente conhecer as configurações individuais do Google Cast, apenas o objeto contêiner. Dessa forma, você pode perfeitamente ordenar que outras classes solicitem a execução de um CastSettingsContainer, e ele pode gerenciar internamente o que está acontecendo com as diferentes configurações. Isso deve limpar seu código muito bem, eliminando muitos construtores estranhos e movendo-os para o Container.

    
por 28.10.2016 / 01:04
fonte
0

Dado isso:

castManager.addBreakEventListener(...);
castManager.addRequestSenderListener(...);

por que não registrar apenas as classes dependentes como uma coleção de ouvintes . Dessa forma, você não tem conjuntos específicos de classes que está injetando em seu 'contêiner', mas uma lista de interessados.

Quando ocorre um evento, você pode "publicar" um evento, e os ouvintes registrados podem então atuar nesse evento, ou ignorá-lo se desejarem, e. (em pseudocódigo)

for (listener : listeners) {
   listener.startupEvent(myStartupEvent);
}

Alguns componentes se importariam, outros não. Você pode ter diferentes conjuntos / tipos de eventos e, consequentemente, pode desejar ter registros diferentes (por exemplo, eu quero me inscrever para eventos da categoria X , mas não da categoria Y , então você pode querer diferentes coleções de ouvintes ...)

Acho isso uma maneira poderosa de combinar vários componentes. É flexível (basta adicionar um novo ouvinte e / ou um novo tipo de evento) e você não sofre a explosão de dependências e membros de componentes. A desvantagem é que você precisa ter certeza de que seu componente está conectado corretamente, pois você perde a tipagem estática que garante que typeA seja construído com typeB

    
por 28.10.2016 / 14:15
fonte