Implementação e reflexão da interface fluente. Estudo de caso

5

Espero ter escolhido o grupo certo para essa pergunta ...

Eu tenho esse pequeno framework que quero implementar e gostaria de ter uma opinião sobre ele. Em particular, estou mais preocupado com a sucessão e o estilo da solução. Meu esboço de aula é assim:

public interface Builder<T> {

    T build();
}

public interface RootObject {


    public static abstract class MutableBuilder<T> implements Builder<T> {

        protected MutableBuilder() { }

        protected abstract void setA(A a);

        protected abstract void setB(B b);

        protected abstract void setC(C c);

        protected abstract void setD(D d);
    }
}

O objetivo é ter um construtor que retorne uma instância de objetos (esperançosamente) imutáveis. Toda a implementação é deixada para o código do cliente, mas eu ainda quero dar a impressão da interface fluente do Effective Java.

Se fosse só por isso, eu não ficaria assim tão intrigado. O problema surge quando eu adiciono os requisitos:

  • a estrutura precisa pesquisar de forma reflexiva por meio de uma implementação RootObject genérica para descobrir se a classe interna MutableBuilder estática foi implementada.
  • se encontrado, o framework instancia um ou mais MutableBuilder dinamicamente (essa é a razão pela qual eu tenho uma classe abstrata com um construtor e a retorno para o código do cliente.

A mera discussão sobre reflexão me faz pensar se estou fazendo a coisa certa. Parece uma solução razoável para mim (é claro).

    
por Andrea Richiardi 21.03.2013 / 04:38
fonte

1 resposta

3

Se possível, vá natural

Eu quero começar dizendo que o Java tem técnicas de criação de objetos embutidos ("naturais"). Forçar seus clientes a declarar tipos especificamente para criação de objetos sem nenhuma razão específica resultará em sua estrutura estar longe de ser "fácil de usar".

Evite introspecção, se possível.

Você está usando indevidamente o termo (aceito) " construtor ".

Um construtor só deve ser usado se um tipo tiver parâmetros opcionais. Nem todos os tipos têm isso, portanto, exigir um construtor para cada objeto é o abuso do padrão.

Se você estiver usando o construtor para dissociar uma implementação, o padrão correto a ser implementado será o padrão de método de fábrica

Prefira uma fábrica sobre sua solução atual

Nos comentários de sua postagem, você mencionou que sua estrutura agora exige que o cliente passe em um construtor. Embora seja bom você ter encontrado uma solução, parece haver um problema maior com seu design atual.

Os construtores não devem definir as propriedades necessárias , pois o cliente não é forçado a executar os comportamentos fornecidos por ele. Isso transforma o requisito em uma opção (criticamente) recomendada e é por isso que os construtores ainda utilizam construtores de classe. Seu design atualmente faz mau uso do padrão e, pelo som do comportamento que você está tentando alcançar, uma fábrica seria mais adequada.

    
por 01.11.2016 / 04:01
fonte