22 poin oleh GN⁺ 2024-09-04 | 5 komentar | Bagikan ke WhatsApp
  • Saat memelihara codebase yang tidak familier, banyak waktu dihabiskan untuk mencari string
  • Bahkan dalam proyek yang ditulis sendiri, kita tetap perlu sering mencari banyak hal seperti nama fungsi, pesan error, dan nama kelas
  • Jika pencarian tidak berjalan baik, ada risiko referensi di codebase tidak ditemukan lalu dianggap tidak perlu
  • Dalam konteks ini, penulis merumuskan beberapa aturan yang bisa diterapkan untuk menjaga Greppability pada codebase

Jangan memecah identifier

  • Memecah identifier atau menyusunnya secara dinamis bukan ide yang baik
  • Misalkan ada dua tabel database bernama shipping_addresses dan billing_addresses, membangun nama tabel secara dinamis berdasarkan jenis pesanan mungkin terlihat bagus
const getTableName = (addressType: 'shipping' | 'billing') => {  
    return `${addressType}_addresses`  
}  
  • Ini memang tampak DRY, tetapi kurang baik untuk maintenance. Seseorang yang mencari nama tabel shipping_addresses di codebase bisa saja melewatkan bagian ini
  • Hardcode identifier adalah pendekatan yang lebih baik
  • Kode yang direfaktor demi kemudahan pencarian:
const getTableName = (addressType: 'shipping' | 'billing') => {  
    if (addressType === 'shipping') {  
        return 'shipping_addresses'  
    }  
    if (addressType === 'billing') {  
        return 'billing_addresses'  
    }  
    throw new TypeError('addressType must be billing or shipping')  
}  
  • Hal yang sama berlaku untuk nama kolom, field objek, dan nama method/fungsi (di JavaScript, nama method dapat dengan mudah disusun secara dinamis)

Gunakan nama yang sama di seluruh stack

  • Jangan mengganti nama field di batas aplikasi hanya demi menyesuaikan konvensi penamaan
  • Contoh yang paling umum adalah membawa identifier snake_case bergaya PostgreSQL ke JavaScript lalu mengubahnya menjadi camelCase, dan itu bukan ide yang baik
  • Ini membuat pencarian jadi lebih sulit. Untuk menemukan semua item, kita harus mencari dua string, bukan satu
const getAddress = async (id: string) => {  
    const address = await getAddressById(id)  
    return {  
        streetName: address.street_name,  
        zipCode: address.zip_code,  
    }  
}  
  • Mengembalikan objeknya secara langsung justru lebih baik
const getAddress = async (id: string) => {  
    return await getAddressById(id)  
}  

Flat lebih baik daripada nested

  • Terinspirasi dari Zen of Python, saat menangani namespace, dalam banyak kasus lebih baik membuat struktur folder/objek tetap flat daripada nested
  • Jika ada dua opsi untuk konfigurasi file terjemahan:
{  
    "auth": {  
        "login": {  
            "title": "Login",  
            "emailLabel": "Email",  
            "passwordLabel": "Password",  
        },  
        "register": {  
            "title": "Register",  
            "emailLabel": "Email",  
            "passwordLabel": "Password",  
        }  
    }  
}  
{  
    "auth.login.title": "Login",  
    "auth.login.emailLabel": "Email",   
    "auth.login.passwordLabel": "Password",  
    "auth.register.title": "Login",  
    "auth.register.emailLabel": "Email",  
    "auth.register.passwordLabel": "Password",  
}  
  • Sebaiknya pilih opsi kedua. Kunci lebih mudah ditemukan, dan bisa direferensikan seperti t('auth.login.title')
  • Jika melihat struktur komponen React:
./components/AttributeFilterCombobox.tsx  
./components/AttributeFilterDialog.tsx  
./components/AttributeFilterRating.tsx  
./components/AttributeFilterSelect.tsx  
  • Ini lebih disukai daripada struktur seperti berikut
./components/attribute/filter/Combobox.tsx  
./components/attribute/filter/Dialog.tsx  
./components/attribute/filter/Rating.tsx  
./components/attribute/filter/Select.tsx  
  • Dari sudut pandang pencarian, kita bisa mencari nama komponen lengkap yang memuat namespace seperti AttributeFilterCombobox, alih-alih nama umum seperti Dialog

Opini GN⁺

  • Tulisan blog ini menjelaskan dengan baik pentingnya pencarian identifier saat memelihara codebase
  • Menyusun identifier secara dinamis atau mengganti nama di batas aplikasi membuat maintenance kode menjadi lebih sulit. Identifier harus konsisten dan jelas
  • Sebaliknya, hardcode identifier dan menjaga namespace tetap flat lebih baik dari sudut pandang pencarian
  • Untuk meningkatkan keterbacaan dan kemudahan maintenance kode, prinsip-prinsip ini layak diterapkan di proyek
  • Selain aturan yang diajukan penulis, masih ada berbagai cara lain untuk meningkatkan kualitas kode, seperti menulis Self-Documenting Code dan menggunakan komentar yang bermakna

5 komentar

 
nowpark 2024-09-06

Tolong ubah ke full path dari JSON, saya juga tinggalkan satu alat yang membuatnya lebih greppable!

https://id.news.hada.io/topic?id=3159

 
botplaysdice 2024-09-05

Bagus juga... greppability ya...

 
ahwjdekf 2024-09-04

Sepertinya juga berguna untuk menuliskan informasi yang bermanfaat dalam satu baris sebisa mungkin.

 
roxie 2024-09-09

Bagus.

 
GN⁺ 2024-09-04
Opini Hacker News
  • Mencari simbol seperti nama fungsi dan nama kelas itu kurang efektif dibanding memakai alat yang memahami sintaks kode

    • Hanya dengan fitur "go to definition" dan "find usages", kebutuhan akan pencarian teks bisa sangat berkurang
    • Selama 10 tahun terakhir, saya kebanyakan hanya mencari string yang terlihat oleh pengguna
    • Postingan seperti ini berarti penulisnya perlu meluangkan waktu untuk mempelajari alat yang lebih baik dan sesuai dengan bahasanya
    • IDE yang bagus saja bisa menghemat banyak waktu
  • Akan berguna jika alat grep punya mode "super case-insensitive"

    • Misalnya, saat mencari "FooBar|first_name", ia diperluas agar bisa mencocokkan semua variasi penulisan
    • Sulit membayangkan situasi di mana fitur seperti ini tidak menjadi default
  • Mendukung greppability

    • Dalam bahasa Swedia, kata seperti "grep-bar" atau "grep-barhet" memang benar-benar ada
    • "greppbar" berarti "dapat dipahami", dan "greppbarhet" berarti "kemungkinan untuk dapat dipahami"
  • Saat merancang Hamilton, tujuannya adalah membuat definisi fungsi dan penggunaan turunannya mudah untuk di-grep

    • Di dunia transformasi data Python, sangat mudah membuat codebase yang tidak banyak terbantu oleh grep
  • 'greppable' bukan kata/konsep yang dipakai secara mandiri

    • Saya sudah lama memakainya sebagai prinsip pengorganisasian
    • Ini salah satu cara terbaik untuk menata kode
  • Pernah melihat contoh rumit yang memakai interpolasi string bersyarat

    • Saat pertama kali bergabung ke proyek itu, butuh waktu terlalu lama untuk menemukan tiga kata yang saya lihat di UI
    • Belakangan saya mengubah semuanya menjadi string yang mudah di-grep
  • Banyak gaya penulisan kode dan alat menjaga konstanta string tetap dalam satu baris tanpa memandang panjang baris

    • Tujuannya agar saat melihat string di output program, Anda bisa mencari string yang sama di kode
  • Rust, Javascript, dan Lisp menaruh kata kunci di depan definisi fungsi sehingga mudah dicari

    • C tidak punya kata kunci seperti itu, jadi Anda hanya bisa mencari nama fungsi
    • Beberapa aturan penulisan C membagi definisi menjadi dua baris agar lebih mudah dicari
  • Setuju dengan greppability, tetapi tidak setuju mempertahankan nama yang sama lintas batas

    • Satu simbol sebaiknya hanya ada di satu domain agar beban kognitif berkurang
  • Kemudahan pencarian kode itu bagus, tetapi contohnya sengaja meningkatkan kemungkinan kesalahan

    • Menambahkan kondisi string menimbulkan kemungkinan ketidaksesuaian antara input dan output
    • Meratakan dictionary meningkatkan kemungkinan terjadinya typo
    • Typo sering terjadi, dan jika sudah disalin ke beberapa codebase, akan sulit diperbaiki