理解工厂方法模式
Jan 05, 2025 am 10:49 AM介绍
大家好,我写这篇文章是为了分享我继续学习设计模式的知识。今天,我将介绍工厂方法模式,这是现实应用程序中常用的设计模式。如果我的文章有任何错误,请随时在下面评论,我很乐意修复和更新。
工厂方法模式提供了在超类中创建对象的接口,但允许子类更改将创建的对象的类型。
问题
假设您有一个银行应用程序,并且您正在构建一个通过银行转账、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中文网其他相关文章!

热门文章

热门文章

热门文章标签

记事本++7.3.1
好用且免费的代码编辑器

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

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

2025年的前4个JavaScript框架:React,Angular,Vue,Svelte

如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?

如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?

如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?
