ファクトリ メソッド パターンを理解する
導入
皆さん、こんにちは。私はデザイン パターンについて学び続けているので、私の知識を共有するためにこの投稿を書いています。今日は、実際のアプリケーションで一般的に使用されるデザイン パターンであるファクトリー メソッド パターンを紹介します。私の投稿に間違いがある場合は、お気軽に以下にコメントしてください。喜んで修正して更新します。
ファクトリ メソッド パターンは、スーパークラスでオブジェクトを作成するためのインターフェイスを提供しますが、サブクラスは作成されるオブジェクトのタイプを変更できます。
問題
銀行アプリケーションがあり、銀行振込、PayPal 振込などのさまざまな方法で送金するための機能を構築しているとします。
ファクトリー メソッド パターンを使用する前に、それを使用しないシナリオを調べてみましょう。
Java で実装された例を示します。
状況: 人物 1 が振込方法 (銀行振込または PayPal 振込) を使用して人物 2 に送金します。
フォルダー構造:
problem/ ├─ BankApp.java ├─ service/ │ ├─ PaypalTransferPayment.java │ ├─ BankTransferPayment.java ├─ data/ │ ├─ Person.java
メイン アプリケーションで、デフォルトの金額を持つ 2 人の人物を作成します。
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
ステップ 1: 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: Payment インターフェイスを実装する BankTransferPayment クラスと PaypalTransferPayment クラスを作成します。
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 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

intellijideaultimatiateバージョンを使用してスプリングを開始します...

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。

eコマースプラットフォーム上のSKUおよびSPUテーブルの設計の詳細な説明この記事では、eコマースプラットフォームでのSKUとSPUのデータベース設計の問題、特にユーザー定義の販売を扱う方法について説明します。
