首页 > Java > java教程 > 理解工厂方法模式

理解工厂方法模式

Susan Sarandon
发布: 2025-01-05 10:49:41
原创
879 人浏览过

Understanding the Factory Method Pattern

介绍

大家好,我写这篇文章是为了分享我继续学习设计模式的知识。今天,我将介绍工厂方法模式,这是现实应用程序中常用的设计模式。如果我的文章有任何错误,请随时在下面评论,我很乐意修复和更新。

工厂方法模式提供了在超类中创建对象的接口,但允许子类更改将创建的对象的类型。

问题

假设您有一个银行应用程序,并且您正在构建一个通过银行转账、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());
        }
    }
}

登录后复制

当前实现的问题:

  1. 重复代码:每种付款方式都会重复processPayment 方法逻辑。
  2. 紧密耦合的代码:应用程序需要自己创建支付方式对象,导致应用程序难以扩展。
  3. 可扩展性问题:如果添加新的支付方式,源代码会变得更加复杂且难以维护。

解决方案

解决上述情况的方法是使用工厂方法模式。那么,我们该如何应用呢?

在上面的例子中:

  1. 每个 if-else 块都会调用 processPayment 方法,这会导致重复代码。
  2. 根据支付类型条件创建对象,过多的 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中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板