~/bagas
BerandaTentangProyekKeahlianBlogKontak

~/bagas

Bagas Abiyu Kumara — Software Engineer | Cybersecurity Enthusiast. Mengubah kebutuhan bisnis menjadi sistem yang terstruktur, teruji, dan aman.

BerandaTentangProyekKeahlianBlogKontak

© 2026 Bagas Abiyu Kumara. Dibangun dengan Next.js, Tailwind CSS, dan MDX.

Semua artikel
10 Maret 20263 menit baca

Dari 21 Tabel ke Arsitektur Berlapis: Pelajaran Merancang Aplikasi POS Desktop

Bagaimana pola Model–DAO–Service–UI menyelamatkan aplikasi Java Swing dengan 21 tabel dari nasib menjadi spaghetti code.

System DesignJavaDesktopDatabase

AppKasir — aplikasi Point of Sale desktop yang saya bangun dengan Java Swing — punya 21 tabel database yang saling terelasi: data master, transaksi penjualan, pembelian, retur dua arah, sampai tabel penomoran otomatis. Artikel ini tentang keputusan yang membuat kode seukuran itu tetap bisa dipelihara.

Godaan terbesar Swing: logika di dalam form

Pola yang paling sering ditemui di aplikasi Swing: semua kode — query SQL, kalkulasi, validasi — ditulis langsung di event handler tombol.

// Anti-pattern: semuanya di dalam form
private void btnSimpanActionPerformed(ActionEvent evt) {
    Connection conn = DriverManager.getConnection(URL, USER, PASS);
    PreparedStatement ps = conn.prepareStatement(
        "INSERT INTO penjualan ...");
    // ...50 baris query + kalkulasi + update stok di sini
}

Untuk 3 form ini masih "jalan". Untuk 20+ form dengan alur transaksi yang saling memutasi stok, ini bencana: logika stok tersebar di banyak tempat dan setiap perubahan berisiko merusak alur lain.

Pemisahan tanggung jawab: Model–DAO–Service–UI

Solusinya klasik tapi efektif — layered architecture:

Form / JDialog     →  presentasi, event UI
TableModel         →  binding data ke JTable
Service            →  logika bisnis (interface + implementasi)
DAO                →  seluruh akses database
Model              →  entity murni

Aturan mainnya ketat: form tidak boleh menyentuh SQL, dan DAO tidak boleh berisi aturan bisnis. Contoh alur transaksi penjualan:

PenjualanServiceImpl.java
@Override
public void simpanTransaksi(Penjualan penjualan) {
    // Aturan bisnis hidup di satu tempat
    validasiStok(penjualan.getDetail());
 
    String nomor = nomorDao.generateNomorTransaksi("PJ");
    penjualan.setNomor(nomor);
 
    penjualanDao.insert(penjualan);
    for (PenjualanDetail d : penjualan.getDetail()) {
        stokDao.kurangiStok(d.getProdukId(), d.getJumlah());
    }
}

Ketika kemudian modul retur penjualan dan retur pembelian ditambahkan, keduanya tinggal mengikuti pola yang sama — memanggil stokDao yang sudah teruji, bukan menulis ulang mutasi stok.

Skema dulu, kode kemudian

Pelajaran kedua: waktu yang dihabiskan mendesain 21 tabel dengan relasi yang benar terbayar berkali-kali lipat. Contohnya pemisahan header–detail untuk semua jenis transaksi:

CREATE TABLE penjualan (
  id INT PRIMARY KEY AUTO_INCREMENT,
  nomor VARCHAR(20) UNIQUE NOT NULL,
  tanggal DATETIME NOT NULL,
  karyawan_id INT NOT NULL REFERENCES karyawan(id)
);
 
CREATE TABLE penjualan_detail (
  id INT PRIMARY KEY AUTO_INCREMENT,
  penjualan_id INT NOT NULL REFERENCES penjualan(id),
  produk_id INT NOT NULL REFERENCES produk(id),
  jumlah INT NOT NULL,
  harga DECIMAL(12,2) NOT NULL
);

Karena struktur konsisten di semua transaksi (penjualan, pembelian, retur), modul pelaporan JasperReports hampir "gratis" — template laporan tinggal melakukan join pola yang sama.

Keamanan di aplikasi desktop tetap wajib

Meski berjalan offline, AppKasir tetap menerapkan RBAC Admin/Kasir dengan password ter-hash SHA-256 dan pembatasan menu per peran. Aplikasi desktop bukan alasan mengabaikan pemisahan wewenang — kasir tidak boleh bisa menghapus data master atau melihat laporan laba.

Kesimpulan

Tiga hal yang saya bawa dari proyek ini:

  1. Arsitektur menentukan biaya fitur berikutnya. Modul retur murah karena fondasi Model–DAO–Service sudah benar.
  2. Skema relasional yang baik adalah setengah aplikasi. Konsistensi struktur membuat pelaporan dan analitik mudah.
  3. Pola lama tetap relevan. Layered architecture bukan barang baru — tapi untuk aplikasi data-heavy, ia tetap salah satu alat paling efektif yang kita punya.

Daftar Isi

  • Godaan terbesar Swing: logika di dalam form
  • Pemisahan tanggung jawab: Model–DAO–Service–UI
  • Skema dulu, kode kemudian
  • Keamanan di aplikasi desktop tetap wajib
  • Kesimpulan