This article was created for the purpose of individual review assignment of PPL 2021

Setiap orang mungkin mempunyai preferensi dalam menuliskan code masing-masing. Walaupun untuk setiap bahasa pemrograman tertentu tetap ada standar umum dalam penulisan code, baik dalam segi penamaan variabel atau fungsi maupun syntax yang benar, masih banyak hal lain yang mungkin tidak tercakup dalam aturan tersebut. Seperti contoh, seseorang bebas untuk menamakan fungsi yang dia buat sesuka hati, asalkan mengikuti format penulisan fungsi dari bahasa pemrograman yang dibuat. Namun, orang tersebut tetap akan menamakan fungsi yang dibuat sesuai dengan hal yang dilakukan oleh fungsi, agar dia dan orang yang membaca code nya dapat mudah memahami kegunaan fungsi dari namanya. Hal tersebut hanyalah salah satu bagian yang tercakup dalam hal yang saya akan bahas pada artikel ini, yaitu mengenai clean code.

Apa itu Clean Code

Banyak definisi dari clean code yang dapat ditemukan pada internet, sehingga tidak ada definisi tepat dari clean code sendiri. Namun, kurang lebih bisa disimpulkan bahwa clean code adalah sebuah aturan untuk menuliskan code, dimana code tersebut tidak hanya valid untuk dijalankan oleh mesin pemrograman, namun juga mudah memudahkan manusia, baik dalam membaca dan memahami code, mengembangkan code, meningkatkan kualitas code, dan lain-lain. Berikut ini adalah beberapa poin dari clean code yang dapat digunakan untuk membuat code tetap rapih dan jelas sehingga code mudah untuk dipahami.

Penamaan yang berarti

Dalam menuliskan code, pastinya kita akan menggunakan variabel-variabel untuk menyimpan suatu nilai. Agar lebih mudah dipahami, sebaiknya kita menamakan variabel tersebut sesuai dengan konteks nilai yang disimpan. Selain itu, dengan memberikan nama yang jelas, kita tidak perlu menggunakan comment untuk menjelaskan apa yang disimpan pada variabel tersebut. Sebagai contoh:

user_detail = UserDetail.objects.get(user=request.user)

Pada contoh diatas, saya mengambil sebuah objek UserDetail yang kurang lebih berisi detail dari user, dan menyimpannya ke dalam suatu variabel. Dengan menamakan variabel tersebut user_detail, kita paham bahwa objek tersebut menyimpan detail dari user, tanpa harus melihat penjelasan lain.

Penggunaan comment yang efisien

Comment biasanya digunakan untuk menjelaskan lebih lanjut bagian code yang tidak terlalu jelas. Namun, sebenarnya penggunaan comment tersebut kurang benar, dikarenakan hal ini berarti code yang kita buat kurang jelas sehingga membutuhkan bantuan comment agar mudah dipahami. Daripada menggunakan comment, lebih baik agar kita mengubah code menjadi lebih jelas. Tuliskan comment hanya pada bagian code yang memang sulit untuk dipahami memang karena code kompleks dan sulit untuk dimengerti, bukan karena penulisan code yang buruk.

Penulisan Function

Ada beberapa aturan yang harus diterapkan dalam menuliskan function di dalam code, beberapa diantaranya adalah:

  1. Fungsi hanya fokus melakukan satu hal. Fungsi yang baik adalah fungsi yang dapat melakukan satu hal dengan baik, dan hanya satu hal tersebut. Jika fungsi yang dibuat melakukan lebih dari satu pekerjaan, lebih baik agar pekerjaan tersebut dibagi dengan membuat fungsi-fungsi baru. Contoh:
def my_profile(request):
""" View function for redirecting profile page"""
user_status = user_check(request)
if user_status == "NO ROLE":
return redirect('authorization:select_role')
if user_status == "NO DETAIL":
return redirect('authorization:detail')
if user_status == 1:
return my_profile_animallover(request)
if user_status == 2:
return my_profile_shelter(request)
if user_status == 3:
return my_profile_vet(request)
return redirect('homepage:index')

Bisa dilihat pada task yang ada pada code diatas dibagi menjadi beberapa fungsi. Fungsi user_check() digunakan untuk mendapatkan role dari user, kemudian fungsi my_profile() memeriksa role tersebut, dan melakukan redirect atau memanggil fungsi lain tergantung dengan hasil role yang diperiksa.

2. Menggunakan nama yang berarti

Seperti variabel, fungsi juga harus diberi nama yang berarti. Jika variabel dinamakan berdasarkan konteks nilai yang disimpan, fungsi dinamakan berdasarkan pekerjaan yang dilakukan. Sebagai contoh jika ada fungsi digunakan untuk menghitung jumlah total pemasukan, fungsi tersebut dinamakan count_total_income(), menjelaskan pekerjaan yang dilakukan.

3. Tidak menimbulkan side effect

Fungsi yang menimbulkan side effect berarti fungsi tersebut bisa mengubah nilai variabel diluar local environment fungsi tersebut. Hal ini berarti fungsi tersebut bisa mempunyai efek selain hal utama yang dilakukan fungsi tersebut. Hal ini merupakan sebuah masalah karena sewaktu-waktu output yang dihasilkan program bisa berbeda dengan alasan yang tidak jelas. Salah satu contoh sebagai berikut:

a = 0def assign_a(value):
global a
a = value
assign_a(4)

Fungsi diatas meng-assign variabel a menjadi 4. Hal ini sebenarnya tidak diperbolehkan, karena fungsi assign_a() mengubah value dari variabel a yang sebenarnya bukan merupakan bagian dari fungsi tersebut.

Penggunaan Error Handling

Terkadang, penggunaan exception lebih baik daripada menggunakan if-else. Alasannya adalah dengan menggunakan exception, kita sekaligus bisa mendapatkan error lain yang tidak terprediksi, sehingga program tetap akan berjalan jika ada error yang terjadi. Sebagai contoh:

# memakai exception
try:
user = User.objects.get(email=request.user)
detail = UserDetail.objects.get(user=user)
return detail
except:
return "NO DETAIL"
# memakai if-else
user = User.objects.get(email=request.user)
if user is not None:
detail = UserDetail.objects.get(user=user)
retun detail
except:
return "NO DETAIL"

Penerapan TDD

TDD adalah metode programming dimana programmer harus menuliskan test yang akan gagal terlebih dahulu, setelah itu kita baru bisa menuliskan program untuk meluluskan test yang sudah dibuat tersebut. Hal ini berguna agar kita mendapatkan gambaran yang jelas tentang program yang kita buat, baik mengenai input, fungsi dari program, dan output yang dihasilkan. Hal ini juga dapat mencegah terjadinya duplikasi code, karena kita tidak akan menuliskan code dengan fungsi yang sama persis jika kita menerapkan TDD. Ada 3 prinsip dalam melakukan TDD, yaitu:

  1. Kita tidak boleh menuliskan production code sampai kita menuliskan unit test yang gagal.
  2. Kita tidak boleh menuliskan unit test yang lebih dari cukup untuk gagal, dan tidak mengkompilasi berarti kegagalan.
  3. Kita tidak boleh menuliskan unit test yang lebih dari cukup untuk meluluskan unit test yang sedang gagal.

DRY (Don’t Repeat Yourself)

Seperti arti dari prinsip tersebut, jangan mengulang kembali apa yang telah kita lakukan sebelumnya. Dengan kata lain, jangan menuliskan duplikasi dari kode yang sudah dibuat. Jika kita menuliskan baris-baris code yang sudah kita pernah kita tulis sebelumnya, kita bisa menjadikan baris -baris tersebut sebagai fungsi yang memuat baris-baris tersebut. Kemudian ganti baris-baris tersebut dengan pemanggilan fungsi yang kita sudah buat. Sebagai contoh:

def my_profile_vet(request):
user = authenticate(username='dummy', password='12345')
if user is None:
return redirect('homepage:index')
return render(request, 'vet_homepage.html')
def my_profile_animallover(request):
user = authenticate(username='dummy', password='12345')
if user is None:
return redirect('homepage:index')
return render(request, 'animal_lover_profile.html')

Bisa diperhatikan, kedua fungsi tersebut sama-sama menjalankan autentikasi user sebelum mengembalikan render html masing-masing. Baris-baris bagian autentikasi user sebenarnya dapat dimasukkan kedalam satu fungsi agar repetisi diatas tidak terjadi sebagai berikut:

def authenticate_user(request):
user = authenticate(username='dummy', password='12345')
if user is None:
return redirect('homepage:index')
def my_profile_vet(request):
authenticate_user(request)
return render(request, 'vet_homepage.html')
def my_profile_animallover(request):
authenticate_user(request)
return render(request, 'animal_lover_profile.html')

Sekian artikel dari saya mengenai clean code, terima kasih.

Referensi: