14.3 Engineer: Bukan Sekadar Jalan, Tapi Jalan yang Teruji

Setelah fitur dan produk, muncul tuntutan yang lebih berat: bagaimana memastikan software bisa berjalan andal di berbagai kondisi dan perubahan.

Kembali ke aplikasi catatan harian Anda. Misalkan Anda sudah menambahkan fitur pencarian. Anda coba mencari catatan lama, hasilnya muncul. Semua terlihat baik. Lalu Anda serahkan ke teman untuk dipakai. Esoknya teman Anda lapor: “Tadi aku cari catatan yang judulnya kosong, aplikasinya error.” Anda buka kodenya, ternyata fungsi pencarian Anda tidak menangani kasus judul null. Di lingkungan developer Anda, Anda tidak pernah membuat catatan tanpa judul. Tapi di dunia nyata, orang bisa lalai, atau data lama dari impor memang tidak punya judul.

Inilah titik di mana seorang programmer mulai bertransisi menjadi engineer. Programmer puas ketika kode berfungsi di skenario yang dia bayangkan. Engineer tidak puas sampai dia tahu apa yang terjadi di skenario yang tidak dia bayangkan.

Perhatikan perbedaan implementasi fungsi cariCatatan berikut:

// Versi programmer: hanya berfungsi di skenario ideal
function cariCatatan(daftarCatatan, kataKunci) {
  return daftarCatatan.filter(catatan =>
    catatan.judul.includes(kataKunci)
  );
}

// Versi engineer: menangani skenario tak terduga
function cariCatatan(daftarCatatan, kataKunci) {
  if (!Array.isArray(daftarCatatan)) {
    console.error('cariCatatan: daftarCatatan bukan array');
    return [];
  }
  if (typeof kataKunci !== 'string') {
    console.warn('cariCatatan: kataKunci bukan string, dikosongkan');
    kataKunci = '';
  }
  try {
    return daftarCatatan.filter(catatan => {
      const judul = catatan?.judul ?? '';
      return judul.toLowerCase().includes(kataKunci.toLowerCase());
    });
  } catch (error) {
    console.error('cariCatatan: error saat filtering', error.message);
    return [];
  }
}

Diagram berikut menggambarkan perbedaan pola pikir programmer dan engineer dalam menghadapi skenario tak terduga.

flowchart TD A[Kode berfungsi di skenario ideal] --> B{Skenario tak terduga muncul?} B -->|Tidak| C[Programmer: puas, lanjut] B -->|Ya| D[Contoh: judul null, beban tinggi, komponen mati] D --> E[Engineer: antisipasi & uji] E --> F[Penanganan error, constraint, evidence] F --> G[Sistem andal di berbagai kondisi] G --> H[Engineer: bertanggung jawab pada sistem] C --> I[Programmer: bertanggung jawab pada kode]

Pola pikir engineer adalah pola pikir yang terus bertanya: “Apa lagi yang bisa salah?” Bukan karena pesimis, tetapi karena sadar bahwa software tidak hidup di lingkungan steril. Software hidup di tengah pengguna yang tidak terduga, data yang kotor, jaringan yang lambat, perangkat yang beragam, dan perubahan requirement yang tak pernah berhenti.

Seorang engineer memikirkan reliability. Apakah sistem ini tetap berfungsi ketika beban naik sepuluh kali lipat? Apakah sistem ini tetap berfungsi ketika salah satu komponen mati? Apakah sistem ini memberikan pesan error yang jelas ketika sesuatu gagal, bukan sekadar layar putih?

Engineer juga memikirkan constraint. Setiap sistem punya batasan: berapa banyak pengguna yang bisa dilayani bersamaan, berapa besar data yang bisa disimpan, berapa cepat waktu respons yang bisa diterima. Programmer sering mengabaikan constraint karena di lingkungan development semuanya berjalan mulus. Engineer justru menjadikan constraint sebagai bagian dari desain. Dia tidak membangun fitur yang bekerja di atas asumsi ideal, tetapi fitur yang bekerja di dalam batasan nyata.

Yang lebih penting, engineer bekerja dengan evidence. Ketika programmer berkata “sepertinya ini beres”, engineer berkata “tunjukkan buktinya”. Bukti bisa berupa hasil pengujian, log, metrik, monitoring, atau observasi langsung. Engineer tidak percaya pada kode yang tidak teruji. Dia percaya pada kode yang sudah memberikan bukti bahwa dia bekerja sesuai harapan, bahkan dalam kondisi tertekan.

Setiap perubahan kode juga dibawa dengan kesadaran akan konsekuensi. Programmer mengubah satu baris kode, lalu menjalankan ulang, dan melihat fiturnya masih berfungsi. Engineer bertanya: “Fitur lain apa yang mungkin terpengaruh? Siapa lagi yang menggunakan komponen ini? Apakah perubahan ini membuat sistem lebih sulit dirawat di masa depan?” Bukan karena takut berubah, tetapi karena sadar bahwa dalam software, satu perubahan kecil bisa merambat ke seluruh sistem.

Lompatan dari programmer ke engineer bukan lompatan teknologi, melainkan lompatan tanggung jawab. Programmer bertanggung jawab pada kode yang berfungsi. Engineer bertanggung jawab pada sistem yang bisa diandalkan. Dan di era AI, di mana kode bisa dihasilkan dalam hitungan detik, kemampuan untuk memikirkan reliability, constraint, evidence, dan konsekuensi menjadi semakin berharga. AI bisa menulis kode, tetapi AI belum bisa memastikan bahwa kode itu andal di semua skenario yang tidak terpikirkan.

Inilah yang membedakan engineer dari sekadar programmer: dia tidak hanya membuat jalan, dia memastikan jalan itu teruji, punya rambu, punya jalur alternatif, dan bisa dilewati dalam kondisi apa pun. Dan dari sini, langkah selanjutnya adalah mulai memikirkan bentuk keseluruhan sistem, bukan hanya jalurnya.

From Programmer to Architect
From Programmer to Architect