Java: Padrão de Método de Projeto de Fábrica | Design Orientado a Objetos | Padrões de design
Publicados: 2013-06-28 O Factory Design Pattern é um dos padrões Creational Design e é amplamente utilizado no JDK, bem como em frameworks como Spring MVC e Struts. O padrão de método de fábrica é um padrão de design criacional orientado a objetos para implementar o conceito de fábricas e trata do problema de criar objetos (produtos) sem especificar a classe exata de objeto que será criada. A essência desse padrão é “ Definir uma interface para criar um objeto, mas deixar que as classes que implementam a interface decidam qual classe instanciar. O método Factory permite que uma classe adie a instanciação para subclasses “.
Vamos primeiro aprender como implementar o padrão de fábrica em java. Vamos criar 5 classes para implementar este padrão.
- Superclasse (CrunchfiyCompany.java)
- A superclasse no padrão de fábrica pode ser uma interface, uma classe abstrata ou uma classe java normal. Para nosso exemplo, temos superclasse como classe abstrata com o
toString()
substituído para fins de teste.
- A superclasse no padrão de fábrica pode ser uma interface, uma classe abstrata ou uma classe java normal. Para nosso exemplo, temos superclasse como classe abstrata com o
- Subclasse1 (CrunchifyEbay.java)
- Observe que a classe está estendendo a classe CrunchfiyCompany.
- Subclasse2 (CrunchifyGoogle.java)
- Observe que a classe está estendendo a classe CrunchfiyCompany.
- Classe de fábrica (CrunchifyFactoryPattern.java)
- Agora que temos superclasses e subclasses prontas, podemos escrever nossa classe de fábrica.
- Podemos manter a classe Factory Singleton ou podemos manter o método que retorna a subclasse como estático.
- Observe que com base no parâmetro de entrada, uma subclasse diferente é criada e retornada.
- Classe de teste (CrunchifyFactoryPatternTest.java)
- Programa cliente de teste simples que usa a implementação do padrão de fábrica acima.
Outras leituras obrigatórias:
- Thread-Safe e uma implementação Singleton rápida em Java
- O que é Daemon Thread em Java? Exemplo em anexo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package com . crunchify . tutorials ; /** * @author Crunchify.com */ // Super class in factory pattern can be an interface, abstract class or a // normal java class. For our example, we have super class as abstract class // with overridden toString() method for testing purpose. public abstract class CrunchfiyCompany { public abstract String getPhoneNumber ( ) ; public abstract String getZipCode ( ) ; @Override public String toString ( ) { return "Phone #= " + this . getPhoneNumber ( ) + ", Zip Code= " + this . getZipCode ( ) ; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package com . crunchify . tutorials ; /** * @author Crunchify.com */ // Notice that the class is extending CrunchfiyCompany class. public class CrunchifyEbay extends CrunchfiyCompany { private String phoneNumber ; private String zipCode ; public CrunchifyEbay ( String phoneNumber , String zipCode ) { this . phoneNumber = phoneNumber ; this . zipCode = zipCode ; } @Override public String getPhoneNumber ( ) { return this . phoneNumber ; } @Override public String getZipCode ( ) { return this . zipCode ; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package com . crunchify . tutorials ; /** * @author Crunchify.com */ // Notice that the class is extending CrunchfiyCompany class. public class CrunchifyGoogle extends CrunchfiyCompany { private String phoneNumber ; private String zipCode ; public CrunchifyGoogle ( String phoneNumber , String zipCode ) { this . phoneNumber = phoneNumber ; this . zipCode = zipCode ; } @Override public String getPhoneNumber ( ) { return this . phoneNumber ; } @Override public String getZipCode ( ) { return this . zipCode ; } } |

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package com . crunchify . tutorials ; import com . crunchify . tutorials . CrunchfiyCompany ; import com . crunchify . tutorials . CrunchifyEbay ; import com . crunchify . tutorials . CrunchifyGoogle ; /** * @author Crunchify.com */ // Now that we have super classes and sub-classes ready, we can write our factory class. // We can keep Factory class Singleton or we can keep the method that return the subclass a static. // Notice that based on the input parameter, different subclass is created and returned. public class CrunchifyFactoryPattern { public static CrunchfiyCompany getDetails ( String type , String phoneNumber , String zipCode ) { if ( "Ebay" . equalsIgnoreCase ( type ) ) return new CrunchifyEbay ( phoneNumber , zipCode ) ; else if ( "Google" . equalsIgnoreCase ( type ) ) return new CrunchifyGoogle ( phoneNumber , zipCode ) ; return null ; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package com . crunchify . tutorials ; import com . crunchify . tutorials . CrunchfiyCompany ; import com . crunchify . tutorials . CrunchifyFactoryPattern ; /** * @author Crunchify.com */ // Simple Test client program that uses above factory pattern implementation. public class CrunchifyFactoryPatternTest { public static void main ( String [ ] args ) { CrunchfiyCompany eBay = CrunchifyFactoryPattern . getDetails ( "Ebay" , "408.123.4567" , "98765" ) ; CrunchfiyCompany google = CrunchifyFactoryPattern . getDetails ( "Google" , "519.123.4567" , "56789" ) ; System . out . println ( "Factory eBay Config::" + eBay ) ; System . out . println ( "Factory Google Config::" + google ) ; } } |
1 2 |
Factory eBay Config : : Phone #= 408.123.4567, Zip Code= 98765 Factory Google Config : : Phone #= 519.123.4567, Zip Code= 56789 |
Outros exemplos usando padrão de fábrica?
- Os métodos java.util.Calendar, ResourceBundle e NumberFormat
getInstance()
usam o padrão Factory. -
valueOf()
em classes wrapper como Boolean, Integer etc.
Benefícios do Padrão de Fábrica:
- É usado quando temos uma superclasse com várias subclasses e com base na entrada, precisamos retornar uma das subclasses. Esse padrão retira a responsabilidade de instanciar uma classe do programa cliente para a classe de fábrica.
- O padrão de fábrica fornece abordagem ao código para interface em vez de implementação.
- O padrão de fábrica remove a instanciação de classes de implementação reais do código do cliente, tornando-o mais robusto, menos acoplado e fácil de estender. Por exemplo, podemos facilmente alterar a implementação da classe PC porque o programa cliente não tem conhecimento disso.
- O padrão de fábrica fornece abstração entre classes de implementação e cliente por meio de herança.
Desvantagens:
- A fábrica deve ser usada para uma família de objetos. Se as classes não estenderem a interface ou classe base comum, elas não poderão ser usadas em um modelo de design de fábrica.
Lista de todos os tutoriais Java Web Development, Spring MVC.