Apa itu Arsitektur Onion
Arsitektur Onion adalah pola arsitektur untuk merancang aplikasi perangkat lunak. Arsitektur ini digambarkan secara visual dalam lapisan-lapisan konsentris yang menyerupai bawang, oleh karena itu dinamakan demikian. Pola ini menerapkan kontrol dependensi yang ketat, di mana dependensi mengalir ke dalam, sementara interaksi terjadi dari lapisan terluar menuju pusat.
Tujuan utama arsitektur ini adalah mengatasi masalah umum dalam desain perangkat lunak, seperti keterikatan yang kuat dan pemisahan masalah, sehingga memungkinkan kemudahan pemeliharaan dan adaptabilitas dalam struktur aplikasi.
Prinsip-prinsip
Arsitektur Onion didasarkan pada beberapa prinsip panduan:
-
Domain adalah Inti
Inti dari aplikasi adalah domain, yang mencakup aturan bisnis dan logika fundamental. Ini termasuk entitas bisnis dan objek nilai yang penting untuk fungsi aplikasi. Dalam Arsitektur Onion, entitas domain tidak bergantung pada hal lain. Mereka bersifat murni, karena mereka mengandung properti dan metode yang berkaitan langsung dengan apa yang mereka wakili. -
Dependensi ke dalam
Lapisan-lapisan arsitektur hanya boleh bergantung pada lapisan-lapisan dalam dan tidak pada lapisan-lapisan di luar. Ide ini adalah menjaga domain dan lapisan aplikasi terpisah dari masalah eksternal seperti UI, Infrastruktur, atau Pengujian. Dengan memastikan keterikatan hanya menuju pusat, arsitektur ini memungkinkan lapisan-lapisan luar dapat saling dipertukarkan dan dimodifikasi dengan mudah tanpa mempengaruhi lapisan-lapisan dalam. -
Pemisahan dari Infrastruktur
Prinsip lain dari Arsitektur Onion adalah penyembunyian kepentingan infrastruktur di dalam lapisan-lapisan terluar. Dengan demikian, perubahan dalam infrastruktur, seperti perubahan perangkat lunak database atau antarmuka pengguna, tidak mempengaruhi organisasi dan operasi lapisan-lapisan dalam. Pendekatan ini memudahkan pengujian komponen inti tanpa perlu dependensi terkait infrastruktur. -
Kemandirian Kode Inti Aplikasi
Semua kode inti aplikasi dapat diuji tanpa antarmuka pengguna, database, server web, atau elemen eksternal lainnya. Dengan fokus pada inti, aplikasi menjadi lebih mudah dipelihara, lebih mudah ditingkatkan skalabilitasnya, dan lebih sedikit kesalahan yang mungkin terjadi.
Lapisan dalam Arsitektur Onion
Dalam Arsitektur Onion, aplikasi dibagi menjadi beberapa lapisan dengan tanggung jawab yang berbeda, masing-masing berkomunikasi dengan lapisan langsung di dalam atau di luar lapisannya.
Lapisan Model Domain
Lapisan model domain berada di tengah-tengah Arsitektur Onion. Lapisan terdalam ini mengkapsulasi aturan bisnis, kebijakan, dan entitas yang penting untuk domain aplikasi. Model domain terdiri dari entitas bisnis dan objek nilai yang secara langsung mewakili konsep dan perilaku dunia nyata yang berlaku untuk domain tersebut.
Objek domain tidak boleh mengandung referensi ke masalah eksternal seperti database atau antarmuka pengguna, sehingga membuatnya tidak bergantung pada persistensi. Mereka bersifat murni dalam arti bahwa mereka mengkapsulasi properti dan perilaku yang penting bagi domain bisnis.
Lapisan Layanan Domain
Di luar lapisan model domain adalah lapisan layanan domain. Layanan dalam lapisan ini menangani operasi bisnis yang melibatkan beberapa entitas atau objek nilai dalam domain. Mereka mengkapsulasi logika bisnis yang tidak secara alami sesuai dengan objek domain.
Layanan domain digunakan untuk mengoordinasikan tugas antara beberapa entitas, melakukan perhitungan kompleks, atau menerapkan aturan bisnis yang melibatkan beberapa entitas. Seperti objek domain, layanan domain harus tetap terisolasi dari masalah infrastruktur.
Lapisan Layanan Aplikasi
Layanan aplikasi, juga dikenal sebagai kasus pengguna, mengoordinasikan interaksi antara domain dan dunia luar. Mereka tidak mengandung aturan bisnis atau pengetahuan, tetapi bertanggung jawab atas tugas seperti pengelolaan transaksi dan memicu peristiwa domain.
Layanan aplikasi mengoordinasikan lapisan domain dengan lapisan infrastruktur. Mereka memanggil layanan domain dan entitas domain untuk melakukan operasi terkait aturan bisnis, dan berinteraksi dengan lapisan infrastruktur untuk menangani tugas seperti penyimpanan, caching, atau pengiriman pesan.
Lapisan Infrastruktur, Pengujian, dan Antarmuka Pengguna
Lapisan terluar dalam Arsitektur Onion berisi elemen seperti antarmuka pengguna, pengujian, dan tugas-tugas infrastruktur. Ini adalah area perangkat lunak yang rentan terhadap perubahan dari waktu ke waktu karena perkembangan teknologi dan persyaratan. Oleh karena itu, mereka dipisahkan dari aturan bisnis inti, sehingga memastikan bahwa lapisan inti tidak terpengaruh oleh perubahan di lapisan-lapisan luar.
Sub-lapisan Infrastruktur mengkapsulasi masalah seperti persistensi data dan komunikasi jaringan, biasanya melalui repositori dan objek akses data.
Sub-lapisan Pengujian terdiri dari semua pengujian yang mendorong pengembangan dan memastikan kebenaran aplikasi. Ini termasuk pengujian unit, pengujian integrasi, dan pengujian end-to-end.
Akhirnya, sub-lapisan Antarmuka Pengguna menangani semua interaksi pengguna, termasuk logika presentasi dan penanganan masukan pengguna. Ini bisa mencakup antarmuka web, REST API, aplikasi desktop, dan lain-lain.
Mengimplementasikan Arsitektur Onion dalam Python
Implementasi Arsitektur Onion dalam Python melibatkan mendefinisikan kelas-kelas yang mewakili lapisan-lapisan yang berbeda dalam arsitektur: Model Domain, Layanan Domain, Layanan Aplikasi, dan Infrastruktur. Mari kita jelajahi bagaimana kita dapat strukturkan aplikasi sederhana mengikuti Arsitektur Onion.
Sebelum melanjutkan, mari kita pertimbangkan domain hipotetis, seperti sistem pemrosesan pesanan dasar.
Lapisan Model Domain
Pertama, mari kita definisikan entitas domain. Dalam contoh kita, ini bisa menjadi kelas-kelas Order
dan Product
. Kelas-kelas ini tidak mengandung logika terkait infrastruktur atau layanan aplikasi, fokusnya hanya pada logika bisnis.
class Product:
def __init__(self, id, name, price):
self.id = id
self.name = name
self.price = price
class Order:
def __init__(self, id, product, quantity):
self.id = id
self.product = product
self.quantity = quantity
self.total = self.calculate_total()
def calculate_total(self):
return self.product.price * self.quantity
Lapisan Layanan Domain
Selanjutnya, kita mengimplementasikan layanan domain. Layanan ini berisi operasi terkait logika bisnis yang melibatkan lebih dari satu entitas domain. Dalam contoh kita, mari kita pertimbangkan DiscountService
yang menghitung diskon untuk suatu pesanan.
class DiscountService:
def apply_discount(self, order, discount_percentage):
if discount_percentage < 0 or discount_percentage > 100:
raise ValueError("Invalid discount percentage")
order.total -= order.total * (discount_percentage / 100)
return order
Lapisan Layanan Aplikasi
Lapisan layanan aplikasi berfungsi sebagai jembatan antara domain dan infrastruktur. Dalam contoh kita, OrderProcessingService
dapat bertanggung jawab atas pembuatan pesanan dan penerapan diskon.
from domain_services import DiscountService
class OrderProcessingService:
def __init__(self, order_repository, product_repository):
self.order_repository = order_repository
self.product_repository = product_repository
self.discount_service = DiscountService()
def process_order(self, order_id, product_id, quantity, discount_percentage):
product = self.product_repository.get(product_id)
order = Order(order_id, product, quantity)
self.discount_service.apply_discount(order, discount_percentage)
self.order_repository.save(order)
Lapisan Infrastruktur
Lapisan infrastruktur dapat mencakup repositori untuk mengakses data dari database. Dalam skenario dunia nyata, ini mungkin melibatkan kueri ke database SQL atau NoSQL, tetapi untuk kesederhanaan, kita akan menggunakan daftar dalam memori.
class OrderRepository:
def __init__(self):
self.orders = []
def save(self, order):
self.orders.append(order)
class ProductRepository:
def __init__(self):
self.products = []
def get(self, product_id):
for product in self.products:
if product.id == product_id:
return product
Referensi