Menu
Coddy logo textTech

Patron Strategy

Fait partie de la section Programmation orientée objet du Journey Python de Coddy. Leçon 48 sur 64.

Le patron Strategy définit une famille d’algorithmes, encapsule chacun d’eux et les rend interchangeables. Vous pouvez changer d’algorithme lors de l’exécution sans modifier le code client.

Voici des classes de stratégie simples pour différentes méthodes de paiement :

class CreditCard:
    def pay(self, amount):
        return f"Paid ${amount} with Credit Card"

class PayPal:
    def pay(self, amount):
        return f"Paid ${amount} with PayPal"

class Bitcoin:
    def pay(self, amount):
        return f"Paid ${amount} with Bitcoin"

Chaque stratégie implémente la même méthode (pay), mais avec un comportement différent.

Créez une classe de contexte qui utilise des stratégies :

class ShoppingCart:
    def __init__(self):
        self.total = 0
        self.payment_strategy = None
    
    def add_item(self, price):
        self.total += price
    
    def set_payment_strategy(self, strategy):
        self.payment_strategy = strategy
    
    def checkout(self):
        return self.payment_strategy.pay(self.total)

La classe de contexte peut basculer entre différentes stratégies de paiement.

Utilisez le patron de stratégie :

cart = ShoppingCart()
cart.add_item(50)
cart.add_item(30)

# Utiliser la stratégie de carte de crédit
cart.set_payment_strategy(CreditCard())
print(cart.checkout())

# Passer à la stratégie PayPal
cart.set_payment_strategy(PayPal())
print(cart.checkout())

Créez un autre exemple avec des stratégies de tri :

class BubbleSort:
    def sort(self, data):
        return f"Bubble sorted: {sorted(data)}"

class QuickSort:
    def sort(self, data):
        return f"Quick sorted: {sorted(data)}"

class Sorter:
    def __init__(self, strategy):
        self.strategy = strategy
    
    def set_strategy(self, strategy):
        self.strategy = strategy
    
    def sort_data(self, data):
        return self.strategy.sort(data)

# Utiliser différentes stratégies de tri
numbers = [3, 1, 4, 1, 5]

sorter = Sorter(BubbleSort())
print(sorter.sort_data(numbers))

sorter.set_strategy(QuickSort())
print(sorter.sort_data(numbers))

Sortie :

Paid $80 with Credit Card
Paid $80 with PayPal
Bubble sorted: [1, 1, 3, 4, 5]
Quick sorted: [1, 1, 3, 4, 5]

Point clé : le modèle Stratégie vous permet de remplacer les algorithmes lors de l’exécution. Définissez différentes stratégies avec la même interface, puis laissez la classe de contexte choisir laquelle utiliser. Votre code devient ainsi flexible et facile à étendre avec de nouveaux algorithmes, sans modifier le code existant.

challenge icon

Défi

Moyen

Implémentez une nouvelle stratégie BitcoinPayment pour notre système d’achat.

Votre tâche consiste à :

  1. Créer une classe BitcoinPayment qui implémente PaymentStrategy
    • Elle doit accepter un wallet_address dans le constructeur
    • La méthode pay doit afficher exactement : Paying $X using Bitcoin wallet: Y, où X est le montant et Y est l’adresse du portefeuille
    • La méthode pay doit retourner True après l’affichage
  2. Écrire une fonction main qui :
    • Crée un panier d’achat
    • Ajoute au panier un ordinateur portable coûtant $1200 et un casque coûtant $100
    • Crée un BitcoinPayment avec l’adresse de portefeuille "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
    • Définit cette stratégie de paiement sur le panier
    • Appelle la méthode checkout

Le code de départ inclut déjà if __name__ == "__main__": en bas du fichier. Vous n’avez pas besoin de l’ajouter vous-même. Il s’agit d’une convention Python qui garantit que votre fonction main() s’exécute uniquement lorsque le fichier est exécuté directement (et non lorsqu’il est importé par un autre module). Définissez simplement votre fonction main() et le bloc fourni l’appellera automatiquement.

Suivez la même structure que celle présentée dans les exemples de la leçon.

Essayez vous-même

from abc import ABC, abstractmethod

class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount):
        pass

class CreditCardPayment(PaymentStrategy):
    def __init__(self, card_number, expiry_date, cvv):
        self.card_number = card_number
        self.expiry_date = expiry_date
        self.cvv = cvv
        
    def pay(self, amount):
        print(f"Paying ${amount} using Credit Card: {self.card_number}")
        return True

class PayPalPayment(PaymentStrategy):
    def __init__(self, email, password):
        self.email = email
        self.password = password
        
    def pay(self, amount):
        print(f"Paying ${amount} using PayPal account: {self.email}")
        return True

class ShoppingCart:
    def __init__(self):
        self.items = []
        self.payment_strategy = None
    
    def add_item(self, item, price):
        self.items.append({"item": item, "price": price})
    
    def set_payment_strategy(self, payment_strategy):
        self.payment_strategy = payment_strategy
    
    def checkout(self):
        total = sum(item["price"] for item in self.items)
        if self.payment_strategy:
            return self.payment_strategy.pay(total)
        else:
            raise ValueError("No payment strategy set")

# Create your BitcoinPayment strategy class here


if __name__ == "__main__":
    main()
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Compilateur Python en ligne