Setiap programmer pasti memiliki gayanya masing-masing dalam menulis program. Perbedaan gaya dalam menulis program (baca: programming style) ini bukanlah sesuatu yang salah tentu saja. Namun demikian, suatu programming style akan menjadi sesuatu yang bermasalah jika tidak mengikuti kaidah pemrograman yang baik dan benar.
Pradigma dalam menulis program sekarang sudah berubah. Suatu code program dikatakan bagus jika code program itu makin mudah dibaca (readable). Kalau kita telaah lebih jauh, ternyata 80% atau bahkan mungkin 90% dari siklus hidup sebuah software atau yang dikenal dengan Software Development Life Cycle dihabiskan untuk maintanance. Itulah sebabnya hasil dari proses software development harus mudah untuk dipelihara (maintainable). Dan syarat mutlak sebuah software maintainable tentu saja jika source code yang membangun software tersebut readable atau mudah dibaca. Semakin readable source code suatu program, jelas makin mudah source code tersebut dipahami sehingga makin mudah pula diperbaiki jika dikemudian hari ditemukan bug.
Untuk lebih jelasnya coba perhatikan contoh dalam C++ berikut.
1 2 3 4 5 6 | float util1(float a,float b) { float d=0.5; float c=d*a*b; return c; } |
Bandingkan dengan:
1 2 3 4 5 6 | float LuasSegitiga(float aAlas, float aTinggi) { float constant = 0.5; float luas = constant*aAlas*aTinggi; return luas; } |
Contoh yang kedua jelas lebih readable karena menggunakan spasi sebelum dan sesudah operator “=”, serta memberi nama semua variable dan fungsi dengan nama yang sangat jelas. Dengan memberi nama pad setiap variable, fungsi, atau identifier lain dengan jelas akan sangat memudahkan orang untuk memahami maksud dari code tersebut. Seperti pada contoh kedua, sangat jelas maksudnya bahwa util1 adalah fungsi untuk mencari luas sebuah segitiga.
Perhatikan lagi contoh kodisional if berikut ini:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | typedef unsigned int UINT; bool IsValidDateInput(UINT aHari, UINT aBulan) { if (aHari == 2) { return true; } else if (aBulan == 12) { return true; } else { return false; } } |
Bandingkan style penulisan kondisional if di atas dengan contoh berikut:
1 2 3 4 5 6 7 8 9 | #define SELASA 2 #define DESEMBER 12 typedef unsigned int UINT; bool IsValidDateInput(UINT aHari, UINT aBulan) { return (aHari == SELASA || aBulan == DESEMBER); } |
Kedua method di atas sebenarnya mempunyai maksud yang sama, yaitu memeriksa masukan aHari dan aBulan, kemudian mengembalikan nilai true jika masukan aHari adalah integer 2 atau aBulan adalah integer 12. Kembalian method akan false jika masukan yang diberikan selain kedua nilai integer tersebut. Walaupun mempunyai maksud yang sama, contoh kedua tampak lebih elegan, lebih ringkas, dan lebih mudah untuk dipahami. Contoh kedua juga telah mendefinisikan semua magic number menjadi SELASA dan DESEMBER.
Sekarang perhatikan contoh berikut. Contoh code berikut sangat sering dilakukan oleh kebanyakan programmer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include <vector> #include <string> #include <iostream> typedef unsigned int UINT; int main() { std::vector<int> items; for (UINT i = 0; i < 10; i++) { items.push_back(i); } int status = 0; for (UINT ii = 0; ii < items.size(); ii++) { if (items.at(ii) == 11) { status = 1; break; } } if (!status) { return -1; } for (UINT iii = 0; iii < items.size(); iii++) { std::cout << iii << " "; } return 0; } |
Bandingkan dengan code berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include <vector> #include <string> #include <iostream> typedef unsigned int UINT; typedef std::vector<UINT> VECTOR; void AddItems(VECTOR *aItems, UINT aItemNumber) { for (UINT i = 0; i < aItemNumber; i++) { aItems->push_back(i); } } bool IsItemFound(UINT aId, VECTOR *aItems) { for (UINT i = 0; i < aItems->size(); i++) { if (aItems->at(i) == aId) { return true; } } return false; } void DisplayAllItems(VECTOR *aItems) { for (UINT i = 0; i < aItems->size(); i++) { std::cout << aItems->at(i) << " "; } } int main() { const UINT ITEM_NUMBER = 10; const UINT NUMBER_TO_BE_FOUND = 9; VECTOR items; AddItems(&items, ITEM_NUMBER); if (IsItemFound(NUMBER_TO_BE_FOUND, &items)) { DisplayAllItems(&items); } return 0; } |
Kedua contoh terakhir di atas sebenarnya memproses hal yang sama. Sama-sama terdiri dari tiga buah proses berbeda, yaitu proses inisiasi container (vector) dan penambahan data ke dalam container, proses pencarian data terhadap data yang ada di dalam container, dan yang terakhir adalah proses penampilan semua entry yang ada pada container.
Meski memiliki tujuan yang sama, contoh pertama dan ke-dua memiliki perbedaan dalam gaya pemrogramannya. Jika contoh pertama menumpahkan code ketiga proses yang telah disebutkan tadi ke dalam main(), contoh ke-dua justru memisah secara fisik ketiga proses tersebut menjadi tiga buah method yang berbeda. Ketiga method tersebut adalah AddItems yang berisi rutin penambahan data ke dalam container, IsItemFound adalah method yang merupakan rutin untuk menangani proses pencarian data yang ada di dalam container, dan yang terakhir adalah DisplayAllItems yang merupakan rutin untuk menampilkan semua entry yang ada di dalam container.
Setelah membandingkan keduanya, semua tentu sepakat jika contoh ke-dua jauh lebih mudah dipahami maksudnya dari pada contoh pertama. Namun demikian, tetap ada cost yang harus dibayar. Ternyata processing time yang diperlukan microprocessor untuk mengekseskusi code pada contoh ke dua sedikit lebih lama dibanding contoh pertama. Dengan kata lain, proses eksekusi contoh ke-dua lebih lambat dibandingkan dengan contoh pertama. Sebabnya adalah karena code kedua menambahkan sedikitnya tiga buah perintah JUMP pada code assembly untuk ketiga method yang telah disebutkan tadi. Namun demikian, perbedaan kecepatan proses eksekusi di antara keduanya sama sekali tidak akan terasa atau kasat mata, kecuali jika dilakukan benchmark terhadap keduanya. Lagi pula, di jaman microprocessor Core 2 Duo sekarang ini, hal seperti itu bukanlah sesuatu yang penting untuk dipikirkan. Jauh lebih baik mengalokasi tenaga dan pikiran untuk menjadikan program yang dibuat readable sehingga mudah untuk di-maintain kelak. ***

Sunday, 7. December 2008
jadi… lagi uring2an dapet warisan sorcod ga kebaca? hekekeke
Sunday, 7. December 2008
Eh, lagi bagi warisan?
Friday, 12. December 2008
setuju, refactoring itu wajib! hehehehe
Friday, 12. December 2008
Egh ada yogi. Selamat datang ..
Tuesday, 17. February 2009
mas2, ngapain ngurus source code kayak gitu gila semua ya??