Strategy Pattern memungkinkan kamu memilih algoritma atau behavior saat runtime. Alih-alih hardcode satu cara, kamu menyediakan beberapa "strategi" yang bisa ditukar.
Analogi: Navigasi GPS. Kamu pilih strategi: rute tercepat, rute terdekat, atau hindari tol. Tujuan sama, cara berbeda.
Masalah yang diselesaikan:
- Kode penuh
if/elseuntuk memilih perilaku berbeda - Menambah perilaku baru memerlukan mengubah kode yang sudah ada
- Logika yang seharusnya terpisah jadi tercampur
Tanpa Strategy (kode berantakan):
// BURUK — if/else bertumpuk
function calculatePrice(price, customerType) {
if (customerType === "regular") {
return price;
} else if (customerType === "premium") {
return price * 0.9;
} else if (customerType === "vip") {
return price * 0.8;
} else if (customerType === "employee") {
return price * 0.7;
}
// Setiap tipe baru = tambah else if...
}
Dengan Strategy Pattern:
// Setiap strategi adalah fungsi terpisah
const pricingStrategies = {
regular: (price) => price,
premium: (price) => price * 0.9,
vip: (price) => price * 0.8,
employee: (price) => price * 0.7,
};
function calculatePrice(price, customerType) {
const strategy = pricingStrategies[customerType];
if (!strategy) throw new Error(`Unknown type: ${customerType}`);
return strategy(price);
}
console.log(calculatePrice(100000, "vip")); // 80000
// Menambah strategi baru? Cukup tambah 1 baris:
pricingStrategies.student = (price) => price * 0.85;
Contoh: Validasi form
const validators = {
required: (value) => value.trim() !== "" || "Wajib diisi",
email: (value) => /^[^@]+@[^@]+$/.test(value) || "Email tidak valid",
minLength: (min) => (value) =>
value.length >= min || `Minimal ${min} karakter`,
maxLength: (max) => (value) =>
value.length <= max || `Maksimal ${max} karakter`,
};
function validate(value, rules) {
const errors = [];
for (const rule of rules) {
const result = rule(value);
if (result !== true) errors.push(result);
}
return errors;
}
const emailRules = [
validators.required,
validators.email,
validators.minLength(5),
];
console.log(validate("", emailRules));
// ["Wajib diisi", "Email tidak valid", "Minimal 5 karakter"]
console.log(validate("[email protected]", emailRules));
// [] — valid!
Contoh: Sorting strategy
const sortStrategies = {
byName: (a, b) => a.name.localeCompare(b.name),
byPrice: (a, b) => a.price - b.price,
byPriceDesc: (a, b) => b.price - a.price,
byRating: (a, b) => b.rating - a.rating,
};
function sortProducts(products, strategyName) {
return [...products].sort(sortStrategies[strategyName]);
}
const products = [
{ name: "Laptop", price: 15000000, rating: 4.5 },
{ name: "Mouse", price: 250000, rating: 4.8 },
{ name: "Keyboard", price: 750000, rating: 4.2 },
];
sortProducts(products, "byPrice");
// Mouse → Keyboard → Laptop
Di JavaScript, Strategy Pattern sangat natural karena fungsi adalah first-class citizen. Kamu tinggal simpan fungsi di object atau array, lalu panggil sesuai kebutuhan.
Kapan pakai Strategy Pattern:
- Saat ada banyak variasi behavior yang bisa ditukar
- Saat
if/elseatauswitchmulai membengkak - Saat ingin menambah behavior baru tanpa mengubah kode yang ada
- Form validation, sorting, pricing, formatting, authentication