Handout No: 08
[Handout berikutnya, sebelumnya, atau kembali ke halaman utama]
Modularitas dan Abstraksi Data
3 Maret 1999
Goal: modularitas, penyembunyian informasi (enkapsulasi),
dan abstraksi data
Definisi
-
Modul
unit dari organisasi sistem perangkat lunak yang membundel
sekumpulan entitas (data dan metoda operasi) dan dengan secara teliti mengontrol
apa "user eksternal" bisa lihat atau gunakan.
-
Penyembunyian informasi
dilakukan modul untuk melindungi informasi dari "user
external" dalam penggunaannya (misalnya software error, security) dan merupakan
basis dari abstract data type (ragam data abstraks).
-
Abstract data type (ADT)
Kumpulan obyek dan metoda operasi yang mempresentasikan
sifat-sifat abstraks bagi "user" dengan menyembunyikan bagaimana semua
itu direpresentasikan dalam representasi data level yang lebih rendah.
-
Interface dari modul
Spesifikasi bagaimana modul tersebut dilihat atau digunakan
oleh "user" sementara bagian yang private tetap tersembunyi.
Contoh
-
Sebuah microwave oven sebagai suatu modul. Pemakai dapat
menggunakannya dengan tersedianya interface panel tombol. Pemakai hanya
perlu tahu untuk apa tombol-tombol tersebut dan bagaimana mengoperasikannya.
Pemakai tidak perlu tahu mekanisme kerja oven tersebut secara intenal (tabung
magnetron, chip, dsb.).
-
Window menyediakan sejumlah button untuk dapat menutup, memperbesar,
memperkecil, dsb windows tersebut.
Bahasa Pemrograman Modular
Bahasa-bahasa pemrograman moderen menyediakan cara-cara untuk
dapat membuat sistem perangkat lunak secara modular demikian, yaitu
-
cara untuk mengelompokkan bersama data dan metoda operasi
-
cara untuk mendefinisikan interface yang "clean"
-
cara untuk menyembunyikan rincian internal dari data dan
metoda-metoda operasi
-
cara untuk kompilasi secara terpisah
Contoh:
-
Turbo Pascal menyediakan fasilitas pembuatan TPU dengan definisi
interface.
-
Bahasa C memungkinkan pembuatan object module (*.obj) dan
library (*.a) yang dapat di-link ke modul program utama melalui interface
header file (*.h).
Bahasa Java
Bahasa Java memungkinkan konsep pemrograman modular, enkapsulasi,
dan abstraksi data dengan disediakannya skema-skema class, interface, dan
packages. Enkapsulasi dimungkinkan dengan pendefinisian private
bagi data/metoda yang disemebunyikan dan public bagi data/metoda
yang berperan sebagai interface.
Dalam Java terdapat keyword interface dengan pengertian
yang lain. Keword ini digunakan sebagai suatu definisi teknis yang menyatakan
sekumpulan metoda abstraks yang bisa diimplementasikan dalam pendefinisian
kelas-kelas obyek. Manfaat definisi interface ini agar obyek-obyek dari
sejumlah kelas yang mengimplementasikan interface ini dapat saling direfer
oleh variabel beragam interface ini.
Contoh:
interface Xclass {
public
void whataMethod();
}
public class Aclass
implements Xclass {
public
void whataMethod() {
...// diimplementasikan disini
}
}
public class Bclass implements
Xclass {
public
void whataMethod() {
...// diimplementasikan disini
}
}
class Mainclass {
Xclass
a,b;
static
public void main(String [] a) {
a = new Aclass();
b = new Bclass();
a.whataMethod();
b.whataMethod();
}
}
Contoh lain adalah untuk masalah pencarian data (searching).
Key data bisa muncul dalam berbagai tipe data: int, float,
String,
dsb. Fasiltas interface ini dapat memungkinkan pedefinisan algoritma umum
compareTo()
dalam interface ComparisonKey untuk
setiap tipe data. Selanjutnya kelas-kelas yang mengimplementasikan interface
tersebut dapat didefinisikan sesuai denga tipe data yang dikehendaki.
Dengan fasilitas-fasilitasa ini kita bisa mengembangkan
sistem perangkat lunak besar dengan komponen-komponennya yang bersifat
umum demikian dan selanjutnya dapat di-plug-and-play implementasi dalam
berbagai tipe data.
Fasilitas Java lain dalam pendefinisian modularitas dan
ADT adalah keyword package. Keyword ini membundle sekumpulan kelas
yang satu dengan yang lainnya saling memiliki relasi khusus. Pendefinisian
package ini memungkinkan kompilasi secara terpisah dan diimport sebagai
library.
Sebagai contoh kasus untuk pembahasan modularitas dan
ADT adalah suatu kelas Priority Queue.
Definisi
-
Priority Queue
Priority queue (PQ) adalah suatu struktur data abstraks
yang berperilaku sebagai berikut. PQ adalah kumpulan item data yang masing-masing
memiliki tingkat prioritas yang bisa berbeda. Apabila item data diambil
dari kumpulan tersebut maka item data yang berprioritas paling tinggi lah
yang diperoleh.
Dalam pengembangannya pertama kali adalah memformulasikan
konsep abstraksnya tanpa harus memikirkan tipe datanya, apalagi implementasi
rincinya. Implementasinya sendiri dapat dilakukan dalam dua representasi
level bawah yang berbeda: array atau linked-list yang dapat belakangan
kita buat.
Kegunaannya PQ
Banyak ditemukan dalam masalah-masalah penjadwalan, misalnya
untuk sistem antrian untuk pelayanan pasien dalam ruang praktek dokter,
penjadwalan pembayaran tagihan, dsb. Prioritas bisa didefinisikan dalam
beberapa aspek. PQ dapat digunakan juga untuk pengurutan data kengan key
data sebagai harga prioritas: sejumlah data tak terurut dimasukkan ke dalam
PQ lalu setelah semua masuk satu demi satu data diambil dari PQ. Pada pengurutan
menaik maka data yang diambil ditaruh dari kanan ke kiri elemen-elemen
array. Pada pengurutan menurun harga key bisa kebalikan dari harga prioritas,
alterntifnya data yang di ambil satu demi satu di taruh dari kiri ke kanan
elemen-elemen array.
Spesifikasi PQ
Terdapat sejumlah metoda operasi yang menjadi 'interface':
bagi pemakai kelas obyek ini.
-
mengkonstruksikan PQ yang diinisialisasi kosong
PQ = new PriorityQueue();
-
mendapatkan ukuran (jumlah item data) dalam PQ,
-
menyisipkan item baru dalam PQ,
-
bila PQ tidak kosong, menghapus item dengan prioritas tertinggi
dalam PQ
Secara sepintas bisa diketahui bahwa terdapat suatu proses
internal (yang tidak perlu diketahui oleh user) di dalam skema ini yaitu
pengurutan item data. Implementasi bagaimana pun user "tidak perduli".
Contoh penggunaan dalam metoda pengurutan data berdasarkan
Priority Queue:
void priorityQueueSort(ComparisonKey[]
A) {
int n =
A.length;
PriorityQueue
PQ = new PriorityQueue(); // create & inisialisasi PQ
for (int
i = 0; i < n; i++) PQ.insert(A[i]); // mengisi PQ
for (int
i = n-1; i >= 0; i--) A[i] = PQ.remove(); // mengambil satu/satu
}
Selanjutnya contoh penggunaan PQ dengan tipe key integer
ini dapat dilihat dalam program
lebih lengkapnya.
Pada saat ini definisi kelas PriorityQueue belum diimplementasikan.
Sebelum mengimplementasikannya maka key data item yang sedang kerjakan
ini dibungkus dalam tipe data yang generik yaitu ComparisonKey sebagai
suatu interface.
interface ComparisonKey
{
int compareTo(ComparisonKey
value);
String
toString();
}
Untuk selanjutnya ComparisonKey
ini diimplementasikan sesuai dengan tipe data yang sedang digunakan, dalam
hal ini misalnya kita menggunakan integer (nanti kita lihat bila
key bertipe String).
public class PQItem
implements ComparisonKey {
private
int key;
PQItem(int
value) {
key = value;
}
public
String toString() {
return Integer.toString(key);
}
public
int compareTo(ComparisonKey value) {
int a = this.key;
int b = ((PQItem) value).key;
return ((a==b)? 0:( (a > b)?1:-1));
}
}
Implementasi Kelas PriorityQueue
Pada level yang lebih rendah kelas priority queue ini dapat
diimplementasikan baik dengan array atau dengan linked list
-
Versi
Implementasi Unsorted Array (berukuran dinamis)
PQ menyimpan item data dalam suatu array yang apabila
penuh panjangnya dapat diperbesar secara otomatis. Item data masuk begitu
saja di bagian belakang. Saat di-remove maka item data dengan key
terbesar dicari (dilakukan sequential search). Key yang diremove
tempatnya digantikan oleh key yang paling belakang (tidak melakukan pergeseran!)
-
Versi
Implementasi Sorted Linked-list
Saat item data masuk dalam PQ maka langsung ditempatkan
pada posisi yang sesuai dalam urutan menurun (dilakukan pencarian posisi
terlebih dulu lalu dilakukan insert), dan saat di-remove maka cukup
dilakukan delete-first (node pertama yang diambil.
Kedua implementasi tersebut berfungsi sama tapi dengan implementasi
yang berbeda namun sekali lagi user melihatnya sesuai dengan abstraksi
spesifikasi PQ yang ditentukan. Dalam prakteknya maka kedua versi itu bisa
dipilih tanpa mengubah modul-modul pemakainya selama spesifikasinya ditaati.
Representasi Untuk tipe key lain (Representation Independent Module)
Selain implementasinya yang bisa berbeda tanpa mengubah rancangan
modul tingkat di atasnya, representasi key data pun dapat diimplementasikan
secara berbeda karena ComparisonKey
yang didefinisikan abstraks tersebut. Dengan abstraksi ComparisonKey
di atas maka key bertipe lain dapat menggantikan tipe key integer dalam
contoh di atas.ComparisonKey ini
memiliki konsep Representation Independent Module. Berikut ini representasi
String untuk key.
class PQItem implements
ComparisonKey {
private
String key;
PQItem(String
value) {
key = value;
}
public
String toString() {
return key;
}
public
int compareTo(ComparisonKey value) {
String a = this.key;
String b = ((PQItem)value).key;
return a.compareTo(b); // metoda compareTo dalam kelas String
}
}
Dalam program aplikasinya perubahan terjadi pada bagian
data, sementara sejumlah metoda tetap sama, contoh dalam program
lebih lengkapnya.
Modularitan dan Penyebunyian Informasi dalam Rancangan Program
Saat program menjadi semakin besar terjadi situasi berbahaya:
rumit, sulit melakukan debug, dan hampir tidak mungkin di modifikasi kecuali
dikembangkan dengan taat dan secara terstruktur.
Penulisan program komputer dilakukan melalui medium yang
memungkinkan bervariasinya cara penulisan ekspresi-ekspresi yang potensial
dapat menyebabkan masalah yang besar. Dekomposisi ke dalam komponen-komponennya
pun dapat bervariasi, bisa saling kait-mengkait secara kompleks atau teratur
dalam layer-layer.
Abstraksi prosedural: menyatakan fungsi "apa" (what)
yang dilakukan suatu prosedur. Kita perlu mendefinisikan "apa" dari suatu
prosedur terpisah dari "bagaimana" (how) cara yang dilakukan
prosedur untuk mencapai fungsi tersebut. Setelah terdefinisi dengan baik
abstraksi prosedur ini kemudian kita boleh menuliskan rincian "bagaimana"
tersebut, bahkan suatu saat misalnya untuk peningkatan efisiensi maka metodologi/algoritmanya
dapat disubstitusikan tanpa mengubah abstraksi proseduralnya. Jadi pemisahan
tersebut memberi manfaat:
-
memudahkan penggunaan -- hanya perlu tahu apa yang dilakukan
suatu prosedur P
-
memudahkan modifikasi -- rincian penulisan P dapat diubah
tabpa mengganggu program secara keseluruhan (di mana saja pada pemanggilan-pemanggian
P).
Secara umum pendefinisian abstraksi dengan baik pada perancangan
program dapat mengendalikan kompleksitas program serta meningkatkan modifiabilitas.
Penyembunyian informasi (enkapsulasi) baik variabel ataupun
metoda dalam modul-modul bermanfaat dalam:
-
menghindari interferensi entitas lokal dalam modul
terhadap entitas bernama sama di luar modul
-
menghindari interferensi entitas diluar modul terhadap
entitas lokal dalam modul terhadap entitas bernama sama
Bahasa berorientasi obyek semacam C++ atau Java mengakomodasikan
enkapsulasi ini dengan baik dengan deklarasi private. Dalam Java terdapat
tingkatan lebih lanjut sepain private, yaitu: package, protected, baru
kemudian public.
Istilah package dalam Java memiliki konsep yang sama dengan
istilah unit atau module dalam bahasa pemrograman lain.
Keyword untuk diingat:
-
abstraksi prosedural
-
abstraksi data
-
enkapsulasi
Handout berikutnya, sebelumnya, atau kembali ke halaman utama