理解工廠方法模式
介紹
大家好,我寫這篇文章是為了分享我繼續學習設計模式的知識。今天,我將介紹工廠方法模式,這是現實應用程式中常用的設計模式。如果我的文章有任何錯誤,請隨時在下面評論,我很樂意修復和更新。
工廠方法模式提供了在超類別中建立物件的接口,但允許子類別變更將建立的物件的類型。
問題
假設您有一個銀行應用程序,並且您正在建立一個透過銀行轉帳、PayPal 轉帳等各種方式轉帳的功能...
在使用工廠方法模式之前,讓我們先檢查一下沒有它的場景。
我將給出一個用 Java 實作的範例。
情況:Person1 使用轉帳方式(銀行轉帳或 PayPal 轉帳)向 Person2 匯款。
資料夾結構:
problem/ ├─ BankApp.java ├─ service/ │ ├─ PaypalTransferPayment.java │ ├─ BankTransferPayment.java ├─ data/ │ ├─ Person.java
在主應用程式中,建立兩個具有預設金額的人。
package problem; import problem.data.Person; public class BankApp { public static void main(String[] args) { Person person1 = new Person("John", 1000); Person person2 = new Person("Jane", 500); } }
建立 BankTransferPayment 和 PaypalTransferPayment 類別。
package problem.service; import problem.data.Person; public class BankTransferPayment { public void processPayment(Person fromAccount, Person toAccount, float amount) { fromAccount.withdraw(amount); toAccount.deposit(amount); System.out.println("Bank transfer payment success."); } }
package problem.service; import problem.data.Person; public class PaypalPayment { public void processPayment(Person fromAccount, Person toAccount, float amount) { fromAccount.withdraw(amount); toAccount.deposit(amount); System.out.println("Paypal transfer payment success."); } }
實作主函數中的邏輯。
package problem; import problem.data.Person; import problem.service.BankTransferPayment; import problem.service.PaypalPayment; public class BankApp { public static void main(String[] args) { Person person1 = new Person("John", 1000); Person person2 = new Person("Jane", 500); String paymentMethod = "BANK_TRANSFER"; if (paymentMethod.equals("BANK_TRANSFER")) { BankTransferPayment bankTransferPayment = new BankTransferPayment(); bankTransferPayment.processPayment(person1, person2, 100); System.out.println("===Method bank_transfer==="); System.out.println(person1.getName() + " has " + person1.getAmount()); System.out.println(person2.getName() + " has " + person2.getAmount()); } else if (paymentMethod.equals("PAYPAL")) { PaypalPayment paypalPayment = new PaypalPayment(); paypalPayment.processPayment(person1, person2, 100); System.out.println("===Method paypal==="); System.out.println(person1.getName() + " has " + person1.getAmount()); System.out.println(person2.getName() + " has " + person2.getAmount()); } } }
目前實現的問題:
- 重複程式碼:每種付款方式都會重複processPayment 方法邏輯。
- 緊密耦合的程式碼:應用程式需要自行建立支付方式對象,導致應用程式難以擴展。
- 可擴充性問題:如果新增新的付款方式,原始碼會變得更加複雜且難以維護。
解決方案
解決上述情況的方法是使用工廠方法模式。那麼,我們該如何應用呢?
在上面的例子中:
- 每個 if-else 區塊都會呼叫 processPayment 方法,這會導致重複程式碼。
- 根據支付類型條件建立對象,過多的 if-else 語句導致代碼混亂。
為了解決這些問題,將逐步實現Factory Method模式。
資料夾結構(解):
solution/ ├─ BankApp.java ├─ service/ │ ├─ payments/ │ │ ├─ Payment.java │ │ ├─ PaymentFactory.java │ │ ├─ BankTransferPayment.java │ │ ├─ PaypalTransferPayment.java ├─ data/ │ ├─ Person.java
第一步:建立Payment接口,宣告公共方法processPayment
package solution.service.payments; import solution.data.Person; // Step 1: Create an interface for the payment public interface Payment { void processPayment(Person fromAccount, Person toAccount,float amount); }
第 2 步:建立 BankTransferPayment 和 PaypalTransferPayment 類別實作 Payment 介面。
package solution.service.payments; import solution.data.Person; // Step 2: Create a class that implements the Payment interface public class BankTransferPayment implements Payment { @Override public void processPayment(Person fromAccount, Person toAccount, float amount) { fromAccount.withdraw(amount); toAccount.deposit(amount); System.out.println("Bank transfer payment success."); } }
package solution.service.payments; import solution.data.Person; public class PaypalPayment implements Payment{ @Override public void processPayment(Person fromAccount, Person toAccount, float amount) { fromAccount.withdraw(amount); toAccount.deposit(amount); System.out.println("Paypal transfer payment success."); } }
第3步:建立PaymentFactory類別。該類別負責根據支付類型條件建立物件。
package solution.service.payments; public class PaymentFactory { public Payment createPayment(String paymentType) { if (paymentType == null) { return null; } if (paymentType.equalsIgnoreCase("BANK_TRANSFER")) { return new BankTransferPayment(); } else if (paymentType.equalsIgnoreCase("PAYPAL")) { return new PaypalPayment(); } return null; } }
第 4 步:在主應用程式中使用工廠。
修改 main 函數以使用工廠方法模式。
problem/ ├─ BankApp.java ├─ service/ │ ├─ PaypalTransferPayment.java │ ├─ BankTransferPayment.java ├─ data/ │ ├─ Person.java
使用工廠方法模式的好處
- 程式碼更乾淨並且更結構化。
- 在多個 if-else 區塊中重複呼叫 processPayment 消除了。
- 物件創建委託給工廠,提高了可維護性。
獎金
為了讓 PaymentFactory 類別符合開閉原則(來自 SOLID 原則),可以使用策略模式實現動態註冊機制。
更新了 PaymentFactory.java:
package problem; import problem.data.Person; public class BankApp { public static void main(String[] args) { Person person1 = new Person("John", 1000); Person person2 = new Person("Jane", 500); } }
在主應用程式中使用更新後的工廠。
package problem.service; import problem.data.Person; public class BankTransferPayment { public void processPayment(Person fromAccount, Person toAccount, float amount) { fromAccount.withdraw(amount); toAccount.deposit(amount); System.out.println("Bank transfer payment success."); } }
透過應用此方法,程式碼遵循開閉原則,無需修改PaymentFactory邏輯即可新增新的付款方式。
希望這篇文章對您有幫助。
參考:
大師設計模式
以上是理解工廠方法模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

公司安全軟件導致部分應用無法正常運行的排查與解決方法許多公司為了保障內部網絡安全,會部署安全軟件。 ...

將姓名轉換為數字以實現排序的解決方案在許多應用場景中,用戶可能需要在群組中進行排序,尤其是在一個用...

系統對接中的字段映射處理在進行系統對接時,常常會遇到一個棘手的問題:如何將A系統的接口字段有效地映�...

在使用IntelliJIDEAUltimate版本啟動Spring...

在使用MyBatis-Plus或其他ORM框架進行數據庫操作時,經常需要根據實體類的屬性名構造查詢條件。如果每次都手動...

Java對象與數組的轉換:深入探討強制類型轉換的風險與正確方法很多Java初學者會遇到將一個對象轉換成數組的�...

電商平台SKU和SPU表設計詳解本文將探討電商平台中SKU和SPU的數據庫設計問題,特別是如何處理用戶自定義銷售屬...

Redis緩存方案如何實現產品排行榜列表的需求?在開發過程中,我們常常需要處理排行榜的需求,例如展示一個�...
