Pergunta

Eu estava trabalhando com código java que supostamente está usando o padrão de fábrica, mas eu não estou completamente convencido pelo padrão.

Meu código faz isso:

// the factory
class SomeFactoryImpl {
   Set<SomeClass> getSomeListOfObjects();
}

E em algum lugar no código:

{ ...
    SomeFactory factory = new SomeFactoryImpl();
    Set<SomeClass> list = factory.getSomeListOfObjects();
}

O ponto que eu estou pensando é, se classes de fábrica não tem um estático create () método, então terá de instanciar uma fábrica, que OMI deve ser tão complexo como instantiating um objeto em si.

Eu não consideram o argumento de que tal fábrica um pode retornar coleções de objetos a ser produzido é bom o suficiente. Eu sinto que pode haver soluções alternativas mais limpas, se uma instância de fábrica precisa ser criado antes de realmente criar objetos a partir da fábrica.

Eu sinto que é melhor se o método de criar um método estático da classe de fábrica. Mas estou também certo de que minha opinião não é completamente "correta".

Assim, podem os exemplos dão comunidade, para onde instanciar um objeto de fábrica é melhor do que usar estática criar métodos?

Além disso, me deparei com uma resposta a uma pergunta semelhante, que listou esses links e a resposta: por isso eu preciso saber claramente a diferença entre FactoryMethodPattern , FactoryMethod e CreationMethod com exemplos de código.

Foi útil?

Solução

Usando uma instância de uma fábrica mostra os benefícios reais quando combinada com a injeção de dependência.

Assim, no seu exemplo, em vez de:

{ ...
    SomeFactory factory = new SomeFactoryImpl();
    Set<SomeClass> list = factory.getSomeListOfObjects();
}

Você teria que:

public ThisClass(SomeFactory someFactory) {
    this.factory = someFactory;
}   

, em seguida, mais tarde ...

{ ...
    Set<SomeClass> list = factory.getSomeListOfObjects();
}

Alguns pontos:

  • Nesta circunstância a sua classe não tem qualquer referência a uma fábrica de concreto, e não precisa de saber sobre SomeFactoryImpl, ele só sabe sobre o SomeFactory abstraída.
  • Neste caso, a instância fábrica que está sendo passada ao redor pode ser configurado em uma base exemplo, em vez de uma base estática, que tende a ser (em minha opinião) a melhor maneira de se lidar com isso. Se você pode fazer o imutável instância fábrica, então você pode realmente reduzir as preocupações multi-threading.
  • Tendo uma chamada estática para dar-lhe uma instância não é realmente muito melhor, a referência à classe que cria ainda é um detalhe de implementação concreta, é apenas mais acima - apesar de que pode torná-lo alto o suficiente para resolver o seu problema .

Eu sei que isto apenas endereços um subconjunto da sua pergunta ...

Outras dicas

Eu acho que, um método estático para a criação do objeto é a abordagem mais popular, mas há também alguns casos de uso em que primeiro criar uma instância de fábrica faz sentido. Por exemplo, se você quiser combiná-lo com um registro (onde vários registros devem ser autorizados a co-existir).

Além disso, se a fábrica conta com algumas informações contexto dinâmico (conexões de banco de dados, ...) é, na minha opinião melhor deixar uma alça de fábrica exemplo disso.

Primeiro de tudo você está esquecendo o principal objectivo do padrão de fábrica, eu abri o livro da Gang of Four e afirma:

"Definir uma interface para criar um objet, mas deixa as subclasses decidirem qual classe instanciar. Factory Method permite a instanciação de classe adiar para subclasses."

Isto significa que, na verdade, você define uma interface, de modo SomeFactoryImpl deve realmente implementar uma interface definida em outro lugar. Isto se torna útil quando você tem muitos objetos que precisam ser instanciado, mas você não quer se preocupar com o tipo de objeto que eles estão .. Por exemplo eu usei-los a desenvolver uma aplicação swing remoto no qual o cliente baixado através de serialização a definição de algumas classes que não existiam no cliente VM. Cada classe definida uma subclasse de JPanel que seu ponto de vista específico, mas quando chegar o cliente que eu tinha que encontrar uma maneira de istantiate essas classes sem conhecê-los, então eu usei um padrão de fábrica para chamar a classe de fábrica e deixá-lo instanciar meu objeto uknown (althrough-lo estende-se uma subclasse de Jpanel definida por me). Outro exemplo seria a geração de objeto específico do caso para atender às suas necessidades. Por exemplo (como indicado na página da Wikipedia relacionado com este padrão de projeto), você pode pensar uma fábrica que constrói objeto e, em seguida, uma outra fábrica para o mesmo tipo de objeto, mas usado para gerar "objetos falsos" que irá falhar algum tipo de teste de unidade.

No entanto, você pode resolver o seu problema específico com métodos estáticos também, mas pensar em divisão a parte que gera itens da parte que usa-los em um grande projeto. Claro que está desenvolvendo a parte do cliente deve apenas saber qual interface de fábrica é usado e saber exatamente isto para usar todos os objetos definet na outra parte.

Padrão Criação é um tipo de padrão 'facilidade' usado apenas para definir versões personalizadas de construtores sem se preocupar com definição padrão (com o nome do método igual ao nome da classe), mas é nada especial. Apenas uma maneira diferente de objetos istantiate .. o padrão de criação realmente não resolver qualquer tipo de problema específico (excluindo construtores com mesmo número e tipo de argumentos).

Aqui está o porquê eu criar instâncias de objetos de fábrica

  1. me permite criar uma fábrica, configurá-lo (para criar widgets azuis vs. flores vermelhas etc.) e, em seguida, tê-lo disponível para criar minhas flores azuis, flores vermelhas sob demanda. Note-se que isto é distinto de ter um RedWidgetFactory, BlueWidgetFactory. A configuração é ortogonal ao tipo (s) de objectos sendo criado
  2. reduz possíveis problemas de segmentação que você pode encontrar tendo uma fábrica (acessado através de um método estático) utilizado em todo o seu sistema. Esta é, talvez, um pouco na defensiva, mas eu descobri que é uma boa mentalidade para ter (especialmente em sistemas de tamanho considerável). Claro que depende de como os objetos são criados (por exemplo, se a sua fábrica de criar componentes que são compartilhados subjacente)

IMO, o código que você tem é na verdade, uma amostra adequada do GoF Abstract Factory padrão, mesmo que o seu uso não é completamente ideal. Se bem me lembro, o livro GoF descreve a relação entre fábricas (SomeFactory, SomeFactoryImpl) e produtos (SomeClass), mas deixa os detalhes de instanciar fábricas abrir.

Se o que você tem é uma API interna que não vai ser amplamente utilizado, o que você tem é provavelmente suficiente. Caso contrário, você pode:

  1. Tenha uma outra classe (a "gerente de fábrica" ??por assim dizer) selecionar sua implementação fábrica com base em um parâmetro (por exemplo, o DriverManager no JDBC), ou outras informações de contexto.
  2. Use algum tipo de estrutura de injeção de dependência.

Se ir com # 1, eu, pessoalmente, normalmente tentar e modelá-lo depois de JDBC, onde:

  • Driver seria a fábrica abstrata
  • Connections, Statements etc são produtos
  • DriverManager (não especificado no GoF livro explicitamente) é a classe utilitário que seleciona uma fábrica para você com base no JDBC URL aprovada em

(Neste caso, o DriverManager vai em frente e cria o produto para você também, se você usar os métodos getConnection(...), como a maioria faz.)

Para amarrá-lo de volta à sua pergunta, um sem dúvida poderia usar JDBC chamando

new OracleDriver().connect(...)

Mas, como o seu fora pontas, este é sub-óptima, e derrota um pouco o propósito de usar o padrão de fábrica abstrata.

Este problema costumava me incomodar muito também, até que eu percebi um dia que esse padrão realmente não fala explicitamente sobre como fábricas são criados.

Espero que isso responde sua pergunta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top