Thursday, March 26, 2009

Software engineering

Jika pelukis membuat lukisan, penulis membuat buku, maka kami, para software engineer, writes code. Kami menulis code dalam bahasa pemrograman, sehingga muncullah software di dalam komputer yang dapat membantu manusia dalam menghadapi aktivitasnya sehari2.

Suatu fakta yg signifikan, bahwa bidang ini termasuk muda dibandingkan yg lain seperti chemical engineering atau electrical engineering. Saya dulu mengira bahwa perkembangan ilmu di bidang IT atau software, dapat dengan cepat menyebar di seluruh dunia, karena pada umumnya para pelajar IT atau pekerja IT lebih sering menggunakan Internet daripada orang lain. Sehingga, begitu ada breakthrough di teknik object oriented, saya mengira bahwa dalam waktu satu dekade (10 tahun) hampir semua pekerja IT sudah mengerti teknik object oriented tersebut. Teknik yang saya maksud ialah Design Patterns, yang dipublikasikan sekitar 1995 oleh Erich Gamma (sekarang ia bekerja sebagai engineer di IBM). Ternyata, sampai sekarang pun, mayoritas pekerja IT Indonesia belum paham. Mungkin teknik ini terlalu rumit untuk diterapkan secara praktikal, atau mungkin bahwa dunia IT Indonesia tidak terlalu memerlukan object-orientation..

Dan ini membawa kita ke topik yang menarik, apakah yg diperlukan bagi seorang software engineer di Indonesia? Akan saya coba brainstorming dari aktivitas sehari-hari seorang software engineer (thats me :). Sebuah hal yang cukup sering dilakukan, adalah membangun sebuah aplikasi web-based, untuk memenuhi kebutuhan pencatatan manusia, dan memberikan logika (business logic) sehingga aktivitas (transaksi) sehari-hari lebih teratur dan menaati prinsip-prinsip tertentu. Dan umumnya, setelah dicatat, ada pihak yang tertarik untuk dibuatkan laporan secara otomatis oleh komputer, sesuai dengan keperluannya saat itu.

Secara teknis, pilihan kami ialah mengcoding aplikasi menggunakan bahasa pemrograman seperti PHP, Java, atau .NET. Akan tetapi, karena targetnya web-based application, kami dituntut juga untuk mengetahui HTML, bahasa yang digunakan untuk 'menggambar' layar-layar user interface yang akan dihadapi user. Untuk mempercantik tampilan, pasangan HTML adalah CSS. Kita lihat bahwa aplikasi web-based memberikan tantangan yang 'lebih' misalnya karena memberikan kita kesempatan untuk mempelajari dan menguasai 3 buah bahasa sekaligus (satu bahasa Core Logic, satu bahasa markup, satu bahasa styling)
Kemudian, karena keperluan manusia yang dibantu komputer umumnya adalah pencatatan, maka tentunya para engineer mempraktekkan best-practice beberapa dekade terakhir yaitu penyimpanan data di relational database management system. Kita lihat, bahwa kecenderungan terakhir ini memberikan kesempatan para engineer untuk memahami dan menguasai bahasa keempat, yaitu SQL (structured query language).
SQL sederhana merupakan masalah sepele, tapi sebuah SQL kompleks yang terdiri dari 4 inner query, belasan kolom, dan belasan kondisi WHERE merupakan ujian kemampuan visualisasi abstrak bagi developer, dan merupakan mimpi buruk para software engineer. Beberapa pihak mendiskreditkan RDBMS dan mendorong manusia ke arah lebih civilised seperti object oriented database (atau object oriented persistence system), tetapi saya melihat bahwa kompleksitas SQL muncul karena source code yang sulit diubah dan bukan karena kelemahan konsep RDBMS.

Sebuah software yang dihasilkan proses engineering, di Indonesia, pada umumnya sulit diubah karena banyak faktor:
1. terlalu banyak duplikasi, akibatnya ketika ingin mengubah satu hal, misalnya nama kolom di suatu tabel, kita harus mengubah di banyak tempat di source code (belasan atau puluhan tempat, jika softwarenya cukup besar)
2. terlalu rumit, sehingga untuk mengubah satu hal, membutuhkan seminggu bagi developer untuk memahami kodenya (sebelum merubah apapun)
3. source code tidak terstruktur, menyulitkan manajemen source code, misalnya untuk mencari source code yang menangani suatu hal tertentu. Asumsi untuk faktor ini ialah kita melakukan maintenance software, tanpa developer yang membuat aplikasi pertama kali.

Sebuah breakthrough lain, yang cukup signifikan dalam dekade terakhir, ialah Ruby On Rails. Sebenarnya ini merupakan sebuah 'library' dalam bahasa pemrograman Ruby. Yang membuat signifikan, ialah pembuatnya mengklaim 10x perubahan produktivitas ketika melakukan pembuatan aplikasi menggunakan Rails. Rails bukan hanya library, tetapi merupakan framework, yang 'memaksakan' struktur tertentu pada source yang dibuat. FORTRAN juga memaksakan struktur tertentu, tapi hanya bersifat sintaksis, berbeda dengan Rails yang memaksa kita bekerja dengan konsep Model-View-Controller. MVC merupakan sebuah Architectural Design Pattern yang membuat engineer memisahkan source code menjadi tiga kelompok besar, Model, yang memuat business logic, View, yang memuat logika penampilan, dan Controller, yang memuat logika penerimaan input dari user (button ditekan, form disubmit). Bagi saya, pemisahan MVC cuma masalah strukturisasi. Ada pula orang yang berpendapat, seharusnya kita tidak perlu mengcode V atau C, karena kedua layer ini dapat dibuat generik (lihat: Naked Objects Framework). Menurut saya, yang terpenting adalah di M-yaitu sang Domain Model. Business logic disimpan di sini, dan Rails mengadopsi konsep Active Record - yaitu mencampur business logic dengan logika persistensi (yang melakukan query ke database untuk menyimpan dan mengambil data). Bagi pembuat Hibernate, sebuah persistence framework berbasis Java, sangat penting untuk memisahkan business logic dan layanan persistensi - jadi kita lihat ada dua konsep berbeda yang berkembang belakangan ini. Saya berprinsip, tidak penting disatukan atau dipisah (seperti halnya MVC) tapi yang terpenting, seberapa mudah saya dapat melakukan perubahan pada Domain Model? Seberapa mudah saya menambahkan satu field? Seberapa sulit saya memindahkan satu property (field) dari satu model (atau entitas, atau tabel di RDBMS) ke model lainnya?
Menurut saya, ini adalah hal yang cukup penting. Saat ini, karena sulit untuk mengubah 'model' (atau desain, atau ERD), maka developer stuck pada model yang tidak sesuai dengan kebutuhan sebenarnya. Karena SQL, merupakan bahasa yang sangat powerful, maka aplikasi tetap dapat berfungsi dengan model data yang rancu, namun di sana-sini akan muncul banyak SQL rumit yang menyulitkan perubahan aplikasi. Padahal, perkembangan (development) itu intinya proses perubahan dari aplikasi yang belum jadi menjadi aplikasi yang siap pakai..

Solusi terhadap masalah kita, sayangnya, menuntut kita berpikir mengabaikan prinsip maupun cara lama. Masalah saat ini tidak akan dapat diselesaikan dengan cara berpikir yang menyebabkan terjadinya masalah tersebut. Beberapa ide pemikir IT dekade terakhir antara lain :
1. memindahkan business logic sepenuhnya ke aplikasi, mengurangi beban kompleksitas pada SQL, stored function, stored procedures, ataupun database triggers. Padahal, ada pekerja IT yg saat ini berprinsip untuk memaksimalkan penempatan business logic di dalam database..
2. desain, menjadi hal yang tidak tabu untuk dirubah.. kesederhanaan yang terjadi ketika desain berubah menjadi lebih match dengan kondisi riil lapangan, bernilai sangat tinggi - performansi aplikasi meningkat, aplikasi lebih mudah dituning, source code mudah dibaca, penambahan fungsi mudah dilakukan, dan lain-lain, semua ini worthwhile untuk ditukar dengan usaha untuk merombak source code sebagai akibat perubahan desain
3. atau even better, buatlah sehingga merubah desain, semudah mungkin.. menggunakan framework manapun, sehingga hal ini dapat tercapai. Hibernate Persistence Framework menjanjikan para engineer mengkode SQL dengan volume jauh lebih sedikit daripada cara manual, begitu pula Ruby On Rails, CakePHP, CodeIgniter.. Prevayler Persistence Framework, di sisi lain, menjanjikan bahwa para engineer tidak perlu menulis satu barispun SQL (death to the database, they said)

Kita lihat, ternyata breakthrough 'design patterns' tidaklah useless at all, karena semua framework yang dibuat sekarang, dibangun atas design pattern-design pattern.

Saya belum menyinggung istilah refactoring di paragraf-paragraf di atas. Idenya ialah, kita harus bisa mengubah desain pada sebuah running application, sehingga kualitasnya meningkat, tanpa mengorbankan fungsionalitas aplikasi. Jadi mirip dengan tone yang saya gunakan pada paragraf-paragraf di atas. Sebenarnya, mengukur kualitas software dari banyaknya duplikasi, kompleksitas source code, adalah dua dari banyak metoda yg digunakan untuk mengukur kapan kita harus melakukan refactoring. Bau di code, atau Code smells, begitu istilah Kent Beck & Martin Fowler, yang mereka jadikan patokan perlunya melakukan refactoring atau tidak. Sebenarnya saya belum menerapkan satu safety net di sini - yaitu automated test. Menurut penulis buku Refactoring, automated test membuat refactoring tidak berakibat buruk bagi fungsionalitas aplikasi. Which is, unfortunately, is the very issue I am facing - tiap refactoring yang saya lakukan di aplikasi saya, membuat munculnya bug-bug yang menghantui user sampai saya perbaiki..

Ok, now, menutup satu topik yang sudah saya buka, bahwa dalam menulis web based application kita harus memahami minimal 4 bahasa komputer.. Alternatifnya, kita belajar menggunakan GWT (which is, mulai populer setelah beberapa tahun hidup..) GWT membuat kita cuma coding dalam satu bahasa: Java. Ia melakukan konversi dari Java ke Javascript pada saat deployment aplikasi. Sayangnya, kita tetap harus memahami HTML dan CSS, meskipun ada abstraksi HTML yang disertakan oleh GWT sebagai kelas-kelas Java. Setidaknya satu bahasa untuk dipelajari menjadi berkurang :). I wonder, jika Prevayler tetap dikembangkan, dan dapat digunakan bersama GWT.. berarti kita bebas dari SQL& Javascript - its a totally killer concept :). Cuma tampaknya, web-based application memang akan lebih tidak menyenangkan dari pada client-server application, yang mana kita sama sekali tidak perlu tahu HTML & CSS, dan tidak perlu tahu perbedaan browser IE dan Firefox :).

Manusia punya batas, dan mengurangi unnecessary complexity membuat kita dapat memikirkan konsep aplikasi yang lebih useful (dan tentunya.. sedikit lebih rumit)

Monday, March 2, 2009

Inconsistent Access Control in Liferay Social Office

Beberapa hari ini cukup dipusingkan dengan Access Control di Liferay Social Office. Untuk sebuah folder di bawah Document Library, apapun Permissions yang kita set, selalu saja semua user dapat melakukan 'Add Document' atau 'Add Folder'. Kecuali kalau 'view' permission tidak kita berikan ke user, maka user tersebut tidak dapat membuka folder tersebut, apalagi Add Document atau Add Folder. Saya belum cek kalau user mengetikkan URL add document langsung (tanpa view isi foldernya lebih dahulu) tetap bisa dilakukan Add Document atau tidak. Anyway, ternyata masalahnya ada di propagasi permission dari parent folder ke subfoldernya. Semua permission yang dimiliki current user pada sebuah folder akan dipropagasikan ke subfolder di bawahnya. Perilaku Aplikasi menjadi cacat karena Community Member memiliki permission Add Document dan Add Folder pada root folder di komunitas tersebut, sementara tidak ada UI untuk merubah permission pada root folder. Hanya Permission pada folder-folder lain yang dapat diubah, lewat menu 'Action:Permissions' yang tersedia saat kita menampilkan folder tersebut sebagai isi dari folder lain.
Solusi saat ini ialah menambahkan UI untuk mengubah permissions pada current folder yang sedang ditampilkan, sehingga pada saat menampilkan root folder, administrator dapat mengubah permissions pada root folder.
Perubahan pada webapps\ROOT\html\portlet\document_library\view.jsp atau view.portal.jsp :

(baris: 274)
boolean showCurDocumentSearch = showFileEntriesSearch && (results.size() > 0);
boolean showChangePermissions = DLFolderPermission.contains(permissionChecker, folder, ActionKeys.PERMISSIONS);
%>
Tambahkan di baris 301:
<c:if test="<%= showChangePermissions %>">
<liferay-security:permissionsURL
modelResource="<%= DLFolder.class.getName() %>"
modelResourceDescription="<%= folder.getName() %>"
resourcePrimKey="<%= String.valueOf(folder.getFolderId()) %>"
var="changePermissionsURL"
/>
<liferay-ui:icon image="permissions" url="<%= changePermissionsURL %>" />
</c:if>

Nah, selanjutnya, kami mengalami anomali di portlet permissions. Di Forum Liferay ada beberapa posting yang membahas kasus ketika seseorang pernah diberi akses untuk menambahkan sebuah portlet ke sebuah halaman, kemudian akses tersebut dihilangkan ketika user tersebut telah menambahkan portlet tersebut. Pada banyak kasus, user tetap dapat melihat isi dari portlet yang sudah ditambahkan meskipun hak aksesnya sudah tidak dimiliki. Ia hanya dicegah dari menambahkan portlet, dan tidak dicegah dari melihat isi portlet yang mana ia tidak lagi memiliki akses. Pada kasus kami, manifestasinya ialah kadang-kadang halaman depan user menunjukkan status denied, dan setelah beberapa kali dicoba (dengan navigasi berputar-putar ke tempat lain dahulu) portlet-portlet di halaman depan user tetap ditampilkan di halaman default.