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.
Qu'est-ce que le modèle de conception de stratégie ?
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.
Idée de base :
- Définir une famille d'algorithmes (stratégies).
- Encapsulez chaque algorithme dans une classe distincte.
- Rendre les algorithmes interchangeables.
- Laissez le client choisir quel algorithme utiliser lors de l'exécution.
Quand et pourquoi devriez-vous utiliser le modèle de stratégie ?
Cas d'utilisation :
Le modèle de stratégie est particulièrement utile lorsque :
- Vous disposez d'une famille d'algorithmes, et le client doit en choisir un à exécuter.
- Vous devez sélectionner différents comportements de manière dynamique (par exemple, tri, tarification, traitement des paiements).
- Le comportement est indépendant du client mais varie selon le contexte.
- Vous voulez éviter les grandes instructions conditionnelles (comme if ou switch) qui décident du comportement à exécuter.
Pourquoi l'utiliser ?
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.
Maintenabilité : il réduit la complexité du code en déléguant différents comportements à des classes de stratégie individuelles, ce qui facilite la maintenance.
Quand ne pas utiliser ?
Algorithmes simples : Si l'algorithme avec lequel vous travaillez est simple et ne change pas, l'utilisation d'un modèle de stratégie peut être excessive.
Trop de stratégies : Si vous disposez d'un grand nombre de stratégies, cela peut conduire à une explosion de classes, ce qui pourrait nuire à la lisibilité et augmenter la complexité.
Changements peu fréquents : Si l'algorithme ne change pas souvent, l'introduction du modèle de stratégie peut introduire une complexité inutile.
Concepts et composants clés du modèle de stratégie
Le modèle de stratégie se compose des éléments clés suivants :
-
Contexte :
- C'est la classe qui va interagir avec un objet Stratégie. Il contient généralement une référence à une stratégie et délègue le comportement réel à cette stratégie.
-
Stratégie :
- Il s'agit d'une interface (ou classe abstraite) qui déclare une méthode d'exécution de l'algorithme. Des stratégies concrètes mettent en œuvre cette interface pour proposer différents comportements.
-
Stratégie concrète :
- Ce sont les classes qui implémentent l'interface Strategy et définissent des algorithmes ou des comportements spécifiques.
Exemple concret : système de traitement des paiements
Considérons un système de traitement des paiements qui permet aux utilisateurs de payer en utilisant différentes méthodes telles que la Carte de crédit, PayPal et la Crypto-monnaie. Le comportement de traitement des paiements diffère pour chaque méthode, mais le contexte (le panier dans ce cas) doit pouvoir traiter les paiements sans se soucier des spécificités de chaque méthode de paiement.
Étape 1 : Définir l'énumération PaymentMethod
Nous allons commencer par utiliser une énumération pour définir différents modes de paiement. Cela rend le choix du mode de paiement sûr et plus facile à gérer.
public enum PaymentMethod { CREDIT_CARD, PAYPAL, CRYPTOCURRENCY; }
Étape 2 : Créer la classe PaymentInformation
Cette classe encapsule les détails requis pour traiter un paiement. Il contient le mode de paiement et les détails du paiement (comme le numéro de carte, l'e-mail ou l'adresse de crypto-monnaie).
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; } }
Étape 3 : Définir l'interface PaymentStrategy
Ce sera l'interface de base pour toutes les stratégies de paiement. Il définit la méthode commune pay(), que toutes les stratégies concrètes mettront en œuvre.
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(); } }
Step 4: Implement Concrete Strategies
Here, we implement the concrete strategies for CreditCardPayment, PayPalPayment, and CryptoPayment. Each of these classes implements the pay() method according to the payment type.
Credit Card Payment Strategy
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."); } } }
PayPal Payment Strategy
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."); } } }
Cryptocurrency Payment Strategy
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."); } } }
Step 5: Factory to Select the Strategy
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()); } } }
Step 6: Client Code (ShoppingCart)
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); } }
Step 7: Running the Example
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); } }
Output:
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
Benefits of the Strategy Pattern
- Flexibility: Strategies can be easily swapped at runtime, allowing dynamic
behavior changes without modifying the core logic.
- Extensibilité : L'ajout de nouvelles stratégies ne nécessite pas de modifier le code existant ; vous créez simplement de nouvelles classes de stratégie.
- Séparation des préoccupations : la stratégie encapsule l'algorithme, de sorte que la classe de contexte (par exemple, ShoppingCart) ne sait pas comment le paiement est traité.
- Maintenabilité : le code est plus propre et plus maintenable car la logique de chaque stratégie est isolée dans sa propre classe.
Inconvénients du modèle de stratégie
- Complexité : l'introduction de plusieurs stratégies augmente le nombre de classes dans le système, ce qui peut rendre la navigation plus difficile, en particulier pour les cas d'utilisation simples.
- Surcharge : Dans certains cas, si le nombre de stratégies est faible, l'utilisation de ce modèle peut introduire une abstraction et une surcharge inutiles.
- Gestion des dépendances : La gestion des dépendances entre les stratégies et leur initialisation peut nécessiter une surcharge supplémentaire, notamment lorsque les stratégies dépendent de ressources externes.
Conclusion
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.
Lectures complémentaires
- Modèles de conception : éléments de logiciels orientés objet réutilisables par Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides – le livre fondateur qui a présenté de nombreux modèles de conception, y compris le modèle de stratégie.
- Head First Design Patterns par Eric Freeman, Elisabeth Robson – une introduction accessible aux modèles de conception avec des exemples pratiques.
- Refactoring : Improving the Design of Existing Code par Martin Fowler – explore la valeur des modèles de conception dans la refactorisation du code pour une meilleure maintenabilité.
以上是掌握策略設計模式:開發人員指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Java在企業級應用中被廣泛使用是因為其平台獨立性。 1)平台獨立性通過Java虛擬機(JVM)實現,使代碼可在任何支持Java的平台上運行。 2)它簡化了跨平台部署和開發流程,提供了更大的靈活性和擴展性。 3)然而,需注意性能差異和第三方庫兼容性,並採用最佳實踐如使用純Java代碼和跨平台測試。

JavaplaysigantroleiniotduetoitsplatFormentence.1)itallowscodeTobewrittenOnCeandrunonVariousDevices.2)Java'secosystemprovidesuseusefidesusefidesulylibrariesforiot.3)

ThesolutiontohandlefilepathsacrossWindowsandLinuxinJavaistousePaths.get()fromthejava.nio.filepackage.1)UsePaths.get()withSystem.getProperty("user.dir")andtherelativepathtoconstructthefilepath.2)ConverttheresultingPathobjecttoaFileobjectifne

Java'splatFormIndenceistificantBecapeitAllowSitallowsDevelostWriTecoDeonCeandRunitonAnyPlatFormwithAjvm.this“ writeonce,runanywhere”(era)櫥櫃櫥櫃:1)交叉plat formcomplibility cross-platformcombiblesible,enablingDeploymentMentMentMentMentAcrAptAprospOspOspOssCrossDifferentoSswithOssuse; 2)

Java適合開發跨服務器web應用。 1)Java的“一次編寫,到處運行”哲學使其代碼可在任何支持JVM的平台上運行。 2)Java擁有豐富的生態系統,包括Spring和Hibernate等工具,簡化開發過程。 3)Java在性能和安全性方面表現出色,提供高效的內存管理和強大的安全保障。

JVM通過字節碼解釋、平台無關的API和動態類加載實現Java的WORA特性:1.字節碼被解釋為機器碼,確保跨平台運行;2.標準API抽像操作系統差異;3.類在運行時動態加載,保證一致性。

Java的最新版本通過JVM優化、標準庫改進和第三方庫支持有效解決平台特定問題。 1)JVM優化,如Java11的ZGC提升了垃圾回收性能。 2)標準庫改進,如Java9的模塊系統減少平台相關問題。 3)第三方庫提供平台優化版本,如OpenCV。

JVM的字節碼驗證過程包括四個關鍵步驟:1)檢查類文件格式是否符合規範,2)驗證字節碼指令的有效性和正確性,3)進行數據流分析確保類型安全,4)平衡驗證的徹底性與性能。通過這些步驟,JVM確保只有安全、正確的字節碼被執行,從而保護程序的完整性和安全性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

WebStorm Mac版
好用的JavaScript開發工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

禪工作室 13.0.1
強大的PHP整合開發環境

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能