O que é um método de "fábrica estática"?
java
design-patterns
factory-method
freddiefujiwara
fonte
fonte
Respostas:
Evitamos fornecer acesso direto às conexões com o banco de dados porque elas consomem muitos recursos. Portanto, usamos um método estático de fábrica
getDbConnection
que cria uma conexão se estiver abaixo do limite. Caso contrário, ele tenta fornecer uma conexão "sobressalente", falhando com uma exceção se não houver.fonte
O padrão estático do método de fábrica é uma maneira de encapsular a criação de objetos. Sem um método de fábrica, você poderia simplesmente chamar a classe construtor diretamente:
Foo x = new Foo()
. Com este padrão, você iria em vez chamar o método de fábrica:Foo x = Foo.create()
. Os construtores são marcados como particulares, portanto, não podem ser chamados, exceto de dentro da classe, e o método factory é marcado comostatic
para que possa ser chamado sem primeiro ter um objeto.Existem algumas vantagens nesse padrão. Uma é que a fábrica pode escolher entre muitas subclasses (ou implementadores de uma interface) e devolvê-la. Dessa forma, o chamador pode especificar o comportamento desejado por meio de parâmetros, sem precisar conhecer ou entender uma hierarquia de classes potencialmente complexa.
Outra vantagem é, como apontaram Matthew e James, controlar o acesso a um recurso limitado, como conexões. Essa é uma maneira de implementar conjuntos de objetos reutilizáveis - em vez de construir, usar e derrubar um objeto, se a construção e a destruição forem processos caros, pode fazer mais sentido construí-los uma vez e reciclá-los. O método de fábrica pode retornar um objeto instanciado existente e não utilizado, se ele tiver um, ou construir um se a contagem de objetos estiver abaixo de algum limite inferior ou lançar uma exceção ou retornar
null
se estiver acima do limite superior.Conforme o artigo da Wikipedia, vários métodos de fábrica também permitem interpretações diferentes de tipos de argumentos semelhantes. Normalmente, o construtor tem o mesmo nome que a classe, o que significa que você só pode ter um construtor com uma determinada assinatura . As fábricas não são tão restritas, o que significa que você pode ter dois métodos diferentes que aceitam os mesmos tipos de argumento:
e
Isso também pode ser usado para melhorar a legibilidade, como observa Rasmus.
fonte
NOTA! "O método estático de fábrica NÃO é o mesmo que o padrão do Método de Fábrica " (c) Java efetivo, Joshua Bloch.
Método Factory: "Defina uma interface para criar um objeto, mas deixe as classes que implementam a interface decidirem qual classe instanciar. O método Factory permite que uma classe adie a instanciação para subclasses" (c) GoF.
"O método estático de fábrica é simplesmente um método estático que retorna uma instância de uma classe." (c) Java efetivo, Joshua Bloch. Geralmente esse método está dentro de uma classe específica.
A diferença:
A idéia principal do método estático de fábrica é obter controle sobre a criação de objetos e delegá-lo do construtor ao método estático. A decisão do objeto a ser criado é como na Abstract Factory feita fora do método (no caso comum, mas nem sempre). Enquanto a idéia-chave (!) Do Factory Method é delegar a decisão de qual instância da classe criar dentro do Factory Method. Por exemplo, a implementação clássica de Singleton é um caso especial do método estático de fábrica. Exemplo de métodos estáticos de fábrica comumente usados:
fonte
A legibilidade pode ser melhorada por métodos estáticos de fábrica:
Comparar
para
fonte
private Foo(boolean withBar){/*..*/}
public static Foo createWithBar(){return new Foo(true);}
public static Foo createWithoutBar(){return new Foo(false);}
de http://www.javapractices.com/topic/TopicAction.do?Id=21
fonte
Tudo se resume à manutenção. A melhor maneira de colocar isso é que sempre que você usa a
new
palavra-chave para criar um objeto, você está acoplando o código que está gravando em uma implementação.O padrão de fábrica permite separar como você cria um objeto do que faz com ele. Quando você cria todos os seus objetos usando construtores, está essencialmente conectando o código que usa o objeto a essa implementação. O código que usa seu objeto é "dependente" desse objeto. Isso pode não parecer muito importante na superfície, mas quando o objeto muda (pense em alterar a assinatura do construtor ou em subclassificar o objeto), é necessário voltar e religar as coisas em todos os lugares.
Hoje, as fábricas foram largamente descartadas em favor do uso de injeção de dependência, porque exigem muito código de placa de caldeira que acaba sendo um pouco difícil de manter. A injeção de dependência é basicamente equivalente às fábricas, mas permite que você especifique como seus objetos são conectados de forma declarativa (por meio de configurações ou anotações).
fonte
Se o construtor de uma classe for privado, você não poderá criar um objeto para a classe de fora dela.
Não podemos criar um objeto para a classe acima de fora dela. Portanto, você não pode acessar x, y de fora da classe. Então, qual é o uso dessa classe?
Aqui está o método Answer: FACTORY .
Adicione o método abaixo na classe acima
Então agora você pode criar um objeto para esta classe de fora dela. Desse jeito...
Portanto, um método estático que retorna o objeto da classe executando seu construtor privado é chamado como método FACTORY
.
fonte
Static Factory Method
relação ao construtor público?Pensei em acrescentar alguma luz a este post sobre o que sei. Usamos essa técnica extensivamente em nossa
recent android project
. Em vez decreating objects using new operator
você também pode usarstatic method
para instanciar uma classe. Listagem de código:Os métodos estáticos suportam a criação condicional de objetos : toda vez que você invoca um construtor, um objeto é criado, mas você pode não querer isso. suponha que você queira verificar alguma condição apenas para criar um novo objeto. Você não criaria uma nova instância do Vinoth todas as vezes, a menos que sua condição seja satisfeita.
Outro exemplo extraído do Java eficaz .
Este método converte um valor primitivo booleano em uma referência de objeto booleano. O
Boolean.valueOf(boolean)
método nos ilustra, nunca cria um objeto. A capacidade destatic factory methods
retornar o mesmo objeto de repetidasinvocations
permite que as classes mantenham controle estrito sobre quais instâncias existem a qualquer momento.Static factory methods
é que, diferentementeconstructors
, eles podem retornar umobject
de qualquersubtype
tipo de retorno. Uma aplicação dessa flexibilidade é que uma API pode retornar objetos sem tornar suas classes públicas. Ocultar classes de implementação dessa maneira leva a uma API muito compacta.Calendar.getInstance () é um bom exemplo para o acima, cria-se, dependendo da localidade um
BuddhistCalendar
,JapaneseImperialCalendar
ou por um padrãoGeorgian
.Outro exemplo que eu poderia pensar é
Singleton pattern
: onde você torna seus construtores privados, cria umgetInstance
método próprio , onde você garante que sempre haja apenas uma instância disponível.fonte
Um método de fábrica, um método que abstrai a instanciação de um objeto. Geralmente as fábricas são úteis quando você sabe que precisa de uma nova instância de uma classe que implemente alguma interface, mas não conhece a classe de implementação.
Isso é útil ao trabalhar com hierarquias de classes relacionadas, um bom exemplo disso seria um kit de ferramentas da GUI. Você pode simplesmente codificar as chamadas aos construtores para implementações concretas de cada widget, mas se você quiser trocar um kit de ferramentas por outro, terá muitos lugares para mudar. Ao usar uma fábrica, você reduz a quantidade de código que precisaria alterar.
fonte
Uma das vantagens que resulta da fábrica estática é que essa API pode retornar objetos sem tornar suas classes públicas. Isso levou a uma API muito compacta. Em java, isso é alcançado pela classe Collections, que oculta cerca de 32 classes, o que a torna muito compacta.
fonte
Um método estático de fábrica é bom quando você deseja garantir que apenas uma única instância retorne a classe de concreto a ser usada.
Por exemplo, em uma classe de conexão com o banco de dados, convém que apenas uma classe crie a conexão com o banco de dados, de modo que, se você decidir mudar do Mysql para o Oracle, poderá alterar a lógica de uma classe e o restante do aplicativo irá use a nova conexão.
Se você deseja implementar o pool de banco de dados, isso também seria feito sem afetar o restante do aplicativo.
Ele protege o restante do aplicativo das alterações que você pode fazer na fábrica, que é a finalidade.
O motivo para ser estático é que, se você deseja acompanhar algum recurso limitado (número de conexões de soquete ou identificadores de arquivo), essa classe pode acompanhar quantos foram desmaiados e retornados, para não esgotar o recurso limitado.
fonte
Uma das vantagens dos métodos estáticos de fábrica com o construtor privado (a criação de objetos deve ter sido restrita a classes externas para garantir que as instâncias não sejam criadas externamente) é que você pode criar classes controladas por instância . E as classes controladas por instância garantem que não existem duas instâncias distintas iguais ( a.equals (b) se e somente se a == b ) durante a execução do programa, significa que você pode verificar a igualdade de objetos com o operador == em vez do método equals , de acordo com java eficaz.
De Java eficaz, Joshua Bloch (Item 1, página 6)
fonte
Um membro declarado com a palavra-chave 'estático'.
Métodos que criam e retornam novos objetos.
A linguagem de programação é relevante para o significado de 'estático', mas não para a definição de 'fábrica'.
fonte
A implementação Java contém as classes de utilitários java.util.Arrays e java.util.Collections, ambas contêm métodos estáticos de fábrica , exemplos e como usar:
Arrays.asList("1","2","3")
Collections.synchronizedList(..), Collections.emptyList(), Collections.unmodifiableList(...)
(Apenas alguns exemplos, você pode verificar exemplos de métodos mor no javadocs https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html )A classe java.lang.String também possui métodos estáticos de fábrica :
String.format(...), String.valueOf(..), String.copyValueOf(...)
fonte