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 教程的列表。