1. Singleton Pattern
Tugas: Buat kelas ConfigurationManager
yang memastikan hanya ada satu instance yang bisa diakses global.
- Simpan konfigurasi seperti
appName
danversion
. - Pastikan thread-safe.
Contoh Penggunaan:
ConfigurationManager config = ConfigurationManager.getInstance();
config.setAppName("MyApp");
System.out.println(config.getAppName()); // Output: MyApp
<details> <summary>Solusi</summary>
public class ConfigurationManager {
private static volatile ConfigurationManager instance;
private String appName;
private String version;
private ConfigurationManager() {}
public static ConfigurationManager getInstance() {
if (instance == null) {
synchronized (ConfigurationManager.class) {
if (instance == null) {
instance = new ConfigurationManager();
}
}
}
return instance;
}
// Getter & Setter
}
</details>
2. Factory Method Pattern
Tugas: Buat factory untuk menghasilkan objek pembayaran (CreditCardPayment
, PayPalPayment
) berdasarkan jenis.
PaymentProcessor creditCard = PaymentFactory.createPayment("creditcard");
creditCard.process(100.0); // Output: "Processing Credit Card payment: $100.0"
<details> <summary>Solusi</summary>
interface PaymentProcessor {
void process(double amount);
}
class CreditCardPayment implements PaymentProcessor {
@Override
public void process(double amount) {
System.out.println("Processing Credit Card payment: $" + amount);
}
}
class PaymentFactory {
public static PaymentProcessor createPayment(String type) {
return switch (type.toLowerCase()) {
case "creditcard" -> new CreditCardPayment();
case "paypal" -> new PayPalPayment();
default -> throw new IllegalArgumentException("Invalid payment type");
};
}
}
</details>
3. Observer Pattern
Tugas: Implementasikan sistem notifikasi di mana NewsAgency
mengirim berita ke Subscriber
(contoh: EmailSubscriber, SMSSubscriber).
NewsAgency agency = new NewsAgency();
agency.addSubscriber(new EmailSubscriber("user@example.com"));
agency.publishNews("Java 21 Released!");
// Output: "Email to user@example.com: Java 21 Released!"
<details> <summary>Solusi</summary>
interface Subscriber {
void update(String news);
}
class NewsAgency {
private List<Subscriber> subscribers = new ArrayList<>();
public void addSubscriber(Subscriber s) {
subscribers.add(s);
}
public void publishNews(String news) {
subscribers.forEach(s -> s.update(news));
}
}
class EmailSubscriber implements Subscriber {
private String email;
public EmailSubscriber(String email) {
this.email = email;
}
@Override
public void update(String news) {
System.out.println("Email to " + email + ": " + news);
}
}
</details>
4. Decorator Pattern
Tugas: Tambahkan fitur tambahan ke objek Coffee
(contoh: MilkDecorator
, SugarDecorator
).
Coffee coffee = new BasicCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription()); // Output: "Basic Coffee, Milk, Sugar"
System.out.println(coffee.cost()); // Output: 3.5 (2.0 + 1.0 + 0.5)
<details> <summary>Solusi</summary>
interface Coffee {
String getDescription();
double cost();
}
class BasicCoffee implements Coffee {
@Override
public String getDescription() {
return "Basic Coffee";
}
@Override
public double cost() {
return 2.0;
}
}
abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
}
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription() + ", Milk";
}
@Override
public double cost() {
return decoratedCoffee.cost() + 1.0;
}
}
</details>
5. Strategy Pattern
Tugas: Implementasikan algoritma sorting yang berbeda (BubbleSort
, QuickSort
) dan pilih strategi secara dinamis.
SortingContext context = new SortingContext(new BubbleSort());
context.sort(Arrays.asList(3, 1, 4)); // Output: "Sorting using BubbleSort"
context.setStrategy(new QuickSort());
context.sort(Arrays.asList(5, 2, 9)); // Output: "Sorting using QuickSort"
<details> <summary>Solusi</summary>
interface SortingStrategy {
void sort(List<Integer> list);
}
class BubbleSort implements SortingStrategy {
@Override
public void sort(List<Integer> list) {
System.out.println("Sorting using BubbleSort");
// Implementasi bubble sort
}
}
class SortingContext {
private SortingStrategy strategy;
public SortingContext(SortingStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(SortingStrategy strategy) {
this.strategy = strategy;
}
public void sort(List<Integer> list) {
strategy.sort(list);
}
}
</details>
6. Adapter Pattern
Tugas: Buat adapter untuk mengonversi antarmuka LegacyUser
ke ModernUser
.
LegacyUser legacyUser = new LegacyUser("john_doe", "John Doe");
ModernUser modernUser = new UserAdapter(legacyUser);
System.out.println(modernUser.getFullName()); // Output: "John Doe"
<details> <summary>Solusi</summary>
class LegacyUser {
private String username;
private String fullName;
public LegacyUser(String username, String fullName) {
this.username = username;
this.fullName = fullName;
}
public String getUsername() { return username; }
public String getFullName() { return fullName; }
}
interface ModernUser {
String getFullName();
}
class UserAdapter implements ModernUser {
private LegacyUser legacyUser;
public UserAdapter(LegacyUser legacyUser) {
this.legacyUser = legacyUser;
}
@Override
public String getFullName() {
return legacyUser.getFullName();
}
}
</details>
Tantangan: MVC (Model-View-Controller)
Tugas: Implementasikan pola MVC sederhana untuk aplikasi to-do list:
- Model: Menyimpan daftar tugas.
- View: Menampilkan tugas ke konsol.
- Controller: Menangani input pengguna (tambah/hapus tugas).
Contoh Output:
Tasks:
1. Belajar Java
2. Olahraga
<details> <summary>Hint</summary>
- Gunakan Observer Pattern untuk update view saat model berubah.
- Gunakan Command Pattern untuk operasi tambah/hapus tugas.
</details>
Tips Belajar:
- Pahami Kategori Design Patterns:
- Creational (Singleton, Factory, Builder)
- Structural (Adapter, Decorator, Facade)
- Behavioral (Observer, Strategy, Command)
- Identifikasi Masalah yang Cocok:
Contoh:- Butuh satu instance? → Singleton
- Inisialisasi objek kompleks? → Builder
- Perubahan perilaku runtime? → Strategy
- Baca Buku “Design Patterns: Elements of Reusable Object-Oriented Software” (Gang of Four).
- Latihan Refactoring: Ambil kode yang sudah ada dan coba terapkan pola yang sesuai.
- Buat Diagram UML untuk memvisualisasikan hubungan antar kelas.
Semangat! 😊 Coba implementasikan solusi sendiri sebelum melihat contoh, lalu bandingkan hasilnya.