Menu
Coddy logo textTech

Strategy Kalıbı

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 95 / 104.

Strategy kalıbı, bir algoritma ailesi tanımlar, her birini kapsüller ve bunların birbirleriyle değiştirilebilir olmasını sağlar. Bu, kodunu değiştirmeden bir nesnenin davranışını çalışma zamanında değiştirmenize olanak tanır; algoritma, onu kullanan istemcilerden bağımsız olarak değişir.

Örüntü üç bölümden oluşur: algoritma yöntemini bildiren bir Strateji arayüzü, farklı varyasyonları uygulayan Somut Stratejiler ve bir strateji kullanan bir Bağlam:

#include <iostream>
#include <memory>

// Strateji arayüzü
class PaymentStrategy {
public:
    virtual void pay(int amount) = 0;
    virtual ~PaymentStrategy() = default;
};

// Somut stratejiler
class CreditCardPayment : public PaymentStrategy {
public:
    void pay(int amount) override {
        std::cout << "Paid " << amount << " via Credit Card\n";
    }
};

class PayPalPayment : public PaymentStrategy {
public:
    void pay(int amount) override {
        std::cout << "Paid " << amount << " via PayPal\n";
    }
};

// Bağlam
class ShoppingCart {
    std::unique_ptr<PaymentStrategy> strategy;
public:
    void setPaymentMethod(std::unique_ptr<PaymentStrategy> s) {
        strategy = std::move(s);
    }
    
    void checkout(int total) {
        if (strategy) strategy->pay(total);
    }
};

int main() {
    ShoppingCart cart;
    
    cart.setPaymentMethod(std::make_unique<CreditCardPayment>());
    cart.checkout(100);
    
    cart.setPaymentMethod(std::make_unique<PayPalPayment>());
    cart.checkout(50);
}

ShoppingCart hangi ödeme yöntemini kullandığını bilmez - yalnızca ayarlanmış olan strateji üzerinde pay() çağrısı yapar. setPaymentMethod() ile stratejileri çalışma zamanında değiştirebilir, böylece sistemi esnek hâle getirip yeni ödeme seçenekleriyle genişletmeyi kolaylaştırabilirsin.

Belirli bir görev için birden fazla algoritmanız olduğunda ve bunlar arasında dinamik olarak geçiş yapmak istediğinizde ya da davranışı seçmek için koşullu ifadelerden kaçınmak istediğinizde Strategy kullanın.

challenge icon

Görev

Kolay

Farklı gönderim yöntemlerine göre teslimat maliyetlerini hesaplamak için Strategy desenini kullanan bir Gönderim Hesaplayıcısı oluşturalım. Bu, algoritmaları çalışma zamanında değiştirmeniz gereken pratik bir senaryodur: aynı paket kara, hava veya ekspres yoluyla gönderilebilir ve her yöntemin kendine özgü fiyatlandırma mantığı vardır.

Kodunuzu üç dosyaya ayıracaksınız:

  • ShippingStrategy.h: Strateji arayüzünüzü ve somut gönderim stratejilerini tanımlayın.

    Saf sanal bir ShippingStrategy metoduna sahip, gönderim maliyetini double olarak döndüren ve sanal bir yıkıcı içeren soyut bir calculateCost(double weight) sınıfı oluşturun.

    Ardından üç somut strateji uygulayın:

    • GroundShipping: ağırlık birimi başına 1.5 maliyet (weight * 1.5)
    • AirShipping: ağırlık birimi başına 4.0 maliyet (weight * 4.0)
    • ExpressShipping: ağırlık birimi başına 6.5 maliyet ve ayrıca sabit 10.0 ücret (weight * 6.5 + 10.0)
  • ShippingService.h: Bir gönderim stratejisi kullanan bağlam sınıfını oluşturun.

    ShippingService sınıfınız, özel bir üye olarak std::unique_ptr<ShippingStrategy> tutmalıdır. Şunları uygulayın:

    • Gönderim yöntemini değiştirmek için bir setStrategy(std::unique_ptr<ShippingStrategy> strategy) metodu
    • Geçerli stratejiyi kullanarak maliyeti hesaplayıp döndüren bir calculateShipping(double weight) metodu

    calculateShipping çağrıldığında hiçbir strateji ayarlanmamışsa 0.0 döndürün.

  • main.cpp: Stratejilerin çalışma zamanında değiştirilmesini gösterin.

    İki girdi okuyun:

    1. Paket ağırlığı (double)
    2. Gönderim yöntemi: ground, air veya express

    Bir ShippingService oluşturun ve giriş yöntemine göre uygun stratejiyi ayarlayın. Gönderim maliyetini hesaplayıp yazdırın.

    Ardından farklı bir stratejiye geçin (girdi air değilse air, aksi takdirde ground kullanın) ve aynı ağırlık için maliyeti tekrar hesaplayın. Bu, stratejileri çalışma zamanında değiştirmenin gücünü gösterir.

    Her maliyeti kendi satırında, tam olarak bir ondalık basamakla ve yöntem adı önde olacak şekilde yazdırın:

    [Method]: $[cost]

Örneğin, 5.0 ve ground girdileriyle:

Ground: $7.5
Air: $20.0

3.0 ve express girdileriyle:

Express: $29.5
Air: $12.0

10.0 ve air girdileriyle:

Air: $40.0
Ground: $15.0

ShippingService sınıfının her fiyatlandırma algoritmasının ayrıntılarını bilmesinin gerekmediğine dikkat edin. Yalnızca o anda ayarlanmış olan stratejiye yetki verir. Hizmet sınıfını hiç değiştirmeden yeni gönderim yöntemlerini (drone teslimatı veya aynı gün teslimat gibi) kolayca ekleyebilirsiniz.

Kendin dene

#include <iostream>
#include <string>
#include <iomanip>
#include <memory>
#include "ShippingStrategy.h"
#include "ShippingService.h"

int main() {
    double weight;
    std::string method;
    
    std::cin >> weight;
    std::cin >> method;
    
    // Çıktıyı 1 ondalık basamağa ayarla
    std::cout << std::fixed << std::setprecision(1);
    
    ShippingService service;
    
    // TODO: Giriş yöntemine göre ("ground", "air" veya "express"):
    // 1. Servis üzerinde uygun stratejiyi ayarla
    // 2. Maliyeti hesapla ve şu formatta yazdır: "[Method]: $[cost]"
    
    // TODO: Farklı bir stratejiye geç:
    // - Giriş "air" ise, GroundShipping'e geç
    // - Aksi takdirde, AirShipping'e geç
    // Yeni maliyeti hesapla ve yazdır
    
    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online C++ derleyicisi