Learn the Rules, Break The Rules, and Create the New Ones...

Hi... My name is Rizky Prihanto. You can call me RQ, or Rizky either. I am currently living on Bandung, Indonesia. Had a lot of works and research about Enterprise Information Systems (majoring on education and e-governments). I have bunch of interests (some friends call it 'freakz') about MySQL Opensource Database and now I am one of the administrator of MySQL Indonesia User Group - the opensource community initialized by Sun Microsystems Indonesia.

My Company PT Cinox Media Insani, Bandung, Indonesia. I work here since 2008 and I take responsibility as Chief of Software Architect. My job is about planning, imaginating, fantasy-ing, concepting, and build the infrastructure of the new information systems (or app engines) which going to be implemented.

This blog This is my blog that represent my current opinion, research and experiences about anything in Software Engineering. Written since 2007 (actually) and has been vaccum for a lot of while. And now I wanna ressurrect this blog (optimistically) from the long-long-hibernation with something fresh and new ideas -- still about MySQL, software engineering, development, and may be something managerial here.

About the tagline I've learned the statement above from some paper written by Kent Beck about Extreme Programming (XP) methodology -- some sort of practical software development methods which have no boundaries. That's very inspiring me a lot. I have written some article on this blog that tell my interpretation about that statement here.

My Another Blogs I have classifying my blogs into some sort of genre. The blog that you read here right now is my primary blog that tell you (majoring) about IT stuff. But if you wanna look another side of me, you can visit here, here, here,or here. Hope it'll be interesting for some of you.

Credits I would thanks to Blogger for this great blog platform. Skinpress who designed this Wordpress template (which is bloggerized by Free Blogger Templates). My appreciate is also going to you who give your generously time for visiting my blog.

Filosofi OOP

Ini ada artikel menarik tentang konsep OOP. Nggak tahan aku untuk ngga ta' publish di blog ini. Bagussh banggedd soalnya. Inspirasional n provokatif. Yupz! PROVOKATIF... Sumber pastinya ga tau siapa yg nulis. Klo *ternyata* salah satu dari kalian ada yg merasa nulis ini artikel, FEEL FREE to contact me..., u'll have the credits to this nice article...

Oke, tanpa basa-basi lagi, lets go...

~~~~


Begitu banyak buku mengenai Object Oriented Programming (OOP) telah ditulis. Akan tetapi hingga saat ini, pemahaman mengenai OOP dirasa masih kurang. Saya kira sebab-musabab-nya adalah terletak pada dua hal:

1. Buku OOP selalu memulai pembahasannya dengan SYNTAX bahasa OOP, yang memang paling popular yaitu : Encapsulation, Inheritance, dan Polymorphism.

2. Selalu mulai dengan contoh paradigma keluarga buah-buahan, atau kendaraan, atau jenis-jenis binatang, yang memang merupakan object di dunia nyata, tapi relevansinya dengan dunia programming, yg sangat virtual, yg penuh kreativitas dan khayalan, sangatlah jauh. Yang terbaik dari contoh ini adalah ya itu… untuk melatih menghafal syntax-syntax OOP di atas.

Oleh karena itu artikel singkat ini bertujuan untuk mencoba menjelaskan OOP dari sudut pandang yang lain, yang tidak terikat dengan bahasa pemrograman apapun. Karena, you know what, kita bisa ber-OOP-ria menggunakan bahasa apapun, yes hanya dengan BASIC Interpreter, dengan Assembly, kita bisa ber-OOP dengan sangat sempurna.

Jadi yang penting adalah mengerti OOP, sedangkan bahasa OO hanyalah sebuah tool belaka. Seperti halnya orang melukis. Bisa melukis adalah seperti bisa OOP. Bahasa prosedural adalah pensil hitam putih. Bahasa OO adalah cat warna. Orang yang bisa melukis, biarpun hanya pakai pensil hitam putih, lukisannya bagus juga. Yang tidak bisa melukis, walaupun pake cat warna, lukisannya juga pasti tidak bagus

1.1. Mengapa OOP

Kita langsung saja ke permasalahan paling mendasar, sedasar-dasar-nya, pertanyaan yang seharusnya selalu terngiang-ngiang di pikiran setiap Software Developer yg memang NIAT programming, yaitu:

1. “MENGAPA OOP BISA MENGURANGI BUG”.

2. “MENGAPA OOP BISA MENINGKATKAN KEMAMPUAN KITA UNTUK MEMBUAT PROGRAM YANG LEBIH BESAR DAN LEBIH RUWET”.

Jawabnya hanya satu : LOKALISASI.

Konsep ini dikenal dengan banyak nama : encapsulation, independensi, modular, object, re-usable, information hiding, dll, dll, apapun nama keren lainnya. Intinya hanya berisi dua jurus:

1.1.1. Semua yang bisa dikumpulkan jadi satu, kumpulkan jadi satu

Otak orang terbatas. Size program tidak terbatas. Jadi sepintar apapun seseorang, kalau otaknya yang terbatas itu tidak digunakan dengan baik tidak akan bisa menghasilkan program yg bermanfaat. Bahkan yang otaknya idiot-pun kalau digunakan dengan baik, akan menghasilkan sesuatu yang luar biasa. Pernah nonton film “Forrest Gump”-kan, ini adalah film yang seharusnya ditonton oleh semua software developer.

Dengan dikumpulkan jadi satu sedekat mungkin, kalau kita melakukan perubahan, kita dapat dengan mudah mencari bagian mana saja yang harus dicek. Ini penting, karena dengan otak yang terbatas, kita tidak mungkin ingat bagian program mana saja yang harus kita cek kalau kita melakukan perubahan.

1.1.2. Yang tidak perlu diketahui oleh yang lain, jangan di-publish

Dengan tidak mem-publish sesuatu yang tidak perlu diketahui oleh yang lain, ini menjamin variable-variable yang sudah kita kumpulkan jadi satu (dengan teknik di atas), tidak diutak-atik oleh bagian program yang lain. Dengan otak yang terbatas kita tidak mungkin setiap kali ingat bahwa sebuah variable tidak boleh diakses sembarangan.

Hmm, seperti halnya “lokalisasi” yang baik untuk merapihkan W/PTS supaya tidak merusak masyarakat, ternyata baik juga untuk merapihkan code-code yang tuna-susila.

1.2. Private Modifier adalah Fitur Terpenting dari Bahasa OOP

Dengan merenungkan kedua teknik tersebut, kita akan memahami mengapa teknik pemrograman ini disebut “OBJECT”. Karena itu memang seperti object. Kalau kita membeli barang / object, TV, buah, DVD, mobil, laptop, PC, dll, dll, kita tidak pernah pusing dengan apa isinya, dan tidak bisa mengutak-atik isinya karena terlindung di dalam boxnya. Yang perlu kita perhatikan adalah bagaimana menggunakannya, atau interface-nya. NOTE : hanya ini kesamaan object oriented dengan object dunia nyata – jangan diperpanjang menjadi contoh programming object oriented programming karena nggak kebayang program keluarga buah-buah-an punya manfaat apa (selain daripada digunakan oleh yang mencari contoh seenaknya).

Perhatikan bahwa saya tidak menyebutkan “bahasa”, tetapi hanya “teknik”, yang berarti memberi penekanan bahwa teknik OOP tidak terikat dengan bahasa pemorgraman apapun.

Bahkan sesungguhnya, bahasa OOP tidak memberikan sumbangsih banyak ke konsep ini, bahasa OOP hanya menambahkan SATU (YES, HANYA SATU) fitur untuk menunjang konsep ini, yaitu : private modifer (YES, HANYA PRIVATE MODIFIER).

Penemu konsep OOP (kalaupun ada) sangatlah jenius, dengan menyebutkan konsep “Object”, dia sudah menemukan sebuah penekanan MAHA penting dari teknik pemrograman. Dengan bahasa pemrograman paling muktahir sebelum OOP, semua konsep OOP bisa diimplementasikan dengan baik, hanya kurang fitur private variable tersebut.

Mari kita renungkan hal-hal berikut.

Encapsulation, Inheritence, dan Polymorphism, hanyalah teknik penulisan syntax yang lebih convenience saja. That’s all. Dengan gampang kita bisa melakukan ketiga syntax tersebut (Encapsulation, Inheritence, dan Polymorphism) menggunakan bahasa non-OOP.

1. Encapsulation bisa disubtitusi dengan fungsi yang parameter pertamanya adalah handle. Contoh yang paling popular adalah Win32 API. Contoh:

“objWindow.Resize(…”menjadi “WndResize(hWindow, …)“

2. Inheritance (yg katanya adalah untuk re-usable) bisa disubtitusi dengan mudah menggunakan “containment” (struktur data yang di dalamnya mempunyai struktur data lain). Contoh:

“class DialogBox : Window {…“ menjadi “class DialogBox {Window myParent; …“

3. Polymorphism, well, ini dengan mudah disubtitusi menggunakan teknik penamaan fungsi yang baik, atau menggunakan fungsi yang parameternya struktur data. Contoh:

“CreateWindow(), CreateWindow(int xLoc, int yLoc)“ menjadi “WndCreateWindow(), WndCreateWindow_2(int xLoc, int yLoc)”

Ketiga hal tersebut, yang disebut sebagai pilar dari Object Oriented Programming, adalah OMONG KOSONG belaka. Dengan mudah kita bisa mematahkan argumen developer yang menyebutkan manfaat OOP adalah ketiga pilar tersebut. Dan sesungguhnya developer tersebut belum mengerti apapun mengenai OOP.

Yang terbaik dari ketiga hal tersebut adalah penamaan yang keren, yang membantu penjualan compiler OOP, karena ini lebih menjual daripada compiler yang hanya menambah fitur “private variable” ?

1.3. Teknik OOP Lokalisasi selain Private Modifier

Jadi apakah saja teknik-teknik OOP yang sesungguhnya… berikut adalah sebagian dari teknik OOP yang sepenuhnya hanya berdasarkan konsep LOKALISASI di atas. Sebagian dipandang begitu kampungan sehingga orang malu menyebutkannya, tetapi inilah contoh-contoh teknik OOP yang sesungguhnya.

Intermezzo : Kalau kalian mengamati improvement yang dilakukan oleh designer Microsoft .net Framework terhadap bahasa-bahasa pemrograman, terutama C# dan VB .net, termasuk Visual Studio .net, teknik-teknik lokalisasi berikut ini sangat di-emphasize oleh VS .net. Inilah salah satu reason utama mengapa kita memilih VS .net dan Ms .net Framework.

1.3.1. Definisi Variable Sedekat Mungkin dengan Lokasi Digunakannya Variable tersebut Pertama Kali

Jika ada monitor yang seukuran dinding, monitor tersebut adalah monitor terbaik untuk programming. Mengapa? Karena dengan demikian kita bisa sekaligus melihat banyak hal, aka “lokalisasi”. Sayangnya monitor seperti itu sangatlah mahal. Oleh karena itu dengan mendeclare variable sedekat mungkin dengan lokasi digunakannya variable tersebut pertama kali adalah sebuah fitur yang sangat baik karena dengan begitu kita yakin:

1. Variable tersebut berada di lokasi terdekat dengan lokasi yang menggunakan variable tersebut, sehingga kemungkinan besar bisa kita lihat langsung di layar monitor kita yang terbatas.

2. Kita yakin bahwa variable tersebut belum pernah digunakan di code-code yang mendahului deklarasi variable tersebut (hampir seperti private modifier).


Teknik ini sering dianggap tabu, karena banyak pelajaran dasar pemrograman kita yang dimulai dengan Pascal, yang syntax model lamanya adalah mengharuskan kita untuk mendeklarasi segala sesuatu di bagian atas fungsi / program. Perlu dinote bahwa teknik Pascal yang seperti itu mungkin ada kaitannya teknik kompilasi, dimana compiler yang memungkinkan deklarasi variable di mana saja, relatif lebih sulit dibuat.

Keuntungan lain dari deklarasi variable sedekat mungkin adalah kita dapat menerapkan teknik copy/cut-paste dengan lebih clean.

Note : sering terjadi salah persepsi bahwa copy/cut-paste adalah teknik yang jelek. Yang jelek adalah jika dan hanya jika teknik copy/cut-paste tersebut menghasilkan code yang redundan. Jika tidak itu adalah teknik yang sangat baik karena jelas mempercepat coding.

1.3.2. Code Editor Searching

Sebaik apapun teknik lokalisasi kita terapkan, tidaklah mungkin sempurna. Tentu ada bagian dari code kita, yang mau tidak mau tersebar di mana-mana. Dengan fitur searching dari code editor, memungkinkan kita untuk menemukan code-code tersebut dengan mudah. Dengan demikian walaupun lokasi dari code-code tersebut tidak berada di satu file, dan bahkan mungkin beda folder dan solution, tetap terasa dekat. Inilah salah satu bentuk implementasi teknik lokalisasi yang nyata.

Kalau kalian mengamati, fitur “Search” di Visual Studio .net, adalah fitur search tercepat yang pernah ada. VS .net keliatannya bahkan menggunakan sebuah teknologi “text” caching dan algoritma khusus untuk ini. That is OOP concept.

1.3.3. Pattern Debugging

In very often case, you can simply find bug, by just watching the pattern of your program. When you find something un-usual, that means there is “something”. Of course, this can be done only WHEN YOU PROGRAM IN STANDARD MANNER (so it is very important that as long as it is possible, to always write program in standard manner). (Dan inilah kegunaan utama dari sebuah standar, bukan debat kusir Camel Notation atau Hungarian Notation. Debat bagusan warna Biru atau Orange ya.)

Note : When your pattern bends but it turns out that it must be so, IT IS AN INDICATION YOU HAVE TO GIVE IT A COMMENT. This way you will save your time (I bet you will forget about this just in the next day) and your colleagues.

Dengan pattern debugging, Anda bisa melihat code dari sudut pandang yang berbeda. Kesamaan dari pattern di seluruh aplikasi, adalah sebuah bentuk dari teknik lokalisasi juga, karena pada saat bersamaan Anda bisa melihat code-code yang saling terkait (walaupun code-code tersebut mempunyai lokasi fisik yang jauh).

Yup inilah OOP. Dan ini juga mengapa saya tidak terlalu setuju untuk membanding “object” di software dan “object” dunia nyata. Karena keduanya berbeda jauh, yang satu virtual, yang lain nyata. “Object” dunia nyata tidak bisa seperti ini ( menurut teori Fisika non-quantum yang merupakan persepsi kebanyakan orang ? ).

Dengan membandingkannya dengan “object” dunia nyata, lebih cenderung menghancurkan pengertian developer mengenai OOP – daripada manfaat yang didapat.

1.3.4. COMMENT

Comment, yach comment, adalah OOP. Kenapa? Dengan comment memungkinkan kita untuk menjangkau / menyatukan code-code yang tidak terjangkau dengan teknik-teknik lokalisasi yang ada (private modifier, deklarasi variable sedekat mungkin, code editor searching, pattern debugging, dll). Dengan comment kita bisa mengetahui bahwa sebuah code affect kemana saja, dan juga mengapa code kita agak “aneh” karena mengakomodir behavior dari code yang lain. Ini adalah lokalisasi karena pada satu waktu kita bisa melihat seluruh code yg terkait.

Anw that comment is TRULY OOP too My Friends!

(Dan hebatnya sekarang ada gerakan untuk membuang comment dari code, dibilangnya apa itu… “bad smell”. Coool, so kalau gerakan ini sukses, terima-kasih banyak, karena persyaratan software developer masa depan adalah harus dilengkapi dengan indra keenam.)

1.3.5. “Goto” adalah OOP, BETUL BETUL OOP

Satu teknik yang dipandang kampungan oleh sebagian besar orang adalah “Goto”. Kasihan sekali Goto, karena yang salah sebenarnya adalah pengguna Goto, bukan Goto-nya sendiri.

Goto sangatlah baik, dan sangat-sangat baik sekali untuk digunakan sebagai error handling. Dengan goto memungkinkan kita untuk memisahkan antara “normal flow” dari aplikasi dan “error handling”. Kenapa ini perlu dipisahkan? Karena error handling biasanya sangat simple dan jarang terkait dengan normal flow (note : error handling yang terkait dengan normal flow aplikasi, bisa dipastikan itu bukanlah error handling, melainkan bagian dari normal flow aplikasi). Dengan demikian kehadiran error handling di tengah-tengah normal flow aplikasi, tentu sangat mengganggu clarity dari code kita. Tidak ada gunanya kita ber-lokalisasi, tetapi jika yang dilokalisasi adalah caut-marut. So Goto membantu emphasize OOP.

Anw, karena kesalahan persepsi tersebut, and tx juga, diciptakan sebuah syntax khusus untuk error handling yang lebih convenience, yakni : Try-Catch. Tanpa memahami esensi dari error handling di atas, atau inti dari konsep lokalisasi di OOP, Anda tidak akan bisa menghargai manfaat sesungguhnya dari Goto maupun Try-Catch.

1.4. Fitur Bahasa OOP yang Baik selain Private Modifier

1.4.1. Re-usable

Re-usable adalah kata yang selalu didengung-dengungkan oleh developer OOP. Sayangnya saya belum pernah menemukan satu developer-pun yang bisa menunjukkan ini dengan baik.

Contoh yang selalu digunakan untuk menunjukkan re-usable adalah ke-tiga-pilar-omong-kosong itu.

Re-usable itu sudah ada, bahkan di Bahasa Assembly yang paling primitif-pun sudah ada. Kalau Anda punya fungsi, dan fungsi itu bisa digunakan oleh seluruh bagian dari code, ini adalah re-usable. Perkara fungsi itu letaknya ada di object, module, manifest yang berbeda (beda exe), dll, selama fungsi itu bisa kita akses, namanya adalah re-usable. Ok.

Jadi apa yang ditambahkan oleh OOP ke masalah re-usable ini? Inilah sifat khusus dari Inherintance, baik Implementation Inheritance maupun Interface Inheritance, yang bermanfaat untuk re-usable.

Re-usable yang sudah secara sejak dulu tersedia adalah “calling re-usable”, yaitu banyak code memanggil sebuah code. Jika Anda mempunyai sebuah fungsi “CalculateBonus”, dan fungsi ini dipanggil dari modul Sales Order dan Delivery Order, ini adalah “calling re-usable”.

Yang belum tersedia secara explisit di bahasa-bahasa non-OOP adalah “callback re-usable” (kecuali menggunakan pointer, tetapi pointer berpotensi menimbulkan masalah lain yang lebih serius). Jika Anda membuat aplikasi seperti Trilian Messenger, yaitu sebuah program chatting yang mempunyai fitur untuk chat dengan berbagai messenger lain seperti Yahoo! Messenger, MSN Messenger, Google Messenger, ICQ, dll, akan lebih convenience jika Anda menyediakan satu macam user interface untuk chatting yang bisa bekerja dengan semua messenger tersebut. Atau seperti Windows yang bisa mengakses berbagai macam hardware. Inilah problem yang solusi paling baiknya adalah menggunakan “callback re-usable’.

Keliatannya bedanya? Untuk “callback re-usable”, code pemanggilnya yang digunakan bersama-sama (untuk kasus “calling re-usable”, code yang dipanggil yang digunakan bersama-sama).

Inilah improvement Bahasa OOP terhadap re-usable. Note : yang di-improve adalah Bahasa-nya, bukan konsep Lokalisasi, dan pada kenyataanya ini juga merupakan implementasi dari konsep Lokalisasi. Karena tanpa Bahasa OOP-pun kita bisa lakukan “callback re-usable”.

Dengan memahami teknik “Lokalisasi”, baru Anda bisa menyelami kegunaan sesungguhnya daripada Inherintance.

1.4.2. Declarative Programming

Kesalahan terbesar dari design Microsoft Transaction Server adalah memisahkan behavior dari sebuah code, ke tempat yang jauh sekali dari code-nya (di Transaction Server Administration). Ini bertentangan sekali dengan konsep Lokalisasi.

Inilah yang diimprove dengan Declarative Programming. Untuk yang belum tahu inilah salah satu contoh syntax Declarative Programming:


[Serializable]
public class SomeClass
{



“[Serializable]” adalah sebuah declarative yang menyatakan sebuah class support fitur “seriazable” (bisa disimpan dalam bentuk XML). Dengan Declarative Programming, memungkinkan property-property diatur langsung di tempat yang sedekat mungkin dengan code yang diaturnya, bukan di tempat yang nun-jauh ntah dimana.

Sebenarnya inipun merupakan sebuah bentuk dari “callback re-usable”, maksudnya ujung-ujungnya diimplementasikan sebagai Interface Inheritance juga.

Berikut adalah beberapa contoh dari mistik (miss-perception) Bahasa OOP yang jelek, karena lebih banyak menimbulkan salah persepsi dibandingkan manfaatnya. Beberapa bahkan betul-betul jelek karena menghancurkan konsep Lokalisasi (konsep terpenting dari OOP).


2.1. Operator Overloading

Operator Overloading hanya betul-betul diperlukan di kasus tertentu yang sangat sedikit jumlah. Akan tetapi fitur ini ”sangat merangsang” para developer untuk menggunakannya karena dipandang sangat “cool”. Akibatnya lebih banyak ajeb-nya daripada manfaat-nya. Fitur ini dengan gampang disubtitusi menggunakan function call seperti biasa DAN INI BAHKAN LEBIH TERANG-BENDERANG. Dengan Operator Overloading, kita tidak pernah yakin apakah ”+” hanya berarti ”+” bukan merupakan operasi penggabungan alokasi memori (yang mempunyai impact sangatlah dasyat). Ini bahkan menghancurkan konsep Lokalisasi. Kenapa? Karena tujuan dari konsep Lokalisasi adalah supaya code kita terang-benderang, jelas mana aja yang harus diubah, dan mana yang tidak boleh diubah, A ya A. Tx to Operator Overloading, A belum tentu A lagi.

2.2. Get-Set Evil Duo

That is sooo coooool, sehingga sebagian developer merasa cool kalau semua variable dibuat sebagai get-set. Yang terbaik dari pemikiran ini adalah membuat mata sakit.

Klo ada sebuah variable bisa di-set dan di-get, ya itu namanya public variable. Klo tidak punya get dan set sama sekali, namanya private variable. Kedua ini sudah ada syntaxnya (yg jauh lebih sederhana) sejak jaman baheula. Klo hanya bisa di-get, berarti hanya bisa dibaca, ini namanya read-only variable, baru agak baru dan sedikit ada gunanya. Agak baru karena inipun dengan mudah dilakukan dengan menggunakan sebuah fungsi biasa (misal : GetProcessorDate).

Dan yang bahaya, adalah sebuah statement kecil meng-assign sebuah variable, bisa berujung kepada access ke database server di sebuah server nun jauh dimana. Ini namanya tidak terang-terangan. Menggunakan bahasa OOP supaya code lebih manageable, tapi untuk yang dari dulu sudah ok, malah dibuat jadi lebih rumit karena ngotot mau programming “pure” OOP.

2.3. Black Box

Oleh beberapa orang yang sangat kreatif, omong kosong dari Encapsulation “disempurnakan” lebih lanjut menjadi konsep Black Box. Apa itu? Bahwa dengan Encapsulation kita tidak perlu lagi peduli dengan code dari fungsi yang kita panggil. Ini jelas Salah Besar.

Arti yang sebenarnya dari Black Box, adalah kita jangan mengutak-atik isi dari sebuah fungsi (anw note : fitur private variable tidak menghalangi kita untuk mengutak-atik sebuah private variable, misalnya dengan teknik direct-memory-access). TETAPI BUKAN KITA TIDAK USAH PEDULI MAUPUN TIDAK PERLU TAHU MENGENAI ISI DARI FUNGSI YANG KITA PANGGIL.

Untuk menggunakan Handphone, Anda harus tahu jelas apa gunanya Handphone, dan punya pengertian cukup mengenai bagaimana cara kerja Handphone. Sama saja, dan sangat masuk akal sehat, kalau mau menggunakan sebuah fungsi, mengertilah dulu mengenai fungsi tersebut. Jika baca dari API Guide sudah cukup, fine, jika masih belum jelas, lihat langsung ke source-code-nya.

Terima-kasih sebanyak-banyaknya terhadap orang-orang kreatif tersebut, karena Software Developer yang MALAS mempunyai landasan mistik kuat untuk tidak membaca / mengerti source-code dari sebuah fungsi.

2.4. Antisipasi untuk Masa Depan

OOP terhitung bahasa modern, masa depan-lah. Developer yang gak menguasai OOP berarti ketinggalan jaman. That is ok-lah. Yang jadi masalah adalah developer menjadi super kreatif, sehingga kalau programming, selalu berpikir ini untuk antisipasi masa depan… alhasil banyak code-code yang tidak dipakai sekarang, tapi NANTI untuk masa depan.

SATU FAKTA YANG SUDAH JELAS (di masa sekarang) : code menjadi tambah rumit untuk sesuatu di masa depan. Antisipasi masa depan adalah bagus, yang salah ada pemahaman mengenai apa yang dimaksud di masa depan. Sebuah logika sederhana yang dipatut direnungkan : kalau Anda mengatakan antisipasi masa depan, seberapa jauhkah? Kalau membuat aplikasi ERP, apakah mau disiapkan ke depan sampai dengan setara dengan SAP, atau bahkan lebih? Kalau membuat sebuah sistem di perusahaan yang sudah menggunakan SAP, apakah mau diantisipasi sehingga bisa berjalan juga kalau perusahaan itu berubah menggunakan Oracle Applications? Kalau membuat aplikasi untuk Windows, apakah disiapkan supaya bisa jalan di Linux, Apple, Sun OS, SCO Unix, bisa di-web-kan, AS/400 (kali2 aja ngetop lagi), atau lebih hebat sekalian disiapkan untuk jalan di Palm, atau bahkan jalan di iPod?? Think again!! Apakah bisa kita memprediksi masa depan, apakah bisa kita tahu bahwa tahun depan market menginginkan apa. ITU HANYA ILUSI.

Yang dimaksud antisipasi masa depan, adalah buat code seterang-terang-benderang-nya, se-standar-standar-nya, se-simple-simple-nya, tetapi UNTUK KEBUTUHAN MASA SEKARANG SAAT INI JUGA, supaya kalau nanti mau di-upgrade gampang. Bukan mengarang-ngarang fitur-fitur masa depan dalam masa sekarang. For God sake, kita adalah Software Developer, bukan ahli nujum. Jangan terjebak dalam ilusi tersebut.

Banyak yang bertanya apakah perbedaan antara Prosedural dan OOP. Pertanyaan ini SALAH BESAR. Prosedural dan OOP bukan perbedaan. Tetapi:

OOP melengkapi teknik Prosedural,
BUKAN BERBEDA.



3.1. Salah Kaprah yang Berbahaya

OOP melengkapi Prosedural. Dan Prosedural melengkapi teknik… yang well karena belum ada namanya, jadi kita sebut saja Flow Programming (FP). Salah satu ciri dari FP adalah code banyak dipenuhi dengan “Goto”. Perbedaan cara pandang antara yang memandang “OOP adalah sebuah teknik pemrograman yang berbeda dengan Prosedural” dan cara pandang bahwa “OOP melengkapi Prosedural” sangat vital, dan ini salah satu reason yang menghasilkan banyak code yang tidak berkualitas – hanya karena sekedar mau OOP “murni”.

Mengapa berpikir “melengkapi” dan berpikir “berbeda” bisa menimbulkan salah kaprah yang dahsyat?

1. Dengan anggapan berbeda, maka orang menganggap Prosedural lebih baik daripada FP. Jadilah “Goto” menjadi kambing hitam, dan semua orang beramai-ramai menghindari “Goto”. Padalah “Goto” sangat baik untuk error-handling (tentu sebelum ada syntax Try-Catch-Finally). Dan saya yakin masih ada kegunaan “Goto”, kita hanya perlu open-mind.

2. Dengan anggapan berbeda, maka orang menganggap cara berpikir OOP lebih baik dari Prosedural. Jadilah anggapan bahwa semua harus dibuat “Class”, “di-Inherit”, dan-lain-lain, sehingga code dipenuhi dengan class dan inheritance-nya yang sangat menggelikan. Menggelikan karena sudah pakai class dan inheritance yang sebanyak-banyaknya (di setiap jengkal code yang mungkin), tetapi code-nya tetap saja penuh bug dan susah dimengerti. Lukisannya tetap saja tidak indah dipandang.

3.2. Aplikasi Komputer

Sebelum kita lanjut diskusi dengan seru mengenai objet-oriented, tentu kita harus menyamakan dulu tujuan kita semua. Kalau kita tidak agree dengan tujuan akhirnya, diskusi ini bakal jadi debat kusir tanpa ujung.

3.2.1. Yang Pertama Jelas : User Membutuhkan Aplikasi Komputer

Yang pertama, apapun makanannya, tujuan akhirnya sudah jelas adalah membuat aplikasi yang berguna untuk user. Aplikasi yang berguna adalah aplikasi yang:

1. Biayanya bisa terjangkau oleh user.

2. Bug-nya tidak terlalu banyak, masih bisa diterima-lah (tidak ada aplikasi yg bug-free).

3. Berjalan sesuai dengan fungsi yang diinginkan oleh user.

4. Dan sangat banyak lagi.

Daftar ini bisa panjang sekali. Tetapi sudah pasti tidak ada satu-pun requirement dari user yang mengatakan saya mau program yang didesain secara object-oriented, mau programnya ditulis pake C# (atau VB.net), harus mengandung class dan inherintance, dan lain-lain yang seperti itu. Hanya orang teknikal (atau programmer alias kita) yang concern dengan itu. USER TIDAK PEDULI, buat mereka adalah aplikasi jalan, harganya masuk, dan dideliver tepat waktu.

3.2.2. Apakah itu Aplikasi Komputer

Ok, berarti ada kebutuhan aplikasi komputer. Aplikasi komputer itu apa? Yaitu merupakan rentetan instruksi yang harus dieksekusi oleh mesin. Dalam arti yang paling sederhana, setiap code kita akan dieksekusi oleh mesin step-by-step, persis seperti kalau kita membuat program di Bahasa BASIC yang ada line number-nya. Betul-betul seperti itu. Bagi yang mempelajari Bahasa Assembly, tentu mengerti bahwa processor itu pada dasarnya adalah INTERPRETER. Mereka baca instruksi dari code kita, mengeksekusinya, setelah itu loncat ke code mana (goto), evaluasi if-goto-else-goto-else2-goto2-dst.

Ini adalah arsitektur komputer yang sudah didesain kurang-lebih 100 tahun yang lalu oleh jenius matematika Von Newman. Apapun juga bahasa-mu, bagaimanapun desainnya, bagaimanapun trick-nya, ujung-ujungnya akan selalu menjadi instruksi yang harus dieksekusi oleh processor. Di hasil akhir sudah tidak ada lagi itu istilah bahasa OO, OOP, prosedural, dan lain sebagainya.

3.3. Selanjutnya : Ya Membuat Aplikasi Komputer Itu

Bahwa apapun juga caranya, tujuannya adalah bagaimana kita menghasilkan urutan-urutan instruksi komputer. Perkara mau pakai OOP atau prosedural, itu teknik, bukan tujuan akhir. Itu adalah sebuah teknik, yang disempurnakan dengan teknik berikutnya, dan seterusnya, dengan tujuan kita dapat menghasilkan instruksi untuk komputer, dengan usaha yang efisien dan dengan tingkat kesulitan yang masih dalam batas-batas manusia normal.

Klo di-summarize:

1. User butuh aplikasi komputer.

2. Aplikasi komputer = urutan instruksi.

3. Oleh karena itu kita membuat urutan instruksi (definitely bukan buat aplikasi komputer yang OOP).

Jadi seharusnya tujuan akhir desain dan bahasa komputer adalah membantu kita membuat urutan-urutan instruksi untuk komputer. Jelas desain dan bahasa bukan tujuan akhir, ini hanya cara. Cara ini yang berkembang sampai dengan sekarang menjadi OOP dan bahasa OO.

So mari kita mulai runut, bagaimana ceritanya sampai jadi aplikasi komputer. Dari sini diharapkan jelas, bahwa tidak ada teknik yang completely menggantikan teknik sebelumnya, tetapi merupakan kelanjutan, dengan tujuan “kita membuat aplikasi komputer, dengan cara yang semakin efisien dan efisien”.

3.3.1. Langkah Awal Membuat Aplikasi Komputer

Mari kita berimajinasi sedikit. Coba dibayangkan pada saat sebuah processor baru selesai dibuat. Bagaimana memberikan perintah ke processor. Tentu pertama kita menuliskan perintah ini. Untuk yang belum mengenal Bahasa Assembly, jangan bayangkan kita menulis print(“Hello World”), jauh banget. Kita menuliskan dalam kode-kode angka-angka, YAIK, angka-angka. Angka-angka ini tentu yang mempunyai arti bagi si processor. Misalnya kita mau menjumlah angka 5 + 8. Instruksinya kira seperti ini (sedikit background : register adalah memori internal dari processor):

1. 0105 (yang artinya taroh angka lima di register X).

2. 0208 (yang artinya taroh angka delapan di register Y).

3. 03 (yang artinya jumlahkan angka di register X dan register Y, hasilya taroh di register Z).

Nah angka-angka ini kita taroh di sebuah media, bisa RAM, klo jaman dulu di punch-card, pokoknya apapun itu yang bisa disambung ke processor, sehingga processor bisa membacanya. Instruksi-instruksi tersebut biasanya digabung kira-kira menjadi seperti “0105020803”, kita upload ke RAM / atau punch-card, sambung ke processor, trus jalankan processor tersebut (dengan memasang baterai / listrik, kemudian switch-on gitulah kira2).

Inilah teknik programming yang pertama. Perhatikan : kita membuat urutan instruksi.

3.3.2. Lahirnya Bahasa Assembly

Contoh di atas hanyalah ilustrasi singkat saja untuk menunjukkan betapa repotnya memberikan instruksi dalam bahasa mesin “murni”. Bayangkan betapa rumitnya perintah yang harus diberikan kalau kita mau memerintahkan ini sampai dengan tampil di layar. Apalagi klo mau tampil di GUI Windows / Mac / Linux. Bisa kebayangkan ini akan menjadi sebuah pekerjaan yang hampir impossible buat manusia normal (programmer juga manusia ya).

Memberikan perintah semacam “0105020803”, tentu bikin sakit kepala. Oleh karena itu diciptakanlah Bahasa Assembly. Mungkin ada yg berpikir : kenapa Bahasa Assembly, kenapa gak langsung aja ke salah satu bahasa tingkat tinggi? Bisa saja, tapi kebayang gak pusingnya bikin compiler, misalnya untuk yang bahasa yang relatif mudah dicompile seperti Bahasa BASIC deh, kalo kita mesti ngomong dengan bahasa dedemit seperti “0105020803………….”.

Ok klo kita mesti step by step, make sense dong. Kan kita buat Rain-man (orang yang klo ada kotak korek api penuh, terus korek apinya dijatuhkan semua ke tanah, sebelum semua korek api tersebut sampai ke tanah, dia sudah bisa hitung berapa jumlah korek api tersebut).

So jika kita punya Bahasa Assembly… maka programming kita bentuknya menjadi lebih human karena urutan instruksi bukan berupa angka-angka di atas, melainkan berubah menjadi tulisan yang bisa kita baca dengan lebih mudah seperti berikut:

1. MoveX, 5

2. MoveY, 8

3. SumXY

Ini lebih gampang, dan terutama bikin compiler-nya juga gampang. Semuanya hampir one-to-one dengan kode angkanya. Gak perlu ilmu parser yang rumit. Jauh lebih gampang. Karena compiler Assembly ini code utama-nya paling banter isinya kira-kira begini:

1. Baca text.

2. Jika text = “MoveX” then
>>a. Output “01”
>>b. Baca text
>>c. Output text tsb (yaitu 05)
>>d. Goto nomor 1

3. Jika text = “MoveY” then
>>a. Output “02”
>>b. Baca text.
>>c. Output text tsb (yaitu 0Cool
>>d. Goto nomor 1

4. Jika text = “SumXY” then
>>a. Output “03”
>>b. Goto nomor 1

5. Dan-seterusnya-seterusnya.

Compiler yang logikanya begini, tentu masih mungkin ditulis dengan kode-kode angka tadi. Bandingkan jika harus langsung membuat compiler Bahasa BASIC.

INILAH TEKNIK PROGRAMMING KEDUA. TUJUAN TETAP : MEMUDAHKAN KITA MEMBUAT URUTAN INSTRUKSI.

3.3.3. Lahirnya Bahasa Tingkat Tinggi

Nah untuk orang, klo mo memberikan perintah 5 + 8, walaupun sudah menggunakan Bahasa Assembly, harus beberapa instruksi, dan ditambah untuk mengerti itu mau apa masih perlu olah mental lagi, tentu bikin repot. Belum lagi komputer yang nyaman tentu perlu harddisk, keyboard, monitor, dll. Si processor bahkan tidak mengenal itu semua. Yang dikenal hanya IO-bus. Processor hanya membaca instruksi, mengkalkulasi, dan kemudian mengirimkan sinyal-sinyal listrik kode melalu IO-bus. Sinyal-sinyal ini yg diterima oleh monitor, keyboard, dan peripheral lain, kemudian ditampilkan di monitor, disimpan ke harddisk, atau dikirim ke network card.

Kebayang berapa panjang code-nya untuk melakukan itu semua.

Kita mau yang lebih simple.

So mengapa tidak kita ciptakan saja sebuah bahasa baru. Yang kalo mau menjumlahkan 5 + 8, cukup tulis “5 + 8”, kemudian hasilnya langsung tampil di layar. Inilah yang disebut sebagai bahasa tingkat tinggi, karena kita menulis code dalam simbol-simbol yang bisa kita baca dengan lebih mudah.

Jadi kita perlu interpreter / compiler bahasa tingkat tinggi yang kalo diberikan input “5+8”, bisa langsung mengubah itu menjadi : “0105020803…” dan hasilnya langsung tampil di layar. Ini lebih simple / lebih human. Dan akan saving waktu programming sangat jauh.

Setelah punya Bahasa Assembly, tentu pekerjaan membuat interpreter / compiler bahasa tingkat tinggi ini lebih mungkin (dibandingkan klo harus menulisnya dalam bentuk kode-kode angka). Karena energi yang tadinya kita pakai untuk mendisplay, atau sekedar menjumlah, karena hal-hal itu sulit, bisa kita gunakan untuk berkonsentrasi di algoritma dari parser.

NOTE beberapa tentu sudah kepikir… sebelum kita membuat compiler bahasa apapun itu, bisa jadi kita buat dulu Bahasa Assembly versi 2 yang lebih sophisticated (misalnya menambahkan fitur untuk menulis komentar program), menggunakan Bahasa Assembly versi 1 (yang kita buat dengan kode-kode angka), kemudian membuat Bahasa Assembly versi 3 menggunakan Bahasa Assembly versi 2, dan seterusnya, sampai dengan kita mempunyai sebuah versi Bahasa Assembly yang cukup sophisticated untuk membuat bahasa tingkat tinggi pertama kita.

Apapun bahasa itu, mestinya bahasa semacam Bahasa BASIC yang syntaxnya sangat sederhana – yang bahkan tidak mempunyai prosedur, hanya “Goto” yang gampang diparser, sehingga parsernya juga lebih sederhana – sehingga mungkin dibuat oleh manusia menggunakan Bahasa Assembly.

Saya tidak akan menjelaskan detil itu, karena sesimple-simple-nya bahasa tingkat tinggi sudah memerlukan ilmu parser yang mulai rumit dan di luar pokok bahasan artikel ini. Yg penting poinnya sama dengan tadi. Kira-kira misalnya setelah dibuat bahasa tingkat tinggi sederhana, kita buat bahasa tingkat tingkat tinggi versi 2 menggunakan versi 1, buat versi 3 menggunakan versi 2, dan seterusnya, dan sampailah ke Bahasa BASIC yang cukup sophisticated untuk membuat sesuatu yang lebih sophisticated.

Anw, inilah lahirnya teknik programming ketiga : programming menggunakan bahasa tingkat tinggi. TUJUAN TETAP TIDAK BERUBAH : MEMUDAHKAN KITA MEMBUAT URUTAN INSTRUKSI.

Jadi dinote tujuan membuat urutan instruksi tidak berubah. Hanya klo sebelumnya kita mesti nulis (diulang lagi untuk memudahkan perbandingan):

1. MoveX, 5

2. MoveY, 8

3. SumXY

4. Dan-seterusnya-seterusnya...

Sekarang cukup:

1. 5 + 8

Klo ditanya mengapa pakai bahasa tingkat tinggi? Ini jelas, karena daripada menulis puluhan, bahkan mungkin ratusan baris code, kita cukup menulis satu baris code. Jelas benefit yang luar biasa.

Kita agak jump sedikit. Klo pertanyaannya adalah : mengapa pakai OOP? Kemudian dijawab : misalnya ada class kucing yang diturunkan dari class mamalia, kemudian kalo dulunya kita mesti nulis “makan(kucing.parent)”, sekarang cukup “makan(mamalia)”. Kita hanya benefit ENAM karakter. Jelas meragukan. Padahal dengan OOP terbukti banyak program semakin canggih bisa ditulis karena menggunakan teknik OOP. Jadi bukan karena masalah syntax lagi. There must be something else. Ok lets go on.

3.3.4. Lahirnya Bahasa Prosedural

Dengan bahasa tingkat tinggi yang primitif seperti bahasa BASIC (yang duluuuuu banget), program mengandalkan instruksi semacam “goto” dan semuanya adalah global variable. Ini memusingkan, paling sedikit karena dua alasan utama:

1. Banyak kumpulan dari code yang bisa digunakan di banyak tempat, susah digunakan.

2. Semua variable adalah global variable.

Berikut adalah contoh yang menunjukkan masalah di atas. Misalnya kita mempunyai fungsi untuk menghitung faktorial sebagai berikut ( moga2 algoritmanya bener Smile ):

HitungFaktorial: //Parameter X = jumlah suku dari faktorial.
//Parameter R = kemana kita harus return.
//Return F = hasil dari faktorial.
F = 1;
For L = 1 To X
F = F * L;
Next L;
If R = “LanjutCalc” Goto LanjutCalc //Return ke pemanggil.
If R = “LanjutDisplay” Goto LanjutDisplay //Return ke pemanggil.
If R = “LanjutDadu” Goto LanjutDadu //Return ke pemanggil.
ExitMessage = “BUG : parameter kembali kemana tidak disebutkan.”
Goto Exit

Jadi si pemanggil untuk menggunakan ini, harus melakukan sbb:


X = 10; //Mau hitung nilai dari faktorial 10.
R = “LanjutCalc”; //Supaya kembali ke laptop.
Goto HitungFaktorial
LanjutCalc:


Ini jelas bermasalah. Masalah2nya adalah:
1. (masalah ringan) Waktu mau return dari fungsi repot sekali.

2. (BERAT) Begitu program berhenti dan keluarkan message “BUG : parameter kembali kemana tidak disebutkan.”, kita tidak punya ide code yang mana menyebabkan ini. Ini mulai mencari kutu, dan ini masalah berat karena bisa menghabiskan waktu sangat banyak.

3. (BERAT) Bagaimana jika pemanggil kebetulan menggunakan variable “F”, bisa pusing mencari sebab kenapa program tidak jalan (yang ternyata disebabkan variable “F” digunakan di salah satu pemanggil fungsi HitungFaktorial).

4. (BERAT) Label-label seperti “LanjutCalc” yang bersifat global memungkinkan sebuah code yang ntah dimana bisa nyasar ke sini. Dan ini juga dijamin nyarinya bakal nyari kutu.

Oleh karena itu diciptakanlah yang disebut “fungsi beneran” yang sifatnya kalau mau balik ke pemanggil, cukup tulis “return”. Dan diciptakanlah local variable. Sehingga menjamin variable “L” maupun “F” di dalam fungsi HitungFaktorial TIDAK MEMPUNYAI EFEK TERHADAP SIAPAPUN.

Jika ditulis ulang codenya menjadi seperti ini:

HitungFaktorial(Lokal X) //Parameter X = jumlah suku dari faktorial.
Local F = 1;
For Local L = 1 To X
F = F * L;
Next L;
Return F;

Mari kita analisis apa manfaat terbesarnya:

1. Syntax lebih sedikit, jelas benefit. Akan tetapi benefitnya kecil karena ini hanya menghemat ketikan. Apalagi klo si programmer adalah typist ulung (please yang belum bisa ngetik, belajar ngetik, ini jelas membantu banget). Total penghematan mungkin hanya beberapa menit per-panggilan. BETUL-BETUL HANYA SEMENIT-DUA MENIT. Yaitu klo tadinya setiap kita mau panggil fungsi HitungFaktorial, kita selalu harus tambahin sebuah baris code untuk return (misalnya : “If R = “MyFunction” Goto MyFunction”), sekarang sudah tidak perlu lagi.

2. Penghematan waktu karena sekarang sudah tidak bakal lagi ada kejadian si fungsi gagal untuk return SUDAH TIDAK ADA LAGI. Ini hematnya bisa berjam-jam, bisa berhari-hari. Karena coba dibayangkan klo pemanggil fungsi HitungFaktorial ada 100, pas ada error tersebut, mesti abis berapa jam? Berapa hari? Ini jauh dibandingkan penghematan beberapa menit karena alasan syntax di nomor satu.

3. Penghematan waktu karena sudah tidak ada lagi code yang kebetulan salah satu variable-nya dipakai oleh fungsi HitungFaktorial tersebut. Dengan alasan yang sama dengan nomor 2, ini hematnya bisa jam-jaman, bahkan hari-harian.

4. Penghematan waktu karena sudah tidak ada lagi code yang ntah dimana nyasar ke sebuah label yang ntah dimana juga. Dengan alasan yang sama dengan nomor 2, ini hematnya bisa jam-jaman, bahkan hari-harian.

Nah kalo cara pandang yang digunakan adalah menarik kesimpulan dengan cepat (tetapi salah), yang menjadi salah kaprah pada umumnya, keliatan serupa, TAPI TIDAK SAMA, yaitu:

1. Goto JELEK! Pokoke program sing ana “goto” JELEK.

2. Global variable JELEK! Pokoke program sing ana “global variable” JELEK.

Klo contohnya seperti di atas, “kebetulan” pandangan seperti ini ok-ok saja. Tapi sayangnya dunia programming membutuhkan seribu satu macam code selain daripada contoh di atas.

3.3.4.1. “Goto” Jelek?

Bagaimana kita solving problem error handling seperti ini. Ada sebuah fungsi yang mempunyai empat parameter, dan setiap parameter harus kita cek valid atau tidak, kalau tidak valid, harus mengembalikan sebuah error yang mengindikasikan parameter mana yang tidak valid. Kalau tanpa “Goto”:

HitungSomething(Local A, Local B, Local C, Local D)
If A = valid then
If B = valid then
If C = valid then
If D = valid then




Else
Return “Error-D”;
Endif
Else
Return “Error-C”;
Endif
Else
Return “Error-B”;
Endif
Else
Return “Error-A”;
Endif

Kemudian si pemanggil HitungSomething juga mesti lakukan ini juga:

Local X = HitungSomething(1, 2, 3, 4);
If X = “Error-A” or X = “Error-B” or X = “Error-C” or X = “Error-D” then
Return X;
Else
X = HitungSomethingElse(1, 2, 3);
If X = “Error-A” or X = “Error-B” or X = “Error-C” then
Return X;
Else




Endif
Endif

Coba kita coba dengan “Goto”:

HitungSomething(Local A, Local B, Local C, Local D)
If A <> valid then
E = “Error-A”;
Goto Error;
Endif
If B <> valid then
E = “Error-B”;
Goto Error;
Endif
If C <> valid then
E = “Error-C”;
Goto Error;
Endif
If D <> valid then
E = “Error-D”;
Goto Error;
Endif





Dan code si pemanggil HitungSomething juga cukup juga menjadi:

HitungSomething(1, 2, 3, 4);
HitungSomethingElse(1, 2, 3);





Code menjadi lebih singkat. Dan yang terutama alur utama program lebih jelas terbaca.
Kalau kita berpikiran “Goto” jelek, tentu kita tidak akan pernah menggunakan “Goto”. Tetapi kalau kita mengerti dengan baik alasan kenapa “Goto” jelek, kita bisa menghindari penggunaan “Goto” yang jelek, dan menggunakannya di area dimana “Goto” berfungsi dengan lebih baik. Jadi yang bermasalah bukanlah “Goto”-nya, karena ini-kan hanya sekedar fitur, salah satu senjata dari gudang senjata kita, tergantung kita sendiri bagaimana memanfaatkannya.

Dan oleh karena itu, kalau diperhatikan, sebenarnya fitur-fitur seperti Try-Catch-Finally, bisa return dari mana saja, exit di tengah-tengah loop, suddenly balik ke awal loop, adalah salah satu bentuk “Goto”. Saya menyebutnya sebagai “Goto”-TERARAH. Terarah karena potensi penggunaan “Goto” yang buruk dicegah.

Bahkan di dunia bahasa OO masa kinipun, “Goto” murni masih bisa berguna. Kalau suatu hari Anda menemukan code yang terlalu banyak indentasi ke kanan, mau diapapun juga, tetap indentasi ke kanan juga, coba think solusi menggunakan “Goto”.

3.3.4.2. “Global Variable” Jelek?

Coba bayangkan kalau kita mempunyai aplikasi yang mempunyai katakanlah 10 variable yang sifatnya system-wide. Misalnya : koordinat kiri atas dari window aplikasi, lebar, tinggi, warna button, warna textbox yang error, warna textbox yang mandatory, dan-lain-lain. Bayangkan kalau kita hanya berpikiran global variable jelek. Kita akan menghindari penggunaan global variable. Dan sebagai gantinya, setiap kali kita mau memanggil fungsi yang membutuhkan variable-variable tersebut, kita harus selalu mempassing ke-10 variable tersebut sebagai parameter. Bagaimana jika variable yang system-wide tersebut bertambah menjadi 20. Haruskan kita mengedit setiap fungsi satu-satu? Bukankah ini membuah code menjadi semakin ruwet? Dan tujuan kita menggunakan bahasa prosedural-kan supaya kita bisa menulis instruksi dengan lebih efisien dan hemat tenaga. Bukankah dengan menghindari global variable seperti ini malah semakin membuang energi dan waktu kita?

Global variable yang jelek adalah karena yang menggunakannya tidak mengerti cara menggunakannya. Global variable sendiri hanyalah fitur, bermanfaat atau malah merusak, tergantung dari yang menggunakannya.

3.3.4.3. Sedikit Kesimpulan sebelum Membahas OOP

Dengan semakin canggihnya bahasa OO, mungkin contoh-contoh di atas terlihat primitif sekali. Poinnya bukan di situ. Justru sengaja dengan pembahasan bahasa prosedural dibandingkan bahasa non-prosedural, yang lebih simple, diharapkan bisa lebih terlihat bahwa “mengapa” sebuah fitur bahasa diciptakan. Dengan mengerti “mengapa”-nya ini, dan bukan keyakinan close-minded seperti “ini dilarang”, “itu jelek”, “itu menyalahi aturan prosedural”, menjamin kita bisa berkreasi dengan lebih baik dan tidak terjebak dengan keyakinan-keyakinan tidak berdasar yang malah membuat code menjadi lebih rumit.

Jika contoh yang sederhana seperti di atas bisa dipahami, barulah kita siap membahas OOP yang lebih kompleks. Akan tetapi konsepnya tetap sama : memudahkan kita menghasilkan urutan instruksi.

3.4. Lahirnya OOP dan Bahasa OO

OOP dan bahasa OO kaya dengan berbagai macam fitur yang sangat baik untuk programming. Membahas itu semua di luar dari konteks artikel ini. Jadi kita akan membahas satu saja yang paling popular yaitu fitur : class dan inheritance-nya. Kita akan bahas dari “mengapa”-nya. Diharapkan dengan demikian, selanjutnya tentu kita bisa menarik kesimpulan sendiri apa gunanya dari fitur-fitur yang lain.

Untuk memahami contoh berikut, sebaiknya dibuang dulu pemikiran mistik, bahwa kita harus mengganti pola pikir flow / step-by-step menjadi pola pikir class dan inherintance. Jangan percaya omong kosong ini. Mengapa? Tujuan kita tidak berubah dari jamannya Von Newman 100 tahun lalu, yaitu : membuat instruksi step-by-step untuk komputer. Jadi yang betul adalah kita harus tetap berangkat dari pola pikir flow / step-by-step ini, kemudian kita lihat dimana class bisa membantu kita menulis instruksi dengan lebih efisien. Baru setelah itu lama-lama kita akan terbiasa sehingga class menjadi daya reflex kita. Seperti halnya membuat fungsi, menulis variable, looping, array, dan seribu satu macam trick-trick programming menjadi daya reflex kita. TETAPI BUKAN LONCAT, UBAH POLA PIKIR MENJADI CLASS. Dengan cara begitu, sampai matipun saya yakin tidak akan pernah memahami ensensi dari class. Ini seperti halnya mengatakan : ubah pola pikirmu menjadi ikan, terus diterjunin ke laut.

3.4.1. Diciptakanlah Class

Somehow class itu lahir dari pemikiran bahwa global variable itu perlu. Ironisnya di dunia OOP, fitur global variable malah semakin dipandang sebagai dosa yang lebih berdosa lagi Smile

Dari contoh di atas, kita lihat bahwa global variable tetap perlu untuk variable yang sifatnya system-wide. Akan tetapi bagaimana kalau kita membutuhkan variable yang sifatnya tidak terlalu global sampai dengan system wide, tapi juga bukan local variable yang dibutuhkan hanya oleh satu fungsi, melainkan variable-variable ini dibutuhkan oleh sekumpulan fungsi. UNTUK MEMENUHI KEINGINAN INI, DICIPTAKANLAH CLASS.



Misalnya klo di aplikasi kita mempunyai sebuah window dimana hasil dari setiap output kita harus ditampilkan di dalam window tersebut.

3.4.1.1. Si Local Ternyata Adalah Global Berbulu Domba

Tanpa class, kita hanya punya dua pilihan, menggunakan local variable atau menggunakan global variable.

Klo semua variable dijadikan local variable, maka misalnya window tersebut mempunyai atribut xLoc, yLoc, Panjang, Lebar. Setiap kali kita mau menulis “Hello World!”, syntaxnya menjadi kira-kira : print(xLoc, yLoc, Panjang, Lebar, “Hello World!”).

Kerepotan pertama sudah dijelaskan di atas, bagaimana klo si window tersebut mempunyai property baru, berarti semua fungsi di aplikasi kita yang memanggil window tersebut harus diubah.

Dan ada satu lagi yang bahaya yaitu : perhatikan bahwa variable xLoc dan kawan-kawannya harus dimaintain oleh pemanggil, pemanggilnya pemanggil, pemanggilnya pemanggilnya pemanggil, dan seterusnya. Sepertinya bukan global variable, tapi efeknya sama seperti global variable. Misalnya di salah satu pemanggil-pemanggil tersebut salah menimpa value salah satu dari xLoc dkk. Efeknya akan terasa oleh yang dipanggil oleh si salah, yang dipanggil oleh yang dipanggil oleh si salah, dan seterusnya. Bukankah ini efek yang mirip dengan variable global, dan dengan bonus : repot ngetik, repot copy-paste klo atributnya bertambah. Inilah Global berbulu Domba (Local).

3.4.1.2. Solusi : Class

Jadi solusi yang tinggal adalah menggunakan global variable. Kalau window tersebut adalah satu-satunya code dari aplikasi kita yang memerlukan variable global, fine, tetapi bagaimana jika kita juga punya mouse. Berarti atribut dari mouse harus dibuat global juga. Nah ini mulai bahaya, karena code si window bisa salah mengakses variable globalnya si mouse, dan sebaliknya. Ini bahaya karena mencari kesalahan seperti ini, bisa seperti mencari kutu, bisa berjam-jam, dan berhari-hari.

Dengan diciptakan class. Masalah ini solve. Window kita jadikan class yang artinya semua variable window tetap global tetapi hanya untuk semua fungsi yang berada di class window tersebut. Dan semua variable mouse tetap global, tetapi hanya untuk semua fungsi yang berada di class mouse tersebut.

Perhatikan pola pikirnya adalah bukan berangkat dari class. Tetapi dari masalah coding kita. Jadi kita mengerti “mengapa” kita memakai class, dan tentu saja akan mengerti “mengapa” kita tidak harus selalu pakai class.

3.4.2. Diciptakanlah Object

Kalau window hanya satu, dengan class yang hanya mempunyai fitur untuk membuat variable 1/2 global dan 1/2 local, problem solved. Tetapi gimana kalau aplikasi kita mempunyai lebih dari satu window. Apakah kita harus copy-paste class window kita dan diganti nama jadi class window_juga, yang hanya beda nama class, isinya totally sama persis. Bagaimana klo ternyata class window ada bug? Harus kita betulkan, kemudian kita copy-paste ke semua class window_juga, window_juga_lho, window_lage_lage, window_asli, dan klo ada 100 window gimana? Apa gak gompyor?

Oleh karena itulah diciptakan fitur object. Jadi daripada copy-paste, kita cukup bikin satu class window. Kemudian class window ini istilahnya harus di-instantiate sebelum digunakan. Untuk instantiate kita cukup gunakan syntax “window wnd = new window()”. Selanjutnya kita mengakses fungsi print di window dengan syntax “wnd.print(“Hello World!”). Klo butuh satu window lagi kita tinggal pake syntax “window wnd_juga = new window()”. Dan seterusnya. Sehingga klo class window ada bug, cukup dibetulkan, tanpa perlu copy-paste, semuanya 100 window, bahkan klo ada ribuan window, juga langsung beres.

Inilah object.

Lagi, perhatikan pola pikir yang berangkat dari masalah coding, dan fitur object adalah solusinya. Bukan sebaliknya.

3.4.3. Diciptakanlah Implementation Inheritance

Ada banyak macam inherintance : untuk artikel ini kita bahas yang implementation inheritance saja.

Kalau window kita mau bisa ditampilkan di graphic card Asus dan graphic card NVIDIA, apakah kita harus membuat dua class window untuk masing-masing graphic card? Bisa saja, tetapi terlalu banyak code yang diduplikasi. Klo ada bug, apakah kita harus betulkan di satu class, kemudian copy-paste ke class yang lain? Dan copy-paste ini sedikit lebih rumit karena ada bagian-bagian code yang memang berbeda, yang tentu saja tidak boleh ke-paste.

Okay klo begitu akan baik klo code yang spesifik Asus dan spesifik NVIDIA dipisahkan. Dengan alasan yang seperti di atas, mau pakai 1/2 global dan 1/2 local, dibuatlah class Asus dan NVIDIA. Tapi eit nanti dulu, klo hanya seperti ini, tetap aja itu adalah dua class yang berbeda, yang akhirnya kita juga akan punya dua class window untuk masing-masing class Asus dan NVIDIA.

Dari sinilah diciptakan implementation inheritance. Kita buat class kosong graphic card. Kosong itu maksudnya kita cukup menyebutkan nama-nama fungsi. Nama-nama fungsi ini yang nanti di-refer / di-call oleh class window kita. Sehingga kita tetap punya satu class window. Jadi tidak perlu lagi copy-paste yang repot. Kemudian kita buat class Asus, yang istilahnya diturunkan dari class graphic card. Bahasanya “seram”, “baru”, “cool”, “modern”, tetapi artinya gampang sekali, kita mengisi isi dari fungsi-fungsi yang kosong tersebut. Jadi class window tetap satu saja. Punya satu class kosong untuk keperluan coding di class window. Kemudian dua class Asus dan NVIDIA yang memang dua graphic card yang berbeda sehingga wajar mempunya dua class (dua code = nambah kerjaan). Inilah yang dimaksud dengan callback-reusable. Code yang manggil hanya satu (window), code yang dipanggilnya yang bisa banyak (Asus dan NVIDIA).

Perhatikan pola pikirnya : dari problem coding, diberi solusi implementation inheritance, kemudian dijulikin “re-usable”. Dengan demikian baru kita bisa mengerti “mengapa” kita menggunakan inheritance. Dan “mengapa” kita tidak perlu inherintance. Jangan mau disuruh mikir seperti ikan terus diceburin ke laut.

3.5. Apakah OOP dan Prosedural Berbeda

Jelas tidak. OOP melengkapi teknik programming prosedural, sebagai lanjutan dari penyempurnaan teknik programming, mulai dari jamannya Von Newman 100 tahun yang lalu. Tidak ada yang mistis mengenai itu. Semuanya berangkat dari pemikiran yang sederhana, yang saya yakin masih dalam batas-batas kemampuan manusia normal. Hanya memerlukan pola pikir yang tepat.

Dan itu hanya satu macam dari sekian ratus teknik programming yang ada. Perkara itu memang popular karena solving lebih banyak kasus dibandingkan teknik yang lain, ok saja. Tetapi jangan terjebak ke pola pikir “ooo, semuanya harus object”. Programming adalah dunia yang sangat kreatif. Hanya dengan open mind, kita bahkan mungkin menciptakan sebuah metodologi programming sebagai penyempurnaan dari OOP. Seperti halnya OOP menyempurnakan prosedural. Make the tool works for you. Do not work for tool.

Jangan pernah takut bertemu dengan what-so-called pakar object oriented, pakar design pattern, blah, blah. Tanyakan saja bagaimana bentuk code akhirnya, klo sama-sama saja, klo jawabnya ah-eh-ah-eh, forget it. Ingat tujuan kita adalah menulis instruksi dengan lebih efisien, yang klo perlu sambil tidur dah. Teori boleh segunung, tetapi klo code-nya sama saja, gimana bisa lebih efisien? Bahkan itu menunjukkan dia sama sekali tidak pernah memahami esensi yang paling basic dari “mengapa” kita coding. Boleh dipastikan itu adalah pakar omong-kosong.

Happy programming!

5 comments:

Anonim mengatakan...

Keren, hebat2x...
Tq 4 the article yah Mas/Mbak

Queue mengatakan...

Great Article..

That's a new understanding of OOP.

Ijin sharing yah mas..

Tri Budi Nurwanto mengatakan...

Artikel hebat.. :)

banua delau mengatakan...

Truly open-minded concept

harga jaket kulit domba mengatakan...

keren banget, langsung mak jleb!

Posting Komentar