Pendahuluan: Architectural Pattern #
Dalam software engineering, keputusan arsitektur adalah keputusan paling mahal untuk diubah. Framework bisa diganti dalam hitungan sprint. Library bisa di-refactor dalam satu iterasi. Bahkan bahasa pemrograman bisa dimigrasikan — menyakitkan, tapi bisa dilakukan. Arsitektur yang salah, sebaliknya, akan terus “menghantui” sistem selama bertahun-tahun: setiap fitur baru terasa seperti melawan arus, setiap refactor merembet ke tempat yang tak terduga, dan setiap diskusi teknikal berakhir dengan “sebenarnya masalahnya dari awal adalah…”. Memahami architectural pattern bukan soal menghafal diagram — ini soal memahami mengapa sebuah sistem dibentuk dengan cara tertentu, apa yang dikorbankan, dan kapan sebuah pilihan mulai berubah menjadi beban.
Architectural Pattern vs Design Pattern #
Sebelum masuk ke daftar pattern, penting untuk memahami di mana architectural pattern berada dalam hierarki keputusan engineering.
flowchart TD
AP["Architectural Pattern\n(level sistem)"]
DP["Design Pattern\n(level komponen)"]
CP["Coding Pattern\n(level fungsi/kelas)"]
AP -->|"membatasi dan membentuk"| DP
DP -->|"membatasi dan membentuk"| CP
AP_EX["Microservices, Clean Architecture,\nEvent-Driven, CQRS"]
DP_EX["Repository, Factory, Strategy,\nObserver, Decorator"]
CP_EX["Guard clause, early return,\nimmutability, tail call"]
AP --- AP_EX
DP --- DP_EX
CP --- CP_EX
Perbedaannya bukan hanya soal skala — ini soal jenis keputusan yang dibuat:
| Dimensi | Design Pattern | Architectural Pattern |
|---|---|---|
| Level | Kelas dan fungsi | Sistem dan komponen besar |
| Pertanyaan | Bagaimana objek ini berkolaborasi? | Bagaimana sistem ini dibagi? |
| Dampak perubahan | Terlokalisir, seminggu | Menyebar ke seluruh codebase, berbulan-bulan |
| Siapa yang memutuskan | Developer individual | Tim inti, tech lead, arsitek |
| Contoh | Repository, Strategy | Microservices, Event-Driven |
| Ketika salah | Bug atau kode yang sulit diuji | Sistem yang sulit dikembangkan selama bertahun-tahun |
Architectural pattern menjawab pertanyaan-pertanyaan besar yang design pattern tidak bisa jawab:
Pertanyaan yang dijawab Architectural Pattern:
□ Bagaimana sistem dibagi menjadi komponen-komponen besar?
□ Bagaimana komponen tersebut berkomunikasi satu sama lain?
□ Di mana boundary antara domain, data, dan infrastruktur?
□ Bagaimana sistem bisa dideploy, diskalakan, dan diubah secara independen?
□ Bagaimana tim yang berbeda bisa bekerja tanpa saling menunggu?
□ Bagaimana sistem berevolusi ketika tim, traffic, dan kompleksitas meningkat?
Dimensi Keputusan Arsitektur #
Setiap pilihan arsitektur adalah kompromi sepanjang beberapa dimensi. Tidak ada arsitektur yang “terbaik” — hanya yang paling sesuai dengan konteks. Memahami dimensi ini membantu kamu mengevaluasi pilihan dengan lebih objektif.
flowchart LR
subgraph DIM["Dimensi Utama Keputusan Arsitektur"]
D1["Deployment\nComplexity"]
D2["Operational\nComplexity"]
D3["Development\nVelocity"]
D4["Scalability"]
D5["Testability"]
D6["Team\nAutonomy"]
end
Simple["Monolith\nLayered"] -.->|"rendah"| D1
Simple -.->|"rendah"| D2
Simple -.->|"tinggi awal"| D3
Complex["Microservices\nEvent-Driven"] -.->|"tinggi"| D1
Complex -.->|"tinggi"| D2
Complex -.->|"rendah awal, tinggi saat mature"| D3
Complex -.->|"tinggi"| D4
Complex -.->|"tinggi per-service"| D6
Deployment Complexity #
Seberapa rumit proses deployment sistem ini? Monolith dideploy sekali. Microservices bisa punya puluhan pipeline CI/CD terpisah. Serverless tidak ada server yang dikelola — tapi ada vendor lock-in dan cold start yang perlu dipikirkan.
Operational Complexity #
Seberapa sulit menjalankan sistem ini di production? Satu monolith dengan satu log stream dan satu database lebih mudah di-debug daripada 30 microservice yang berkomunikasi via event bus. Distributed tracing, service mesh, dan circuit breaker bukan kemewahan — mereka adalah keharusan di arsitektur terdistribusi.
Development Velocity #
Seberapa cepat tim bisa menambah fitur baru? Di monolith, satu developer bisa men-touch seluruh stack. Di microservices, team ownership yang jelas mempercepat pengembangan per-service tapi memperlambat fitur yang butuh koordinasi lintas service.
Scalability #
Seberapa mudah sistem ini menangani peningkatan load? Monolith hanya bisa di-scale secara horizontal sebagai satu unit. Microservices memungkinkan scaling per-service sesuai kebutuhan. CQRS memisahkan scaling read dan write secara independen.
Testability #
Seberapa mudah komponen sistem ini diuji secara terisolasi? Clean Architecture dan Hexagonal Architecture dirancang eksplisit untuk membuat unit test mudah dilakukan tanpa database atau HTTP server nyata. Monolith besar yang tightly-coupled bisa sangat sulit diuji.
Team Autonomy #
Seberapa independen tim bisa bekerja? Ini sering lebih penting dari pertimbangan teknikal murni. Conway’s Law menyatakan bahwa struktur sistem cenderung mencerminkan struktur komunikasi organisasi yang membangunnya.
Taksonomi Architectural Pattern #
Ada banyak cara untuk mengkategorikan architectural pattern. Salah satu yang paling berguna adalah berdasarkan tingkat distribusi — seberapa terdistribusi komponen-komponen sistem.
flowchart TD
subgraph L1["Level 1: Satu Unit Deployment"]
M[Monolithic]
MM[Modular Monolith]
end
subgraph L2["Level 2: Satu Proses, Banyak Layer"]
LA[Layered Architecture]
CA[Clean Architecture]
HA[Hexagonal Architecture]
OA[Onion Architecture]
end
subgraph L3["Level 3: Beberapa Service"]
SBA[Service-Based]
MS[Microservices]
end
subgraph L4["Level 4: Event & Async"]
EDA[Event-Driven]
CQRS[CQRS]
SL[Serverless]
end
subgraph L5["Level 5: UI & Presentation"]
MVC[MVC / MVP / MVVM]
end
L1 -->|"scale organisasi"| L3
L2 -->|"scale distribusi"| L3
L3 -->|"scale async"| L4
Monolithic Architecture #
Sistem dibangun dan dideploy sebagai satu unit utuh. Semua komponen berada dalam satu codebase dan satu proses runtime. Ini bukan pilihan yang “salah” — untuk tim kecil dan sistem yang sedang berkembang, monolith sering menjadi pilihan paling rasional dan produktif. Masalah baru muncul ketika monolith tumbuh tanpa struktur, berubah menjadi big ball of mud yang tidak ada seorangpun yang benar-benar memahaminya secara keseluruhan.
Kekuatan utama: Development sederhana, deployment tunggal, debugging mudah, transaksi database trivial.
Kelemahan: Semua team deploy bersama (bottleneck), satu bug bisa crash seluruh sistem, sulit scale bagian tertentu secara independen.
Modular Monolith #
Evolusi dari monolith: satu deployment, tapi codebase dibagi ke dalam modul-modul dengan boundary yang tegas dan aturan dependency yang dijaga ketat. Setiap modul punya interface publiknya sendiri, dan modul lain tidak boleh mengakses internal modul tersebut secara langsung. Ketika boundary dijaga dengan disiplin, modular monolith bisa menjadi end-game architecture yang sangat efektif — tidak perlu microservices jika tim dan sistemnya tidak membutuhkannya.
Kekuatan utama: Deployment simple tapi kode terorganisir, bisa di-extract menjadi service jika diperlukan, refactor lebih aman karena boundary tegas.
Kelemahan: Membutuhkan disiplin tim yang tinggi untuk menjaga boundary, tooling untuk memvalidasi boundary tidak selalu tersedia.
Layered Architecture #
Aplikasi dibagi ke dalam layer horizontal — biasanya presentation, application, domain, dan data/infrastructure — dengan aturan bahwa dependency hanya boleh mengalir ke bawah (layer atas bergantung ke layer bawah, tidak sebaliknya). Ini adalah arsitektur yang paling familiar bagi sebagian besar developer karena mudah dipahami dan paling sering diajarkan.
Kekuatan utama: Mudah dipahami, separation of concern yang jelas, cocok untuk tim junior hingga mid-level.
Kelemahan: Rawan anemic domain model (domain hanya berisi data, logik tersebar di service layer), database sering jadi “pusat gravitasi” yang menciptakan coupling tersembunyi.
Clean Architecture #
Business rule ditempatkan sebagai pusat sistem, dan dependency selalu mengarah ke dalam — layer luar (database, UI, framework) bergantung ke layer dalam (domain), tidak sebaliknya. Ini memungkinkan domain logic diuji tanpa database atau framework. Dipublikasikan oleh Robert C. Martin sebagai sintesis dari berbagai pendekatan domain-centric.
flowchart TD
subgraph CLEAN["Clean Architecture — Dependency Rule"]
FR["Frameworks & Drivers\n(UI, DB, Web)"]
IA["Interface Adapters\n(Controllers, Gateways)"]
UC["Use Cases\n(Application Business Rules)"]
EN["Entities\n(Enterprise Business Rules)"]
end
FR -->|"depends on"| IA
IA -->|"depends on"| UC
UC -->|"depends on"| EN
EN -->|"tidak bergantung pada apapun"| EN
Kekuatan utama: Domain terisolasi dari infrastruktur, testability sangat tinggi, perubahan framework tidak mempengaruhi business rule.
Kelemahan: Banyak layer dan interface yang perlu dibuat, membutuhkan investment awal yang besar, bisa over-engineering untuk sistem kecil.
Hexagonal Architecture (Ports & Adapters) #
Core application berinteraksi dengan dunia luar melalui port (interface yang didefinisikan oleh core) dan adapter (implementasi konkret yang mengisi port tersebut). Database, HTTP API, message queue, CLI — semuanya adalah adapter yang bisa diganti tanpa menyentuh core. Diperkenalkan oleh Alistair Cockburn.
flowchart LR
subgraph HEX["Hexagonal Architecture"]
CORE["Application Core\n(Domain + Use Cases)"]
PP["Primary Port\n(Driving)"]
SP["Secondary Port\n(Driven)"]
end
HTTP["HTTP\nAdapter"] -->|"via port"| PP
CLI["CLI\nAdapter"] -->|"via port"| PP
PP --> CORE
CORE --> SP
SP -->|"via port"| DB["Database\nAdapter"]
SP -->|"via port"| MQ["Message Queue\nAdapter"]
Kekuatan utama: Sangat mudah diganti adapaternya (e.g., ganti dari MySQL ke PostgreSQL, atau tambah REST di samping gRPC), testability ekselen dengan mock adapter.
Kelemahan: Membutuhkan pemahaman yang baik tentang port/adapter distinction, bisa verbose untuk domain yang sederhana.
Onion Architecture #
Domain model berada di pusat, dikelilingi oleh layer-layer yang makin ke luar makin spesifik implementasinya. Mirip dengan Clean Architecture dan Hexagonal, tapi visualisasinya berbeda — lapisan seperti bawang yang membungkus inti domain. Berkembang dari praktik DDD.
Kekuatan utama: Domain murni di pusat, sangat cocok dengan pendekatan DDD, dependency rule yang ketat.
Kelemahan: Mirip dengan Clean Architecture dalam terms of kelebihan dan kekurangan, boundary antar layer bisa ambigu.
Service-Based Architecture #
Aplikasi dipecah menjadi beberapa service yang lebih besar dari microservice — biasanya 4 hingga 12 service per sistem — yang sering kali masih berbagi satu database. Ini adalah langkah pragmatis saat monolith mulai terlalu besar untuk satu tim, tapi organisasi belum siap dengan kompleksitas penuh dari microservices.
Kekuatan utama: Lebih mudah dari microservices, bisa dideploy secara terpisah, tim bisa bekerja lebih independen.
Kelemahan: Shared database menciptakan coupling tersembunyi, tidak memberikan isolasi deployment penuh.
Microservices Architecture #
Sistem terdiri dari banyak service kecil yang bisa dikembangkan, dideploy, dan diskalakan secara independen. Setiap service punya database sendiri, berkomunikasi via API atau event, dan biasanya dimiliki oleh satu tim kecil. Dipopulerkan oleh Netflix, Amazon, dan perusahaan skala besar lainnya.
flowchart TD
GW[API Gateway] --> S1[User Service\nPostgreSQL]
GW --> S2[Order Service\nMySQL]
GW --> S3[Payment Service\nPostgreSQL]
S2 -->|"event"| MQ[(Message Broker)]
MQ --> S4[Notification Service\nRedis]
MQ --> S5[Analytics Service\nClickHouse]
Kekuatan utama: Independen deployment, technology heterogeneity, scaling per-service, team autonomy.
Kelemahan: Distributed system complexity (network failures, latency, eventual consistency), overhead operasional sangat tinggi, debugging lintas service sulit.
Microservices adalah keputusan organisasional, bukan hanya teknikal. Jika tim masih kecil dan komunikasi antar tim masih mudah, microservices akan menambah complexity tanpa manfaat yang setimpal. Sebagian besar sistem tidak butuh microservices — mereka butuh better organized monolith terlebih dahulu.
Event-Driven Architecture #
Komponen sistem berkomunikasi melalui event secara asynchronous menggunakan message broker atau event bus. Producer mempublikasikan event tanpa tahu siapa yang akan mengonsumsinya. Consumer bereaksi terhadap event yang relevan tanpa tahu siapa yang memproduksinya. Ini menciptakan loose coupling yang sangat tinggi.
sequenceDiagram
participant OS as Order Service
participant MB as Message Broker
participant IS as Inventory Service
participant NS as Notification Service
participant AS as Analytics Service
OS->>MB: publish OrderPlaced event
MB-->>IS: OrderPlaced
MB-->>NS: OrderPlaced
MB-->>AS: OrderPlaced
IS->>MB: publish InventoryReserved event
MB-->>OS: InventoryReserved
Kekuatan utama: Loose coupling ekstrem, throughput tinggi, mudah ditambah consumer baru tanpa mengubah producer.
Kelemahan: Eventual consistency (data tidak langsung konsisten), debugging alur event sulit, error handling dan retry logic kompleks.
CQRS (Command Query Responsibility Segregation) #
Memisahkan model untuk operasi tulis (Command) dan baca (Query). Write model dioptimalkan untuk konsistensi dan validasi bisnis. Read model dioptimalkan untuk query yang cepat dan fleksibel — bisa berupa denormalized views, search index, atau cache. Dipromosikan oleh Greg Young dan sering dikombinasikan dengan Event Sourcing.
flowchart LR
C([Client]) -->|"Command"| WM["Write Model\n(Command Handler)"]
C -->|"Query"| RM["Read Model\n(Query Handler)"]
WM -->|"write"| WDB[(Write DB\nnormalized)]
WM -->|"event"| PROJ[Projector]
PROJ -->|"update"| RDB[(Read DB\ndenormalized)]
RM -->|"read"| RDB
Kekuatan utama: Read dan write bisa di-scale secara independen, read model bisa disesuaikan untuk query spesifik, write model bisa fokus ke invariant bisnis.
Kelemahan: Eventual consistency antara write dan read model, complexity tinggi untuk sistem CRUD sederhana, lebih banyak kode yang perlu dikelola.
Serverless Architecture #
Logic aplikasi dijalankan dalam fungsi-fungsi kecil yang di-trigger oleh event, tanpa mengelola server secara langsung. Cloud provider (AWS Lambda, Google Cloud Functions) menangani scaling, availability, dan runtime.
Kekuatan utama: Zero operational overhead untuk infrastruktur, bayar per-eksekusi (efisien untuk traffic tidak merata), scaling otomatis.
Kelemahan: Cold start latency, vendor lock-in, state management kompleks, observability terbatas, tidak cocok untuk long-running process.
MVC / MVP / MVVM #
Pola pemisahan concern di level UI antara data (Model), tampilan (View), dan logika presentasi (Controller/Presenter/ViewModel). Berawal dari MVC di Smalltalk, berevolusi menjadi MVP untuk Android dan MVVM untuk framework reactive modern.
Kekuatan utama: Separation of concern yang jelas di layer UI, mudah diuji jika diimplementasikan dengan benar.
Kelemahan: Logic bisnis sering bocor ke Presenter/ViewModel, tidak menjawab pertanyaan tentang layer yang lebih dalam (data access, domain).
Decision Tree: Memilih Arsitektur yang Tepat #
Tidak ada formula yang sempurna, tapi pertanyaan-pertanyaan berikut membantu mempersempit pilihan:
flowchart TD
Q1{Seberapa besar\ntim dan sistemnya?} -->|"< 5 developer\natau MVP"| MON[Monolith atau\nModular Monolith]
Q1 -->|"5-20 developer\natau sistem berkembang"| Q2
Q2{Apakah domain\nbisnis kompleks?} -->|"Ya — banyak aturan bisnis\ndan invariant"| Q3
Q2 -->|"Tidak — CRUD-heavy\natau data pipeline"| LAY[Layered Architecture]
Q3{Seberapa penting\ntestability?} -->|"Sangat penting\nbanyak integrasi eksternal"| Q4
Q3 -->|"Cukup penting"| OA[Onion Architecture]
Q4{Ada banyak\nintegrasi luar?} -->|"Ya — DB berbeda,\nAPIs, message queues"| HEX[Hexagonal Architecture]
Q4 -->|"Tidak terlalu"| CA[Clean Architecture]
Q1 -->|"> 20 developer\natau domain yang luas"| Q5
Q5{Tim bisa di-split\nper domain?} -->|"Ya — ownership\njelas per domain"| Q6
Q5 -->|"Tidak — masih\nsatu tim besar"| SBA[Service-Based]
Q6{Siap dengan\ndistributed system ops?} -->|"Ya — k8s, tracing,\nmonitoring matang"| MS[Microservices]
Q6 -->|"Belum"| SBA
MS --> Q7{High async\nthroughput?}
Q7 -->|"Ya"| EDA[Event-Driven]
Q7 -->|"Read-heavy &\nwrite complex"| CQRS[CQRS]
Q7 -->|"Event-based &\ntraffic tidak stabil"| SL[Serverless]
Panduan Referensi Cepat #
Tabel berikut adalah ringkasan singkat untuk digunakan saat diskusi arsitektur atau high-level design review:
| Architectural Pattern | Cocok Digunakan Jika | Kurang Cocok Jika | Catatan Penting |
|---|---|---|---|
| Monolithic | Tim kecil, MVP, perubahan cepat | Tim besar, deployment sering konflik | Pilihan paling rasional di awal |
| Modular Monolith | Sistem membesar tapi ingin tetap simple | Boundary modul tidak dijaga dengan disiplin | Bisa jadi end-game architecture |
| Layered | CRUD-heavy, tim junior-mid | Domain logic kompleks dan kaya aturan | Mudah dipahami, rawan anemic domain |
| Clean Architecture | Business rule kompleks, umur sistem panjang | Sistem kecil dan stabil | Investasi jangka panjang |
| Hexagonal | Banyak integrasi eksternal yang bisa berganti | Tim belum terbiasa konsep port/adapter | Sangat kuat untuk testability |
| Onion | Domain-centric dan DDD-heavy | Domain sederhana | Fokus ke kemurnian domain |
| Service-Based | Monolith terlalu besar, transisi bertahap | Butuh isolasi deployment penuh | Shared DB masih umum |
| Microservices | Tim besar, domain luas, ownership jelas | Tim kecil, observability belum matang | Keputusan organisasional, bukan hanya teknikal |
| Event-Driven | Async process, high throughput, loose coupling | Debugging harus sederhana | Distributed tracing wajib matang |
| CQRS | Read-heavy, write complex, perlu scale terpisah | CRUD sederhana | Scalability pattern, bukan default |
| Serverless | Traffic tidak stabil, event-based, minimal ops | Latency sensitif, stateful, long-running | Cold start dan vendor lock-in |
| MVC/MVP/MVVM | Fokus UI dan presentation layer | Logic bisnis berat di presentation | Biasanya digabung dengan pattern backend |
Evolusi Arsitektur: Bukan Keputusan Sekali Seumur Hidup #
Salah satu kesalahpahaman terbesar tentang arsitektur adalah bahwa kamu harus memilih yang “benar” sejak awal. Kenyataannya, arsitektur yang baik adalah arsitektur yang bisa berevolusi seiring pertumbuhan sistem dan tim.
flowchart LR
MVP["MVP\nMonolith"] -->|"tim berkembang\ndomain makin jelas"| MM["Modular\nMonolith"]
MM -->|"boundary makin tegas\nteam ownership jelas"| SBA["Service-Based\nArchitecture"]
SBA -->|"traffic tinggi\nops matang"| MS["Microservices"]
MS -->|"high async\nthroughput needed"| EDA["Event-Driven\n+ CQRS"]
Kebanyakan sistem sukses dimulai sebagai monolith dan berevolusi hanya ketika ada kebutuhan nyata. Melompat langsung ke microservices sebelum domain dipahami dengan baik — apa yang sering disebut premature distributed — adalah sumber masalah yang jauh lebih besar dari monolith yang well-structured.
Tanda-tanda arsitektur perlu berevolusi:
□ Satu perubahan kecil membutuhkan koordinasi dengan banyak tim
□ Deployment salah satu bagian memblokir deployment bagian lain
□ Database menjadi bottleneck dan tidak bisa di-tune lebih lanjut
□ Bug di satu modul sering menyebabkan kegagalan di modul lain
□ Tim sulit memahami keseluruhan sistem karena terlalu besar
Tanda-tanda arsitektur terlalu rumit untuk kebutuhan saat ini:
□ Lebih banyak waktu dihabiskan untuk ops daripada development
□ Fitur sederhana butuh koordinasi lintas banyak service
□ Debugging membutuhkan tracing puluhan service
□ Tim kecil overwhelmed dengan overhead distributed system
Cara Membaca Section Ini #
Setiap artikel dalam section ini mengikuti struktur yang sama:
Konsep inti → mengapa pattern ini ada, masalah apa yang dipecahkan
Struktur → diagram komponen dan bagaimana mereka berinteraksi
Implementasi → contoh kode konkret dalam Go
Trade-off → kelebihan, kelemahan, dan kapan tidak cocok
Anti-pattern → kesalahan implementasi yang sering terjadi
Perbandingan → posisi relatif terhadap pattern lain yang mirip
Checklist → panduan review sebelum mengadopsi
Pendekatan ini menekankan bahwa setiap pattern adalah alat dengan trade-off, bukan solusi universal. Tujuannya bukan agar kamu mengimplementasikan semua pattern, melainkan agar kamu bisa membuat keputusan yang deliberate — tahu persis apa yang kamu dapatkan dan apa yang kamu korbankan.
Ringkasan #
- Architectural pattern bekerja di level sistem, bukan kode — ia menjawab pertanyaan tentang bagaimana komponen besar dibagi, bagaimana mereka berkomunikasi, dan bagaimana sistem berevolusi; bukan tentang bagaimana kelas atau fungsi diorganisir.
- Tidak ada arsitektur yang “terbaik” — setiap pilihan adalah kompromi antara deployment complexity, operational complexity, development velocity, scalability, testability, dan team autonomy.
- Mulai sederhana, evolusi berdasarkan kebutuhan nyata — mayoritas sistem sukses dimulai sebagai monolith dan berevolusi hanya ketika ada tekanan nyata; premature distributed adalah sumber masalah yang jauh lebih besar.
- Microservices adalah keputusan organisasional — bukan solusi untuk sistem yang lambat atau kode yang buruk; jika komunikasi tim masih mudah dan domain belum dipahami, microservices menambah complexity tanpa manfaat.
- Conway’s Law selalu bekerja — struktur sistem cenderung mencerminkan struktur komunikasi organisasi; desain organisasi dan desain arsitektur tidak bisa dipisahkan.
- Domain-centric architecture (Clean, Hexagonal, Onion) memberikan testability terbaik — dengan membuat dependency selalu mengarah ke dalam domain, perubahan infrastruktur tidak mempengaruhi business rule.
- Event-Driven dan CQRS adalah pattern lanjutan yang butuh prerequisite — distributed tracing, idempotency, dan eventual consistency handling harus sudah matang sebelum mengadopsinya.
- Modular Monolith sering diabaikan tapi sangat powerful — dengan boundary yang dijaga ketat, monolith yang well-organized bisa menangani kebutuhan banyak organisasi tanpa kompleksitas distribusi.
- Arsitektur yang baik bisa berevolusi — ia tidak mengunci kamu dalam satu bentuk selamanya; boundary yang tegas dan dependency rule yang jelas membuat ekstraksi menjadi lebih kecil unit memungkinkan kapanpun diperlukan.
- Baca setiap artikel berikutnya sebagai studi trade-off — bukan sebagai panduan “kapan mengimplementasikan ini”, tapi sebagai pemahaman mendalam tentang apa yang diperoleh dan dikorbankan dari setiap pilihan.