Traffine I/O

Bahasa Indonesia

2022-11-19

Arsitektur Heksagonal

Apa itu Arsitektur Heksagonal

Arsitektur Heksagonal, juga dikenal sebagai pola Ports and Adapters, adalah sebuah pola arsitektur perangkat lunak yang mendorong pemisahan kepentingan dengan memandang aplikasi sebagai heksagon. Setiap sisi heksagon mewakili sebuah port yang berinteraksi dengan dunia eksternal melalui adapter.

Arsitektur Heksagonal bertujuan untuk memusatkan logika bisnis inti aplikasi dan mengisolasi logika tersebut dari kepentingan periferal, menjaga batas yang jelas yang tidak dapat dilanggar oleh faktor eksternal. Isolasi ini memungkinkan perubahan pada satu sisi aplikasi (misalnya, database atau antarmuka pengguna) dapat terjadi secara independen dari sisi lainnya, menjamin kestabilan aplikasi dan mempermudah proses pengujian dan pemeliharaan.

Prinsip-prinsip Arsitektur Heksagonal

Dalam bab ini, saya akan menggali prinsip-prinsip yang mendasari arsitektur heksagonal. Kita akan menjelajahi konsep-konsep kunci seperti aplikasi, port, adapter, dan lapisan heksagonal.

Hexagonal architecture
Hexagonal Architecture Explained

Pusat: Aplikasi

Di jantung arsitektur heksagonal terdapat aplikasi, juga dikenal sebagai domain. Ini menggabungkan aturan bisnis dan logika inti perangkat lunak. Aplikasi tidak memiliki ketergantungan pada kepentingan eksternal, seperti database, antarmuka pengguna, atau layanan pihak ketiga apa pun. Fitur ini sangat penting karena memungkinkan kita untuk melakukan perubahan pada bagian sistem tanpa memengaruhi aplikasi inti.

Port: Masuk dan Keluar

Aplikasi berinteraksi dengan dunia luar melalui port, yang dapat dikategorikan menjadi port primer (atau penggerak) dan port sekunder (atau yang digerakkan).

Port primer adalah antarmuka yang mengungkapkan operasi yang disediakan oleh aplikasi kepada dunia luar. Mereka mewakili kasus penggunaan yang didukung oleh aplikasi, mendefinisikan apa yang dapat dilakukan aplikasi. Biasanya, ini adalah API yang akan dirancang dan diimplementasikan oleh pengembang aplikasi.

Port sekunder, di sisi lain, adalah antarmuka yang digunakan aplikasi untuk berinteraksi dengan layanan atau komponen eksternal. Ini adalah hal-hal yang dibutuhkan aplikasi dari dunia luar untuk berfungsi, seperti mekanisme penyimpanan, pemberitahuan, atau API eksternal apa pun.

Adapter: Perantara

Sementara port mendefinisikan jenis interaksi yang mungkin, adapter menangani interaksi tersebut. Adapter adalah penghubung antara aplikasi dan dunia luar. Mereka mengonversi data dari format yang digunakan oleh dunia luar menjadi format yang dapat dipahami oleh aplikasi, dan sebaliknya. Ada beberapa jenis adapter untuk berbagai jenis input dan output, seperti adapter web untuk menangani permintaan HTTP atau adapter database untuk berinteraksi dengan database.

Lapisan Heksagonal

Setiap sisi heksagon dalam arsitektur mewakili sebuah port. Adapter yang berinteraksi dengan port-port ini ditempatkan di tepi heksagon. Penyusunan ini menghasilkan representasi fisik arsitektur sebagai heksagon, yang memberikan nama pola ini.

Arsitektur heksagonal berbeda dari arsitektur berlapis tradisional karena tidak ada lapisan "atas" atau "bawah". Sebaliknya, semua masukan dan keluaran diperlakukan sebagai sama dan ditempatkan di sekitar tepi heksagon, memastikan aplikasi inti tetap terisolasi dan tidak terpengaruh oleh perubahan eksternal.

Implementasi Praktis Arsitektur Heksagonal

Aplikasi berbasis Python yang menggunakan arsitektur heksagonal dapat diorganisir dalam struktur direktori sebagai berikut:

/bookstore
    /application_core
        __init__.py
        application_core.py
    /ports_and_adapters
        __init__.py
        ports_and_adapters.py
    /interfaces
        __init__.py
        interfaces.py
    /tests
        __init__.py
        tests.py
    main.py

Merancang Inti Aplikasi

Inti aplikasi menggabungkan aturan bisnis dan logika sistem. Pertimbangkan sebuah aplikasi toko buku yang disederhanakan, di mana kita akan memiliki entitas Book dan layanan Inventory.

/application_core/application_core.py

class Book:
    def __init__(self, id, title, author, price):
        self.id = id
        self.title = title
        self.author = author
        self.price = price

class Inventory:
    def __init__(self, repository):
        self.repository = repository

    def add_book(self, book):
        return self.repository.save(book)

Membuat Port dan Adapter

Di sini kita membuat port dan adapter untuk sistem. Kita mendefinisikan antarmuka BookRepository (port sekunder) dan implementasi konkret dari antarmuka tersebut, yaitu InMemoryBookRepository (adapter).

/ports_and_adapters/ports_and_adapters.py
from abc import ABC, abstractmethod
from application_core.application_core import Book

class BookRepository(ABC):

    @abstractmethod
    def save(self, book: Book):
        pass

class InMemoryBookRepository(BookRepository):

    def __init__(self):
        self.books = {}

    def save(self, book: Book):
        self.books[book.id] = book
        return book

Mengembangkan Antarmuka

Antarmuka mewakili port primer dalam arsitektur heksagonal. Pada aplikasi toko buku kita, mungkin kita akan memiliki antarmuka baris perintah yang sederhana.

/interfaces/interfaces.py
from application_core.application_core import Book, Inventory
from ports_and_adapters.ports_and_adapters import InMemoryBookRepository

def command_line_interface():
    repository = InMemoryBookRepository()
    inventory = Inventory(repository)

    book_id = input("Enter book id: ")
    title = input("Enter book title: ")
    author = input("Enter book author: ")
    price = float(input("Enter book price: "))

    book = Book(book_id, title, author, price)

    inventory.add_book(book)
    print(f"Added book {title} to inventory.")

Mengimplementasikan Pengujian

Pengujian lebih mudah ditulis dan dipelihara dalam arsitektur heksagonal karena dependensi dapat digantikan dengan test double. Berikut adalah contoh kasus pengujian sederhana untuk menambahkan buku ke inventaris.

/tests/tests.py
import unittest
from application_core.application_core import Book, Inventory
from ports_and_adapters.ports_and_adapters import InMemoryBookRepository

class TestInventory(unittest.TestCase):

    def test_add_book(self):
        repository = InMemoryBookRepository()
        inventory = Inventory(repository)
        book = Book('1', 'Test Book', 'Test Author', 9.99)
        inventory.add_book(book)
        self.assertEqual(repository.books['1'], book)

if __name__ == '__main__':
    unittest.main()

Di direktori utama, Anda mungkin memiliki file main.py yang mungkin terlihat seperti ini:

main.py
from interfaces.interfaces import command_line_interface

if __name__ == '__main__':
    command_line_interface()

Referensi

https://www.arhohuttunen.com/hexagonal-architecture/
https://betterprogramming.pub/a-quick-and-practical-example-of-hexagonal-architecture-in-java-8d57c419250d

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!