Strategy Pattern:
Situasi Penggunaan:
Misalnya kamu sedang membuat aplikasi e-commerce yang memiliki beberapa
metode diskon: diskon persentase, diskon nominal tetap, dan tanpa diskon. Kita
ingin agar strategi diskon ini bisa diubah tanpa mengubah kode utama, dan Strategy
Pattern cocok banget buat ini.
public interface DiscountStrategy {
double applyDiscount(double price);
public class PercentageDiscount implements DiscountStrategy {
private double percentage;
public PercentageDiscount(double percentage) {
[Link] = percentage;
}
@Override
public double applyDiscount(double price) {
return price - (price * percentage / 100);
public class FixedDiscount implements DiscountStrategy {
private double amount;
public FixedDiscount(double amount) {
[Link] = amount;
@Override
public double applyDiscount(double price) {
return price - amount;
public class NoDiscount implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price;
}
CONTEXT CLASS
public class ShoppingCart {
private DiscountStrategy discountStrategy;
public ShoppingCart(DiscountStrategy discountStrategy) {
[Link] = discountStrategy;
public void setDiscountStrategy(DiscountStrategy discountStrategy) {
[Link] = discountStrategy;
public double checkout(double totalPrice) {
return [Link](totalPrice);
MAIN
public class Main {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart(new NoDiscount());
double total = 200.0;
[Link]("Total tanpa diskon: " + [Link](total));
[Link](new PercentageDiscount(10));
[Link]("Total dengan diskon 10%: " + [Link](total));
[Link](new FixedDiscount(30));
[Link]("Total dengan diskon Rp30.000: " + [Link](total));
DECORATOR PATTERN:
Apa itu Decorator Pattern?
Decorator Pattern digunakan untuk menambahkan fitur baru ke objek secara
dinamis tanpa mengubah struktur kelas aslinya. Cocok saat kamu ingin membuat
banyak kombinasi fitur tanpa bikin subclass yang banyak.
Situasi Penggunaan:
Bayangkan kamu bikin aplikasi pemesanan kopi. Ada kopi dasar, lalu pelanggan bisa
menambahkan topping seperti susu, coklat, atau krim. Kita ingin menambahkan
fitur-fitur ini tanpa mengubah kelas Kopi utama.
Component Interface
public interface Coffee {
String getDescription();
double getCost();
Concrete Component (Kopi Dasar)
public class BasicCoffee implements Coffee {
@Override
public String getDescription() {
return "Kopi Hitam";
@Override
public double getCost() {
return 15000;
}
Abstract Decorator
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
[Link] = coffee;
public String getDescription() {
return [Link]();
public double getCost() {
return [Link]();
Concrete Decorators (Topping)
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
@Override
public String getDescription() {
return [Link]() + ", Susu";
@Override
public double getCost() {
return [Link]() + 5000;
public class ChocolateDecorator extends CoffeeDecorator {
public ChocolateDecorator(Coffee coffee) {
super(coffee);
@Override
public String getDescription() {
return [Link]() + ", Coklat";
@Override
public double getCost() {
return [Link]() + 7000;
}
}
MAIN
public class Main {
public static void main(String[] args) {
Coffee myCoffee = new BasicCoffee();
[Link]([Link]() + " = Rp" +
[Link]());
myCoffee = new MilkDecorator(myCoffee);
[Link]([Link]() + " = Rp" +
[Link]());
myCoffee = new ChocolateDecorator(myCoffee);
[Link]([Link]() + " = Rp" +
[Link]());
}
FACTORY PATTERN:
Factory Pattern adalah creational pattern yang menyediakan cara untuk
membuat objek tanpa harus menyebutkan kelas spesifiknya secara
langsung. Cocok kalau kamu mau bikin objek dari banyak kelas turunan
berdasarkan kondisi tertentu.
Situasi Penggunaan:
Bayangkan kamu bikin aplikasi transportasi. User bisa pilih Motor,
Mobil, atau Sepeda. Daripada pakai if-else panjang di mana-mana,
lebih rapi kalau bikin satu Factory yang tangani semua objek
kendaraan.
Interface atau Superclass
public interface Vehicle {
void drive();
Kelas Implementasi (Produk Konkret)
public class Motor implements Vehicle {
@Override
public void drive() {
[Link]("Mengendarai motor.");
}
public class Mobil implements Vehicle {
@Override
public void drive() {
[Link]("Mengendarai mobil.");
public class Sepeda implements Vehicle {
@Override
public void drive() {
[Link]("Mengendarai sepeda.");
Factory Class
public class VehicleFactory {
public static Vehicle createVehicle(String type) {
switch ([Link]()) {
case "motor":
return new Motor();
case "mobil":
return new Mobil();
case "sepeda":
return new Sepeda();
default:
throw new IllegalArgumentException("Jenis kendaraan
tidak dikenal: " + type);
Penggunaan di main()
public class Main {
public static void main(String[] args) {
Vehicle v1 = [Link]("motor");
[Link]();
Vehicle v2 = [Link]("mobil");
[Link]();
Vehicle v3 = [Link]("sepeda");
[Link]();
}
Apa itu Observer Pattern?
Observer Pattern adalah behavioral pattern di mana satu objek (subject) akan
memberi tahu banyak objek lain (observers) jika terjadi perubahan. Cocok kalau
kamu ingin hubungan satu ke banyak (one-to-many), misalnya:
Jika cuaca berubah, semua aplikasi cuaca yang
berlangganan akan diberi tahu.
Situasi Penggunaan:
Bayangkan kamu punya sistem notifikasi cuaca. Ada objek WeatherStation
(Subject), dan beberapa display seperti PhoneDisplay, LaptopDisplay, dll
(Observers). Ketika suhu berubah, semua display otomatis update.
Interface Observer
public interface Observer {
void update(float temperature);
}
Interface Subject
public interface Subject {
void addObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
Concrete Subject (WeatherStation)
import [Link];
import [Link];
public class WeatherStation implements Subject {
private List<Observer> observers = new ArrayList<>();
private float temperature;
@Override
public void addObserver(Observer o) {
[Link](o);
@Override
public void removeObserver(Observer o) {
[Link](o);
}
@Override
public void notifyObservers() {
for (Observer o : observers) {
[Link](temperature);
public void setTemperature(float temperature) {
[Link] = temperature;
notifyObservers();
Concrete Observers (Display)
public class PhoneDisplay implements Observer {
@Override
public void update(float temperature) {
[Link]("Phone Display: Suhu sekarang " +
temperature + "°C");
public class LaptopDisplay implements Observer {
@Override
public void update(float temperature) {
[Link]("Laptop Display: Suhu sekarang " +
temperature + "°C");
Penggunaan di main()
public class Main {
public static void main(String[] args) {
WeatherStation station = new WeatherStation();
Observer phone = new PhoneDisplay();
Observer laptop = new LaptopDisplay();
[Link](phone);
[Link](laptop);
[Link](30.5f); // semua observer akan dapat
update
[Link](27.0f);