En tant qu'ingénieurs logiciels, nous sommes constamment chargés de créer des systèmes maintenables, flexibles et extensibles. Dans ce contexte, les modèles de conception sont des outils puissants qui nous aident à résoudre des problèmes récurrents de manière structurée et réutilisable. L'un de ces modèles de conception est le Modèle de stratégie, qui fait partie de la famille des Modèles comportementaux.
Le Strategy Pattern vous permet de définir une famille d'algorithmes, d'encapsuler chacun d'eux et de les rendre interchangeables. Cela signifie que le client peut choisir l'algorithme ou la stratégie appropriée au moment de l'exécution sans altérer les fonctionnalités de base du système.
Dans ce blog, je vais approfondir le modèle de stratégie, ses concepts et composants clés, un exemple concret, et quand et pourquoi vous devriez l'utiliser. Nous explorerons également comment le modèle de stratégie fonctionne avec l'abstraction, les énumérations et même le modèle d'usine pour rendre la conception plus robuste et flexible.
Le Modèle de stratégie est un modèle de conception comportementale qui permet de sélectionner le comportement d'un algorithme au moment de l'exécution. Au lieu d'avoir un algorithme unique et monolithique, le modèle de stratégie permet au comportement (ou à la stratégie) d'être interchangeable, ce qui rend le système plus flexible et plus facile à maintenir.
Le modèle de stratégie est particulièrement utile lorsque :
Séparation des préoccupations : Le modèle de stratégie sépare les préoccupations de l'algorithme du reste du système. Le code client ignore le fonctionnement interne de l'algorithme, ce qui le rend plus modulaire.
Extensibilité : De nouveaux algorithmes peuvent être ajoutés sans modifier le code existant, simplement en ajoutant de nouvelles classes de stratégie.
Kebolehselenggaraan: Ia mengurangkan kerumitan kod dengan mewakilkan gelagat berbeza kepada kelas strategi individu, yang menjadikan penyelenggaraan lebih mudah.
Algoritma Mudah: Jika algoritma yang anda gunakan adalah mudah dan tidak berubah, menggunakan corak strategi mungkin berlebihan.
Terlalu Banyak Strategi: Jika anda mempunyai sejumlah besar strategi, ia boleh membawa kepada letupan kelas, yang boleh menjejaskan kebolehbacaan dan meningkatkan kerumitan.
Perubahan Jarang: Jika algoritma tidak kerap berubah, memperkenalkan Corak Strategi boleh memperkenalkan kerumitan yang tidak perlu.
Corak Strategi terdiri daripada komponen utama berikut:
Konteks:
Strategi:
Strategi Konkrit:
Mari pertimbangkan sistem pemprosesan pembayaran yang membolehkan pengguna membayar menggunakan kaedah yang berbeza seperti Kad Kredit, PayPal dan Matawang Kripto. Tingkah laku cara pembayaran diproses berbeza untuk setiap kaedah, tetapi konteksnya (Cart Beli-belah dalam kes ini) perlu boleh memproses pembayaran tanpa perlu risau tentang butiran setiap kaedah pembayaran.
Kami akan mulakan dengan menggunakan enum untuk menentukan kaedah pembayaran yang berbeza. Ini menjadikan pilihan kaedah pembayaran jenis selamat dan lebih mudah untuk diurus.
public enum PaymentMethod { CREDIT_CARD, PAYPAL, CRYPTOCURRENCY; }
Kelas ini merangkumi butiran yang diperlukan untuk memproses pembayaran. Ia mengandungi kaedah pembayaran dan butiran pembayaran (seperti nombor kad, e-mel atau alamat mata wang kripto).
public class PaymentInformation { private PaymentMethod paymentMethod; private String paymentDetails; public PaymentInformation(PaymentMethod paymentMethod, String paymentDetails) { this.paymentMethod = paymentMethod; this.paymentDetails = paymentDetails; } public PaymentMethod getPaymentMethod() { return paymentMethod; } public String getPaymentDetails() { return paymentDetails; } }
Ini akan menjadi antara muka asas untuk semua strategi pembayaran. Ia mentakrifkan kaedah biasa bayar(), yang akan dilaksanakan oleh semua strategi konkrit.
public abstract class PaymentStrategy { protected PaymentInformation paymentInformation; public PaymentStrategy(PaymentInformation paymentInformation) { this.paymentInformation = paymentInformation; } public abstract void pay(double amount); protected boolean validatePaymentDetails() { return paymentInformation != null && paymentInformation.getPaymentDetails() != null && !paymentInformation.getPaymentDetails().isEmpty(); } }
Here, we implement the concrete strategies for CreditCardPayment, PayPalPayment, and CryptoPayment. Each of these classes implements the pay() method according to the payment type.
public class CreditCardPayment extends PaymentStrategy { public CreditCardPayment(PaymentInformation paymentInformation) { super(paymentInformation); } @Override public void pay(double amount) { if (validatePaymentDetails()) { System.out.println("Paid " + amount + " using Credit Card: " + paymentInformation.getPaymentDetails()); } else { System.out.println("Invalid Credit Card details."); } } }
public class PayPalPayment extends PaymentStrategy { public PayPalPayment(PaymentInformation paymentInformation) { super(paymentInformation); } @Override public void pay(double amount) { if (validatePaymentDetails()) { System.out.println("Paid " + amount + " using PayPal: " + paymentInformation.getPaymentDetails()); } else { System.out.println("Invalid PayPal details."); } } }
public class CryptoPayment extends PaymentStrategy { public CryptoPayment(PaymentInformation paymentInformation) { super(paymentInformation); } @Override public void pay(double amount) { if (validatePaymentDetails()) { System.out.println("Paid " + amount + " using Cryptocurrency to address: " + paymentInformation.getPaymentDetails()); } else { System.out.println("Invalid cryptocurrency address."); } } }
We will use the Factory Pattern to instantiate the appropriate payment strategy based on the payment method. This makes the system more flexible and allows the client to select a payment method at runtime.
public class PaymentStrategyFactory { public static PaymentStrategy createPaymentStrategy(PaymentInformation paymentInformation) { switch (paymentInformation.getPaymentMethod()) { case CREDIT_CARD: return new CreditCardPayment(paymentInformation); case PAYPAL: return new PayPalPayment(paymentInformation); case CRYPTOCURRENCY: return new CryptoPayment(paymentInformation); default: throw new IllegalArgumentException("Unsupported payment method: " + paymentInformation.getPaymentMethod()); } } }
The ShoppingCart class is the context where the payment strategy is used. It delegates the payment responsibility to the strategy selected by the factory.
public class ShoppingCart { private PaymentStrategy paymentStrategy; public ShoppingCart(PaymentInformation paymentInformation) { this.paymentStrategy = PaymentStrategyFactory.createPaymentStrategy(paymentInformation); } public void checkout(double amount) { paymentStrategy.pay(amount); } public void setPaymentInformation(PaymentInformation paymentInformation) { this.paymentStrategy = PaymentStrategyFactory.createPaymentStrategy(paymentInformation); } }
public class Main { public static void main(String[] args) { PaymentInformation cardInfo = new PaymentInformation(PaymentMethod.CREDIT_CARD, "1234-5678-9876"); ShoppingCart cart = new ShoppingCart(cardInfo); cart.checkout(250.0); PaymentInformation paypalInfo = new PaymentInformation(PaymentMethod.PAYPAL, "john.doe@example.com"); cart.setPaymentInformation(paypalInfo); cart.checkout(150.0); PaymentInformation cryptoInfo = new PaymentInformation(PaymentMethod.CRYPTOCURRENCY, "1A2B3C4D5E6F"); cart.setPaymentInformation(cryptoInfo); cart.checkout(500.0); } }
Paid 250.0 using Credit Card: 1234-5678-9876 Paid 150.0 using PayPal: john.doe@example.com Paid 500.0 using Cryptocurrency to address: 1A2B3C4D5E6F
behavior changes without modifying the core logic.
Le Modèle de stratégie est un modèle de conception essentiel pour atteindre la flexibilité et la modularité de votre système. Il fournit un moyen élégant d'encapsuler des algorithmes et permet une flexibilité d'exécution sans modifier le code existant. Que vous construisiez un système de traitement des paiements, une bibliothèque d'algorithmes de tri ou même un moteur d'IA de jeu, le modèle de stratégie peut vous aider à rendre votre code plus maintenable, extensible et plus facile à modifier à mesure que les exigences évoluent.
En tirant parti de l'abstraction, des énumérations et du Factory Pattern, vous pouvez créer des systèmes encore plus robustes, à la fois sécurisés et flexibles.
Atas ialah kandungan terperinci Menguasai Corak Reka Bentuk Strategi: Panduan untuk Pembangun. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!