Arsitektur Bersih Berbasis Peristiwa
Integrasikan pola berbasis peristiwa ke dalam Arsitektur Bersih dengan menggunakan peristiwa domain untuk meningkatkan pemisahan dan skalabilitas.
Arsitektur Bersih Berbasis Peristiwa adalah pelajaran Clean Architecture & Design Patterns in Practice gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Clean Architecture & Design Patterns in Practice, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Clean Architecture & Design Patterns in Practice mencakup 4 pelajaran total.
Pengantar Arsitektur Bersih Berbasis Peristiwa
Selamat datang di Arsitektur Bersih Berbasis Peristiwa! Dalam sistem yang kompleks, berbagai bagian sering perlu bereaksi terhadap hal yang terjadi di tempat lain tanpa terikat erat.
Pelajaran ini membahas cara mengintegrasikan pola berbasis peristiwa ke dalam Arsitektur Bersih Anda, menggunakan peristiwa domain untuk meningkatkan pelepasan keterikatan dan skalabilitas, dengan tetap mematuhi Aturan Dependensi secara ketat.
Apa yang Dimaksud dengan Peristiwa Domain?
Peristiwa Domain adalah sesuatu yang terjadi dalam domain dan dianggap penting oleh pakar domain. Peristiwa ini merupakan fakta yang tidak dapat diubah, yaitu catatan tentang suatu kejadian, seperti 'Pesanan Ditempatkan' atau 'Pengguna Terdaftar'.
- Peristiwa ini merepresentasikan perubahan keadaan domain.
- Peristiwa ini biasanya diberi nama dalam bentuk lampau, misalnya
OrderPlaced. - Peristiwa ini seharusnya berupa struktur data sederhana yang hanya berisi informasi relevan tentang peristiwa tersebut.
Peristiwa dan Aturan Dependensi
Dalam Arsitektur Bersih, Aturan Dependensi menyatakan bahwa dependensi harus mengalir ke arah dalam. Peristiwa domain sangat sesuai dengan aturan ini:
- Entitas dapat memunculkan peristiwa, tetapi tidak mengetahui siapa yang menanganinya.
- Kasus Penggunaan mengatur entitas dan dapat menerbitkan peristiwa setelah suatu operasi.
- Adaptor Antarmuka, misalnya penyaji dan gerbang layanan eksternal, dapat berlangganan serta menangani peristiwa dari lapisan dalam.
Hal ini mempertahankan pemisahan yang ketat karena lapisan dalam tetap tidak mengetahui detail lapisan luar.
Menerapkan Peristiwa Domain
Peristiwa domain pada dasarnya adalah objek transfer data (DTO) yang membawa informasi tentang sesuatu yang telah terjadi. Sebaiknya tersedia antarmuka umum untuk semua peristiwa domain.
Berikut adalah antarmuka Java sederhana:
public interface DomainEvent {
long occurredOn();
}Kode: Peristiwa Domain Konkret
Mari buat peristiwa domain tertentu: OrderPlacedEvent. Peristiwa ini menyimpan orderId dan penanda waktu saat peristiwa tersebut terjadi.
Cobalah menjalankan definisi sederhana ini:
public class OrderPlacedEvent implements DomainEvent {
private final String orderId;
private final long occurredOn;
public OrderPlacedEvent(String orderId) {
this.orderId = orderId;
this.occurredOn = System.currentTimeMillis();
}
public String getOrderId() {
return orderId;
}
@Override
public long occurredOn() {
return occurredOn;
}
public static void main(String[] args) {
OrderPlacedEvent event = new OrderPlacedEvent("ORD-123");
System.out.println("Order event for: " + event.getOrderId());
}
}Penerbit Peristiwa
Untuk menerbitkan peristiwa, kita memerlukan Penerbit Peristiwa, yang juga dikenal sebagai Pengirim Peristiwa atau Bus Peristiwa. Komponen ini menerima peristiwa domain dan mengirimkannya kepada semua penangan yang terdaftar.
Komponen ini bertindak sebagai mediator yang melepaskan keterikatan sumber peristiwa dari konsumennya. Kasus Penggunaan akan bergantung pada antarmuka penerbit ini, bukan pada penangan tertentu.
Kode: Antarmuka Penerbit Peristiwa
Berikut adalah antarmuka untuk EventPublisher kita. Kita juga memerlukan cara agar para penangan dapat mendaftarkan diri.
public interface EventPublisher {
void publish(DomainEvent event);
<T extends DomainEvent> void subscribe(Class<T> eventType, EventHandler<T> handler);
}Kode: Penerbit Peristiwa Dalam Memori
Ini adalah implementasi sederhana dalam memori untuk tujuan demonstrasi. Dalam aplikasi nyata, implementasi ini mungkin menggunakan antrean pesan, misalnya Kafka atau RabbitMQ, untuk persistensi dan distribusi.
Jalankan kode ini untuk melihat cara kerja dasar penerbit:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public interface DomainEvent { long occurredOn(); }
public interface EventHandler<T extends DomainEvent> { void handle(T event); }
public class OrderPlacedEvent implements DomainEvent {
private final String orderId; private final long occurredOn;
public OrderPlacedEvent(String orderId) {
this.orderId = orderId; this.occurredOn = System.currentTimeMillis();
}
public String getOrderId() { return orderId; }
@Override public long occurredOn() { return occurredOn; }
}
public class SimpleEventPublisher implements EventPublisher {
private final Map<Class<? extends DomainEvent>, List<EventHandler<?>>> subscribers = new HashMap<>();
@Override
public void publish(DomainEvent event) {
List<EventHandler<?>> handlers = subscribers.get(event.getClass());
if (handlers != null) {
for (EventHandler handler : handlers) {
// Unchecked cast is safe due to type checking during subscription
((EventHandler<DomainEvent>) handler).handle(event);
}
}
}
@Override
public <T extends DomainEvent> void subscribe(Class<T> eventType, EventHandler<T> handler) {
subscribers.computeIfAbsent(eventType, k -> new ArrayList<>()).add(handler);
}
public static void main(String[] args) {
SimpleEventPublisher publisher = new SimpleEventPublisher();
publisher.subscribe(OrderPlacedEvent.class, event -> {
System.out.println("Handler 1: Order " + event.getOrderId() + " placed!");
});
publisher.subscribe(OrderPlacedEvent.class, event -> {
System.out.println("Handler 2: Notifying ops for order " + event.getOrderId());
});
OrderPlacedEvent event = new OrderPlacedEvent("DEMO-456");
publisher.publish(event);
}
}Mengintegrasikan Kasus Penggunaan dan Penangan
Sekarang, mari kita lihat bagaimana sebuah Kasus Penggunaan menerbitkan peristiwa dan bagaimana Penangan Peristiwa, yang berada misalnya di lapisan Adaptor Antarmuka, bereaksi terhadapnya. Kasus Penggunaan tetap tidak terikat pada penangan tersebut.
Rancangan ini memungkinkan penambahan penangan baru tanpa mengubah Kasus Penggunaan.
Kode: Alur Berbasis Peristiwa Lengkap
Contoh ini menunjukkan PlaceOrderUseCase yang menerbitkan OrderPlacedEvent, kemudian ditangani oleh OrderEmailNotifier.
Perhatikan bahwa PlaceOrderUseCase hanya bergantung pada EventPublisher, bukan pada pemberi tahu tertentu.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// Domain Layer Interfaces & Classes
interface DomainEvent { long occurredOn(); }
class OrderPlacedEvent implements DomainEvent {
private final String orderId; private final long occurredOn;
public OrderPlacedEvent(String orderId) {
this.orderId = orderId; this.occurredOn = System.currentTimeMillis();
}
public String getOrderId() { return orderId; }
@Override public long occurredOn() { return occurredOn; }
}
// Application Layer Interfaces & Classes
interface EventPublisher {
void publish(DomainEvent event);
<T extends DomainEvent> void subscribe(Class<T> eventType, EventHandler<T> handler);
}
interface EventHandler<T extends DomainEvent> { void handle(T event); }
// Use Case (Application Layer)
class PlaceOrderUseCase {
private final EventPublisher eventPublisher;
public PlaceOrderUseCase(EventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void execute(String orderDetails) {
// Simulate order creation logic
String newOrderId = "ORD-" + System.nanoTime();
System.out.println("Order " + newOrderId + " created with details: " + orderDetails);
// Publish domain event
eventPublisher.publish(new OrderPlacedEvent(newOrderId));
}
}
// Infrastructure/Interface Adapters Layer Implementation
class SimpleEventPublisher implements EventPublisher {
private final Map<Class<? extends DomainEvent>, List<EventHandler<?>>> subscribers = new HashMap<>();
@Override
public void publish(DomainEvent event) {
List<EventHandler<?>> handlers = subscribers.get(event.getClass());
if (handlers != null) {
for (EventHandler handler : handlers) {
((EventHandler<DomainEvent>) handler).handle(event);
}
}
}
@Override
public <T extends DomainEvent> void subscribe(Class<T> eventType, EventHandler<T> handler) {
subscribers.computeIfAbsent(eventType, k -> new ArrayList<>()).add(handler);
}
}
class OrderEmailNotifier implements EventHandler<OrderPlacedEvent> {
@Override
public void handle(OrderPlacedEvent event) {
System.out.println("Email Notifier: Sending email for order " + event.getOrderId());
}
}
class InventoryUpdater implements EventHandler<OrderPlacedEvent> {
@Override
public void handle(OrderPlacedEvent event) {
System.out.println("Inventory Updater: Updating inventory for order " + event.getOrderId());
}
}
public class Main {
public static void main(String[] args) {
SimpleEventPublisher publisher = new SimpleEventPublisher();
// Register handlers
publisher.subscribe(OrderPlacedEvent.class, new OrderEmailNotifier());
publisher.subscribe(OrderPlacedEvent.class, new InventoryUpdater());
// Create use case with publisher dependency
PlaceOrderUseCase placeOrderUseCase = new PlaceOrderUseCase(publisher);
// Execute use case, which publishes the event
placeOrderUseCase.execute("Laptop, Quantity: 1");
placeOrderUseCase.execute("Keyboard, Quantity: 2");
}
}Pemeriksaan Singkat: Peristiwa Domain
Saat mengintegrasikan peristiwa domain ke dalam Arsitektur Bersih, apa manfaat utama Kasus Penggunaan menerbitkan peristiwa daripada memanggil layanan lain secara langsung?
Rangkuman: Arsitektur Bersih Berbasis Peristiwa
Dalam pelajaran ini, kita mempelajari Arsitektur Bersih Berbasis Peristiwa. Anda telah mempelajari bahwa:
- Peristiwa Domain adalah fakta yang tidak dapat diubah dan merepresentasikan kejadian penting.
- Peristiwa ini memungkinkan pelepasan keterikatan, sehingga Kasus Penggunaan dapat menerbitkan peristiwa tanpa mengetahui para pelanggannya.
- Penerbit Peristiwa menengahi pengiriman peristiwa kepada Penangan Peristiwa.
- Pola ini mendukung skalabilitas dan ekstensibilitas, sehingga sistem lebih mudah dikembangkan sambil tetap mematuhi Aturan Dependensi.
Dengan memanfaatkan peristiwa domain, Arsitektur Bersih Anda dapat menjadi semakin kuat dan mudah beradaptasi.
Belajar Clean Architecture & Design Patterns in Practice dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 12
- Pelajaran
- 48
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Arsitektur Bersih Berbasis Peristiwa” gratis?
Ya — teks lengkap “Arsitektur Bersih Berbasis Peristiwa” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Clean Architecture & Design Patterns in Practice, upgrade ke CoddyKit PRO. Kursus Clean Architecture & Design Patterns in Practice mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Arsitektur Bersih Berbasis Peristiwa”?
Integrasikan pola berbasis peristiwa ke dalam Arsitektur Bersih dengan menggunakan peristiwa domain untuk meningkatkan pemisahan dan skalabilitas. Kamu berlatih Clean Architecture & Design Patterns in Practice dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Clean Architecture & Design Patterns in Practice?
Tidak diperlukan pengalaman sebelumnya. Clean Architecture & Design Patterns in Practice di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Arsitektur Bersih Berbasis Peristiwa” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Clean Architecture & Design Patterns in Practice ini?
Ya. Setiap pelajaran Clean Architecture & Design Patterns in Practice menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Menangani Perhatian Lintas Lapisan
- Arsitektur Bersih Berbasis Peristiwa
- Arsitektur Bersih dalam Layanan Mikro
- CQRS dalam Arsitektur Bersih