Pola Strategy
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 95 dari 104.
Pola Strategy mendefinisikan keluarga algoritma, mengenkapsulasi setiap algoritma, dan membuatnya dapat saling dipertukarkan. Ini memungkinkan kamu mengubah perilaku object saat program berjalan tanpa mengubah kodemu. Algoritma tersebut bervariasi secara independen dari client yang menggunakannya.
Pola ini terdiri dari tiga bagian: interface Strategy yang mendeklarasikan method algoritma, Strategi Konkret yang menerapkan variasi berbeda, dan Konteks yang menggunakan sebuah strategi:
#include <iostream>
#include <memory>
// Antarmuka strategi
class PaymentStrategy {
public:
virtual void pay(int amount) = 0;
virtual ~PaymentStrategy() = default;
};
// Strategi konkret
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";
}
};
// Konteks
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 tidak tahu metode pembayaran mana yang digunakannya. ShoppingCart hanya memanggil pay() pada strategi yang ditetapkan. Kamu dapat mengganti strategi saat program berjalan dengan setPaymentMethod(), sehingga sistem menjadi fleksibel dan mudah diperluas dengan opsi pembayaran baru.
Gunakan Strategy saat kamu memiliki beberapa algoritma untuk tugas tertentu dan ingin beralih di antara algoritma tersebut secara dinamis, atau saat kamu ingin menghindari pernyataan percabangan untuk memilih perilaku.
Tantangan
MudahMari buat Kalkulator Pengiriman yang menggunakan pola Strategy untuk menghitung biaya pengiriman berdasarkan berbagai metode pengiriman. Ini adalah skenario praktis ketika kamu perlu mengganti algoritma saat program berjalan: paket yang sama mungkin dikirim melalui darat, udara, atau ekspres, masing-masing dengan logika harganya sendiri.
Kamu akan menyusun kodemu dalam tiga file:
ShippingStrategy.h: Definisikan antarmuka strategy dan strategy pengiriman konkret.Buat class abstrak
ShippingStrategydengan method virtual murnicalculateCost(double weight)yang mengembalikan biaya pengiriman sebagai double, serta destructor virtual.Lalu implementasikan tiga strategy konkret:
GroundShipping: biayanya1.5per satuan berat (weight * 1.5)AirShipping: biayanya4.0per satuan berat (weight * 4.0)ExpressShipping: biayanya6.5per satuan berat ditambah biaya tetap sebesar10.0(weight * 6.5 + 10.0)
ShippingService.h: Buat class konteks yang menggunakan strategy pengiriman.Class
ShippingServicemilikmu harus menyimpanstd::unique_ptr<ShippingStrategy>sebagai member privat. Implementasikan:- Method
setStrategy(std::unique_ptr<ShippingStrategy> strategy)untuk mengganti metode pengiriman - Method
calculateShipping(double weight)yang menggunakan strategy saat ini untuk menghitung dan mengembalikan biayanya
Jika belum ada strategy yang ditetapkan saat
calculateShippingdipanggil, kembalikan0.0.- Method
main.cpp: Tunjukkan cara mengganti strategy saat program berjalan.Baca dua input:
- Berat paket (double)
- Metode pengiriman:
ground,air, atauexpress
Buat
ShippingServicedan tetapkan strategy yang sesuai berdasarkan metode input. Hitung dan cetak biaya pengiriman.Lalu ganti dengan strategy yang berbeda (gunakan
airjika inputnya bukanair, jika tidak, gunakanground) dan hitung kembali biayanya untuk berat yang sama. Ini menunjukkan manfaat mengganti strategy saat program berjalan.Cetak setiap biaya pada baris tersendiri dengan tepat satu angka desimal, diawali dengan nama metode:
[Method]: $[cost]
Contohnya, dengan input 5.0 dan ground:
Ground: $7.5
Air: $20.0Dengan input 3.0 dan express:
Express: $29.5
Air: $12.0Dengan input 10.0 dan air:
Air: $40.0
Ground: $15.0Perhatikan bahwa ShippingService tidak perlu mengetahui detail setiap algoritma penetapan harga. Class ini cukup mendelegasikan tugas kepada strategy yang sedang ditetapkan. Kamu bisa dengan mudah menambahkan metode pengiriman baru (seperti pengiriman dengan drone atau pengiriman di hari yang sama) tanpa mengubah class layanan sama sekali.
Coba sendiri
#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;
// Atur output agar menampilkan 1 angka di belakang koma
std::cout << std::fixed << std::setprecision(1);
ShippingService service;
// TODO: Berdasarkan method input ("ground", "air", atau "express"):
// 1. Atur strategi yang sesuai pada service
// 2. Hitung dan tampilkan biaya dengan format: "[Method]: $[cost]"
// TODO: Ganti ke strategi lain:
// - Jika input adalah "air", ganti ke GroundShipping
// - Jika tidak, ganti ke AirShipping
// Hitung dan tampilkan biaya baru
return 0;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar-Dasar OOP
File EksternalBuild dan Kompilasi C++File Header dan File SourceNamespace dan CakupanPengantar OOP dalam C++class vs objectPointer 'this'method (Fungsi Anggota)Atribut (Anggota Data)Dasar Ctor dan DtorRingkasan: Kalkulator Sederhana4Properti class
Anggota instance vs staticGetter dan setterFungsi anggota constKata kunci mutableMethod dan variabel staticFungsi dan class friendRangkuman, Pengelola Rekening Bank7Pewarisan
Pewarisan DasarTingkat Akses pada PewarisanUrutan Pemanggilan Ctor & DtorPenimpaan methodFungsi Virtual & VTablePewarisan BergandaPewarisan VirtualRangkuman: Hierarki Karyawan10Gambaran Umum STL
Gambaran Umum dan Filosofi STLKontainer STLIteratorAlgoritma STLFunctor dan Ekspresi LambdaRangkuman: Frekuensi Kata13Pola Desain Bagian 1
Pengantar Pola DesainPola SingletonFactory dan Abstract FactoryPola BuilderPola ObserverPola Strategy2Manajemen Memori
Memori Stack vs HeapPointer dan ReferenceMemori Dinamis (new/delete)Smart Pointer di C++RAII di C++Rangkuman: Pengelola Array Dinamis5Enkapsulasi
Penentu Akses dalam C++Penentu Akses secara MendalamPenyembunyian Informasistruct vs classNested dan Inner classRangkuman, Sistem Catatan Siswa8Polimorfisme
Polimorfisme saat Compile vs RuntimeOverloading FungsiMeninjau Kembali Fungsi VirtualFungsi Virtual MurniKelas AbstrakDesain Interface di C++Casting Dinamis & RTTIRangkuman: Kalkulator Bentuk3Konstruktor & Destruktor
Konstruktor DefaultKonstruktor BerparameterKonstruktor SalinKonstruktor PindahDaftar Inisialisasi KonstruktorKonstruktor DelegasiKupas Tuntas DestruktorAturan Tiga, Lima, dan NolRangkuman: class String6Overloading Operator
Pengantar Overloading OperatorOverloading Operator AritmetikaOverloading Operator PerbandinganOperator StreamOverloading Operator PenugasanOverloading Operator [] dan ()Operator Konversi TipeRingkasan, class Matrix9Template
Template FungsiTemplate classSpesialisasi TemplateTemplate VariadikDasar SFINAE & Type TraitsRangkuman, Container GenerikLatihan sendiri: Compiler C++ online