Apa Bedanya Merancang Sebuah Class Dan Sebuah Tabel?
14 Juli 2013 10 Komentar
Salah satu pertanyaan yang sering ditanyakan saat mulai belajar merancang aplikasi secara OOP adalah apa bedanya sebuah class dan sebuah tabel di database? Hal ini cukup meresahkan terutama bagi mereka yang sudah memiliki pengalaman merancang tabel relasional. Mereka mulai meragukan rancangan class diagram saat mereka mempertimbangkan kembali berbagai prinsip di tabel relasional seperti hubungan antar-tabel dan normalisasi. Hingga pada akhirnya, beberapa memilih menganggap class sebagai representasi data layaknya sebuah tabel.
Jadi, apakah merancang class diagram secara OOP adalah hal yang sama seperti merancang tabel di ERD? Sebenarnya class dan tabel adalah dua hal yang berada dalam konteks berbeda sehingga mereka tidak dapat dibandingkan, tapi saya akan mencoba menjawab pertanyaan ini.
Berikut ini adalah cuplikan dari ERD hasil rancangan seorang developer untuk dipakai pada secara prosedural:
Rancangan di atas bukanlah rancangan relasional terbaik, masih banyak yang bisa diperbaiki dari rancangan tersebut. Tapi satu hal yang pasti, rancangan di atas adalah rancangan yang mudah dipakai melalui bahasa pemograman prosedural dan SQL.
Saya akan mencoba menerjemahkan rancangan tersebut ke dalam class diagram. Jangan lupa bahwa sebuah class diagram tetap pada akhirnya harus dipetakan ke dalam tabel. Saya akan mengandaikan bahwa hasil rancangan di class diagram tidak perlu memiliki struktur tabel yang sama seperti versi prosedural di atas.
1. Class Memiliki Struktur Inherintance
Pada rancangan ERD, terlihat bahwa tabel faktur, faktur_retur, faktur_beli, dan faktur_mutasi memiliki sebuah kesamaan, yaitu sama-sama merupakan sebuah faktur. Mereka juga memiliki beberapa field yang sama seperti nomor faktur dan tanggal. Secara OOP, pemisahan ini sangat disarankan, melalui hierarki inheritance dimana faktur_beli adalah sebuah (is-a) faktur, faktur_jual adalah sebuah faktur, dan seterusnya, seperti yang terlihat pada gambar berikut ini:
Pada pemikiran database relasional, inheritance mirip seperti pemisahan tabel dengan relasi one-to-one. Tapi ada perbedaan mendasar yang membuat mereka berbeda jauh.
Pada tabel, perancang akan memisahkan tabel (normalisasi) untuk mengurangi duplikasi guna menghemat penyimpanan; begitu juga ia akan menggabungkan tabel (denormalisasi) untuk mengurangi join sehingga bisa meningkatkan kinerja.
Pada OOP, pertimbangan perancang adalah mensimulasikan ‘permasalahan‘ dengan menciptakan class-class yang mewakili dunia nyata. Dengan demikian, permasalahan dapat dihadapi dengan cara yang lebih mirip seperti pemikiran manusia (bukan pemikiran flow chart gaya komputer).
Memisahkan sebuah class atau melakukan inheritance, bukan saja mengelompokkan data, tetapi juga melakukan abstraction. Perubahan kode program pada superclass secara otomatis akan diterapkan pada seluruh subclass-nya; pertimbangan ini tidak ditemui pada perancangan tabel karena sebuah tabel hanya mewakili data tanpa kode program.
2. Class Lebih Menyerupai “Dunia Nyata” Dibanding Tabel
Tujuan dari sebuah tabel adalah untuk menampung data. Sementara itu, tujuan sebuah perancangan secara OOP adalah untuk mempermudah developer dalam memahami permasalahan.
Tabel faktur (faktur_jual) menampung seluruh data yang berkaitan dengan sebuah faktur. Pada tabel faktur, terlihat bahwa terdapat field-field yang bertujuan untuk menyimpan data pembayaran. Umumnya mereka akan diproses oleh dua halaman/screen yang berbeda, misalnya screen ‘Tambah Faktur‘ untuk mengisi data faktur secara umum dan screen ‘Tambah Pembayaran‘ untuk mengisi pembayaran sebuah faktur yang jatuh tempo. Ini merupakan kandidat untuk memisahkan mereka menjadi dua class yang berbeda, seperti yang terlihat pada gambar berikut ini:
Class Pembayaran dapat dimodifikasi lebih lanjut, misalnya untuk mendukung pembayaran bertahap, seperti yang terlihat pada gambar berikut ini:
Dengan memisahkan class Pembayaran dari class FakturJual, saya memungkinkan kode program yang sama untuk pembayaran dipakai ulang di class FakturBeli seperti yang terlihat pada gambar berikut ini:
Pada contoh class di atas, data beserta dengan kode program yang berkaitan dengan Pembayaran akan di-reuse, sehingga perubahan mekanisme Pembayaran hanya perlu dilakukan pada satu class saja. Sebagai perbandingan, ‘reusability‘ pada sebuah tabel adalah merujuk primary key untuk sebuah record (berorientasi pada data dan bagaimana menghemat media penyimpanan).
3. Class Juga Mewakili Operasi Seperti Perhitungan
Field disc di tabel faktur (master) dan field disc & discrp di tabel penjualan (detail) dipakai untuk menyimpan nilai diskon. Mereka hanya sebuah nilai. Tanpa melihat kode program secara langsung, akan sulit mengetahui bagaimana perhitungan yang melibatkan nilai tersebut.
Berbeda dengan tabel, sebuah class tidak hanya mewakili data, tetapi juga berisi operasi seperti perhitungan. Field yang dipakai untuk perhitungan diskon di tabel di atas merupakan kandidat yang tepat untuk sebuah class tersendiri yaitu Diskon. Berikut adalah contoh rancangannya:
Class Diskon adalah sebuah abstract class yang hanya berisi sebuah method abstract. Setiap turunan class Diskon mewakili sebuah cara perhitungan diskon. Saat ini, setiap baris di faktur (class ItemFaktur) dapat diberikan diskon. Tapi, bagaimana bila total dari faktur juga bisa memiliki diskon? Saya cukup menambahkan asosiasi class Faktur ke class Diskon, seperti pada gambar berikut ini:
Karena class Faktur adalah superclass dari seluruh faktur yang ada, maka turunannya seperti FakturBeli dan FakturJual secara otomatis memiliki asosiasi dengan class Diskon. Bila suatu saat nanti ada penambahan atau perubahan pada class Diskon dan turunannya, maka baik Faktur maupun ItemFaktur dapat langsung mendapatkan imbasnya.
Hal seperti ini tidak dijumpai pada saat merancang tabel. Tabel hanya mewakili penyimpanan data dan tidak menunjukkan seperti apa proses yang terjadi. Developer mungkin akan meletakkan perhitungan diskon pada sebuah function yang di-include atau di-share bersama; developer mungkin juga merasa ini adalah hal sepele sehingga hanya copy-paste rumus ke masing-masing halaman yang membutuhkan; tidak ada patokan atau batasan mengenai ‘proses’ atau perilaku (behaviour) bila hanya melihat rancangan tabel.
4. Class dan Tabel Tidak Dapat Dibandingkan!
Perancangan class secara OOP adalah merancang logika program. Pada OOP, sebuah program dapat dianggap sebagai kumpulan objek yang saling berinteraksi. Mereka pada akhirnya memiliki nilai yang perlu disimpan ke dalam database, dan untuk itu dibutuhkan tabel bila memakai database relasional. Object Relational Mapper (ORM) seperti JPA pada Java atau Doctrine pada PHP berusaha menjembatani perbedaan ini sehingga developer hanya berkonsentrasi pada class-class yang ada tanpa perlu terlalu mengkhawatirkan perancangan tabel.
Ping-balik: Memakai @Embeddable Di JPA | The Solid Snake
Mas, kira2 bisa dibuatin versi griffonnya ga mas?
Yup, bisa, teknik OOP seperti yang ditunjukkan disini dapat diterapkan pada semua bahasa pemograman yang mendukung OOP seperti Java, C# dan Groovy.
Maksud saya bisa di contohkan domain-classnya dibuat di simple-jpa ga mas?
Btw waktu kita buatkan versi installer untuk griffon sendiri pemakaian memorynya tinggi bgt ya mas < 200 MB gt?apa bs ya dikecilin pemakaian memorynya ya?
Salah satu contoh domain class di atas dalam simple-jpa dapat dilihat di https://thesolidsnake.wordpress.com/2013/07/17/memakai-embeddable-di-jpa/
Untuk mengatur pemakaian memori, jalankan Java dengan argumen
Xms
(memori minimal) atauXmx
(memori maksimal). Java memiliki manajemen memori yang kompleks dan keleluasan untuk pengaturan, seperti yang dapat dibaca di http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html#1.1.Other%20DocumentationDi Griffon, bisa juga memberikan nilai
griffon.memory.min
,griffon.memory.max
, ataugriffon.memory.maxPermSize
, tergantung pada jenis memori apa yang ingin dikonfigurasi, pada BuildConfig.groovy.Bila hal ini terjadi pada installer-nya, lakukan tuning pada aplikasi installer-nya.
Sebagai informasi tambahan mengenai penggunaan memori di Java, coba baca: https://thesolidsnake.wordpress.com/2013/07/31/memahami-penggunaan-memori-di-java/
jadi intinya untuk membuat sebuah Class Diagram tidak harus sama persis dengan pembuatan tabel di Database ?
Benar, class berperan penting selama eksekusi program (mencakup logika program) sementara tabel memiliki peran utama dalam penyimpanan data secara permanen.
min mau tanya dong kalo misalkan di class daigram saya ada tabel perencanaan,operator,coustomer,po_masuk,Po_masuk_detail,dan produk nah yg saya mau tanyakan untuk membuat data ERD apa saja ya ?
Thank you mas penjelasannya, waah sekian lama bergelut di dunia pemrograman, baru kali ini saya tercerahkan dalam perbedaan ERD dan class hehe