Apa Bedanya Merancang Sebuah Class Dan Sebuah Tabel?


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:

Contoh Rancangan Tabel Relasional

Contoh Rancangan Tabel Relasional

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:

Inheritance Di Rancangan OOP

Inheritance Di Rancangan OOP

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:

Pemisahan Class Berdasarkan Perannya

Pemisahan Class Berdasarkan Perannya

Class Pembayaran dapat dimodifikasi lebih lanjut, misalnya untuk mendukung pembayaran bertahap, seperti yang terlihat pada gambar berikut ini:

Pengembangan Class Yang Telah Dipisah

Pengembangan Class Yang Telah Dipisah

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:

Pemisahan Class Meningkatkan Reusability

Pemisahan Class Meningkatkan Reusability

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 Yang Mewakili Perhitungan

Class Yang Mewakili Perhitungan

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:

Reuse Operasi Perhitungan

Reuse Operasi Perhitungan

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.

Perihal Solid Snake
I'm nothing...

6 Responses to Apa Bedanya Merancang Sebuah Class Dan Sebuah Tabel?

  1. Ping-balik: Memakai @Embeddable Di JPA | The Solid Snake

  2. Komang Hendra Santosa mengatakan:

    Mas, kira2 bisa dibuatin versi griffonnya ga mas?

  3. Komang Hendra Santosa mengatakan:

    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?

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: