首頁 >Java >java教程 >理解工廠方法模式

理解工廠方法模式

Susan Sarandon
Susan Sarandon原創
2025-01-05 10:49:41876瀏覽

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