Maison >Java >javaDidacticiel >Comprendre le modèle de méthode d'usine

Comprendre le modèle de méthode d'usine

Susan Sarandon
Susan Sarandonoriginal
2025-01-05 10:49:41824parcourir

Understanding the Factory Method Pattern

Introduction

Bonjour à tous, j'écris cet article pour partager mes connaissances tout en continuant à apprendre les modèles de conception. Aujourd'hui, je présenterai le Factory Method Pattern, qui est un modèle de conception couramment utilisé dans les applications du monde réel. S'il y a des erreurs dans mon message, n'hésitez pas à commenter ci-dessous, et je me ferai un plaisir de le corriger et de le mettre à jour.

Le modèle de méthode Factory fournit une interface pour créer des objets dans une superclasse, mais permet aux sous-classes de modifier le type d'objets qui seront créés.

Problème

Supposons que vous disposez d'une application bancaire et que vous créez une fonctionnalité permettant de transférer de l'argent via diverses méthodes telles que le virement bancaire, le virement Paypal,…

Avant d'utiliser le modèle Factory Method, examinons le scénario sans celui-ci.

Je vais donner un exemple implémenté en Java.

Situation : Personne1 envoie de l'argent à Personne2 en utilisant une méthode de transfert (virement bancaire ou virement PayPal).

Structure des dossiers :

problem/
├─ BankApp.java
├─ service/
│  ├─ PaypalTransferPayment.java
│  ├─ BankTransferPayment.java
├─ data/
│  ├─ Person.java

Dans l'application principale, créez deux personnes avec des sommes d'argent par défaut.

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);
    }
}

Créez des classes BankTransferPayment et 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.");
    }
}

Implémentez la logique dans la fonction principale.

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());
        }
    }
}

Problèmes avec la mise en œuvre actuelle :

  1. Code répétitif : La logique du mode de paiement du processus est répétée pour chaque mode de paiement.
  2. Code étroitement couplé : l'application doit créer elle-même les objets de mode de paiement, ce qui rend difficile l'extension de l'application.
  3. Problèmes d'évolutivité : Si de nouveaux modes de paiement sont ajoutés, le code source devient plus complexe et plus difficile à maintenir.

Solution

La solution à la situation ci-dessus consiste à utiliser le modèle de méthode d'usine. Alors, comment on l'applique ?

Dans l'exemple ci-dessus :

  1. Chaque bloc if-else appelle la méthode processPayment, ce qui conduit à du code répétitif.
  2. Les objets sont créés en fonction de la condition du type de paiement, ce qui rend le code compliqué avec des instructions if-else excessives.

Pour résoudre ces problèmes, le modèle Factory Method sera implémenté étape par étape.

Structure des dossiers (solution) :

solution/
├─ BankApp.java
├─ service/
│  ├─ payments/
│  │  ├─ Payment.java
│  │  ├─ PaymentFactory.java
│  │  ├─ BankTransferPayment.java
│  │  ├─ PaypalTransferPayment.java
├─ data/
│  ├─ Person.java

Étape 1 : Créer une interface de paiement, déclare le processus de méthode communePaiement

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);
}

Étape 2 : Créer les classes BankTransferPayment et PaypalTransferPayment implémentant l'interface de paiement.

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.");
    }
}

Étape 3 : Créez la classe PaymentFactory. Cette classe est chargée de créer des objets basés sur la condition du type de paiement.

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;
    }
}

Étape 4 : Utilisez Factory dans l'application principale.

Modifiez la fonction principale pour utiliser le modèle Factory Method.

problem/
├─ BankApp.java
├─ service/
│  ├─ PaypalTransferPayment.java
│  ├─ BankTransferPayment.java
├─ data/
│  ├─ Person.java

Avantages de l'utilisation du modèle de méthode Factory

  • Le code est plus propre et plus structuré.
  • Les appels répétitifs à processPayment dans plusieurs blocs if-else sont éliminés.
  • La création d'objets est déléguée à l'usine, améliorant ainsi la maintenabilité.

Bonus

Pour rendre la classe PaymentFactory conforme au principe Open/Closed (issu des principes SOLID), vous pouvez implémenter un mécanisme d'enregistrement dynamique à l'aide du Modèle de stratégie.

PaymentFactory.java mis à jour :

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);
    }
}

Utilisation de l'usine mise à jour dans l'application principale.

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.");
    }
}

En appliquant cette approche, le code adhère au Principe Ouvert/Fermé, permettant l'ajout de nouveaux modes de paiement sans modifier la logique PaymentFactory.

J'espère que cet article vous sera utile.

Références :

modèles-de-conception-gourou

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn