Java:工厂设计-方法模式| 面向对象设计 | 设计模式
已发表: 2013-06-28 工厂设计模式是创建设计模式之一,它广泛用于 JDK 以及 Spring MVC 和 Struts 等框架。 工厂方法模式是一种面向对象的创建型设计模式,用于实现工厂的概念并处理创建对象(产品)的问题,而无需指定将要创建的对象的确切类。 这种模式的本质是“定义一个用于创建对象的接口,但让实现该接口的类决定实例化哪个类。 Factory 方法允许类将实例化推迟到子类“。
让我们首先学习如何在java中实现工厂模式。 我们将创建 5 个类来实现这种模式。
- 超级类 (CrunchfiyCompany.java)
- 工厂模式中的超类可以是接口、抽象类或普通的 java 类。 对于我们的示例,我们将超类作为抽象类,并重写了
toString()
方法用于测试目的。
- 工厂模式中的超类可以是接口、抽象类或普通的 java 类。 对于我们的示例,我们将超类作为抽象类,并重写了
- 子类 1 (CrunchifyEbay.java)
- 请注意,该类正在扩展 CrunchfiyCompany 类。
- 子类 2 (CrunchifyGoogle.java)
- 请注意,该类正在扩展 CrunchfiyCompany 类。
- 工厂类 (CrunchifyFactoryPattern.java)
- 现在我们已经准备好超类和子类,我们可以编写我们的工厂类了。
- 我们可以保留 Factory 类 Singleton,也可以将返回子类的方法保留为静态。
- 请注意,根据输入参数,创建并返回不同的子类。
- 测试类 (CrunchifyFactoryPatternTest.java)
- 使用上述工厂模式实现的简单测试客户端程序。
其他必读:
- Java 中的线程安全和快速单例实现
- Java中的守护线程是什么? 附上示例
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 |
其他使用工厂模式的例子?
- java.util.Calendar、ResourceBundle 和 NumberFormat
getInstance()
方法使用工厂模式。 - 包装类中的
valueOf()
方法,如 Boolean、Integer 等。
工厂模式的好处:
- 当我们有一个具有多个子类的超类并且基于输入,我们需要返回一个子类时使用它。 这种模式承担了将类从客户端程序实例化到工厂类的责任。
- 工厂模式为接口而不是实现提供代码方法。
- 工厂模式从客户端代码中删除了实际实现类的实例化,使其更健壮、耦合更少且易于扩展。 例如,我们可以很容易地更改 PC 类的实现,因为客户端程序不知道这一点。
- 工厂模式通过继承提供实现和客户端类之间的抽象。
缺点:
- 工厂必须用于一系列对象。 如果这些类不扩展公共基类或接口,则它们不能在工厂设计模板中使用。
所有 Java Web 开发、Spring MVC 教程的列表。