Bagaimana Anda mengelola lompatan kompleksitas?

13

Tampaknya pengalaman yang jarang tetapi umum bahwa kadang-kadang Anda sedang mengerjakan sebuah proyek dan tiba-tiba sesuatu muncul tanpa terduga, melemparkan kunci pas besar dalam karya dan meningkatkan kompleksitas banyak.

Sebagai contoh, saya sedang mengerjakan aplikasi yang berbicara dengan layanan SOAP di berbagai mesin lain. Saya membuat prototipe yang berfungsi dengan baik, kemudian mengembangkan ujung depan yang teratur dan umumnya membuat semuanya berjalan dengan baik, cukup sederhana dan mudah diikuti. Ini bekerja sangat baik sampai kami mulai menguji di jaringan yang lebih luas dan tiba-tiba halaman mulai kehabisan waktu karena latensi koneksi dan waktu yang diperlukan untuk melakukan perhitungan pada mesin jarak jauh menghasilkan permintaan batas waktu untuk layanan sabun. Ternyata kami perlu mengubah arsitektur untuk memutar permintaan ke utas mereka sendiri dan menyimpan kembali data yang dikembalikan sehingga dapat diperbarui secara progresif di latar belakang daripada melakukan perhitungan berdasarkan permintaan berdasarkan permintaan.

Detail dari skenario itu tidak terlalu penting - memang itu bukan contoh yang bagus karena cukup dapat ditiru dan orang-orang yang telah menulis banyak aplikasi jenis ini untuk jenis lingkungan seperti ini mungkin telah mengantisipasinya - kecuali bahwa itu menggambarkan cara yang seseorang dapat mulai dengan premis dan model sederhana dan tiba-tiba memiliki eskalasi kompleksitas dengan baik ke dalam pengembangan proyek.

Strategi apa yang Anda miliki untuk menghadapi jenis-jenis perubahan fungsional yang kebutuhannya muncul - seringkali sebagai akibat dari faktor lingkungan daripada perubahan spesifikasi - nanti dalam proses pengembangan atau sebagai hasil pengujian? Bagaimana Anda menyeimbangkan antara menghindari optimasi prematur / YAGNI / risiko rekayasa berlebihan dalam merancang solusi yang memitigasi terhadap masalah yang mungkin terjadi tetapi tidak selalu kemungkinan sebagai kebalikan dari mengembangkan solusi yang lebih sederhana dan lebih mudah yang mungkin sama efektif tetapi tidak menggabungkan kesiapan untuk setiap kemungkinan kemungkinan?

Sunting: Gila Eddie menjawab termasuk "Anda menyedotnya dan menemukan cara paling murah untuk menerapkan kompleksitas baru." Itu membuat saya memikirkan sesuatu yang tersirat dalam pertanyaan tetapi saya tidak secara khusus mengangkat.

Setelah Anda menekan benjolan itu, dan Anda memasukkan perubahan yang diperlukan. Apakah Anda melakukan hal yang akan membuat proyek sedekat mungkin dengan jadwal tetapi dapat mempengaruhi pemeliharaan atau apakah Anda kembali ke arsitektur Anda dan mengerjakannya kembali pada tingkat yang lebih terperinci yang mungkin lebih dapat dipelihara tetapi akan mendorong semuanya kembali selama pengembangan?

glenatron
sumber

Jawaban:

8

Apa yang terlintas dalam pikiran saya membaca ini adalah pepatah lincah: menangani tugas paling berisiko dan / atau paling tidak dipahami dengan baik dalam siklus hidup proyek . Yaitu mencoba untuk menyusun kerangka kerja proyek sedini mungkin, untuk membuktikan bahwa konsep itu berfungsi. Ini pada gilirannya juga memungkinkan seseorang untuk menjalankan segala macam tes kejam untuk mendeteksi apakah arsitektur benar-benar memberikan janjinya dalam keadaan kehidupan nyata. Juga, jika ada teknologi / platform / alat baru yang tidak dikenal yang termasuk dalam solusi, bawa juga sejak awal.

Jika arsitektur inti OK, fungsionalitas individu dapat ditambahkan dan diuji secara bertahap, dan di-refactored jika diperlukan, dengan biaya yang relatif lebih sedikit. Perlu mengubah arsitektur adalah risiko besar, yang harus dihadapi di muka. Ini memberikan umpan balik yang cepat: dalam kasus terburuk, jika seluruh konsep berantakan, kami mengetahuinya lebih awal dan dapat membatalkan proyek dengan kerugian minimal.

Péter Török
sumber
6

Contoh Anda menyentuh beberapa aspek yang paling menantang dari pemrograman, yaitu komputasi terdistribusi dan pemrograman bersamaan , yang menjadi lebih banyak digunakan dan membuat programmer bekerja semakin sulit.

Bahkan pemrograman "normal" (utas tunggal pada satu mesin) sangat kompleks untuk setiap program non-trvial, sehingga dibutuhkan keahlian dan pengalaman bertahun-tahun untuk mendapatkan keahliannya - tetapi masih jauh dari "diselesaikan". Bahkan pada tingkat kompleksitas ini, sebagian besar disebabkan oleh ledakan kombinatorial , jauh melebihi kapasitas otak manusia untuk sepenuhnya dipahami dan dipahami. Berpikir sebaliknya adalah bodoh.

Komputasi terdistribusi dan pemrograman bersamaan menambah dua dimensi lagi pada ukuran ruang "kompleksitas", yang tumbuh setidaknya dalam kubik (sp?) (N ^ 3) dibandingkan dengan pemrograman "normal". Sebagai contoh, pikirkan beberapa masalah baru dan kesalahan yang harus kita atasi. Bahkan bermain dengan ide, bahwa Anda bisa memahami interkoneksi dan efek samping pada skala ini menggelikan.

Saya jelas tidak memiliki peluru perak, tetapi saya cukup yakin kesalahan terbesar yang bisa dilakukan adalah berpikir Anda memahami semuanya & menyelesaikannya.

Beberapa ide tentang cara mengatasi semua ini, selain apa yang sudah dijawab oleh jawaban lain:

  • Kerendahan hati yang luar biasa
  • Terimalah bahwa sistem / program Anda tidak sempurna, tidak kekal dan tidak lengkap .
  • Bersiaplah untuk kesalahan
  • Rangkullah perubahan
  • Merencanakan redundansi
  • Pikirkan tentang pemeriksaan masa depan
  • Lihatlah (atau pelajari) biologi atau sosiologi bagaimana sistem yang kompleks berperilaku
  • Cobalah yang terbaik untuk menghindari keadaan yang bisa berubah. Gunakan protokol stateless (seperti REST dan HTTP).
  • Pemrograman fungsional mungkin mengurangi beberapa rasa sakit

Saya kira saya bisa terus dan terus. Subjek yang sangat menarik :)

Maglob
sumber
Lihatlah (atau pelajari) biologi atau sosiologi bagaimana sistem yang kompleks berperilaku - Ayo. Sisa jawaban Anda solid, tetapi ini memiliki aplikasi pinggiran untuk masalah yang dijelaskan.
Jim G.
1
@ Jim G. Mungkin. Biologi tidak akan membantu mengoptimalkan for-loop Anda, tetapi jika Anda ingin menghasilkan perspektif baru, wawasan atau abstraksi yang efektif (pada pengembangan perangkat lunak), itu membantu untuk keluar dari kotak pasir seseorang. Berargumen bahwa biologi (atau sosiologi) tidak ada hubungannya dengan pemrograman, itu hanya beberapa melompat jauh dari argumen bahwa OOP atau pola desain tidak ada hubungannya dengan pemrograman. Misalnya: OOP : biologi -> Alan Kay -> OOP / Smalltalk. Atau Pola Desain : sosiologi -> desain kota -> Christopher Alexander -> Bahasa Pola -> Pola Desain.
Maglob
@ Jim G. Cont. Beberapa kutipan, Alan Kay: "Saya memikirkan benda-benda seperti sel biologis dan / atau komputer individu pada jaringan, hanya dapat berkomunikasi dengan pesan", dan Wikipedia: "[Pola Desain] Idenya diperkenalkan oleh arsitek Christopher Alexander di bidang arsitektur [1] dan telah diadaptasi untuk berbagai disiplin ilmu lainnya, termasuk ilmu komputer "
Maglob
Baik. Saya memberi Anda +1 untuk Coba yang terbaik untuk menghindari keadaan bisa berubah dan nugget lainnya. Maksud saya adalah jika manajer Anda menugaskan Anda mengurangi kompleksitas, Anda pasti akan menerapkan pisau Occam untuk masalah dan mulai bekerja. Saya tidak berpikir bahwa Anda atau orang lain akan "mencari ke biologi" untuk bantuan dengan masalah langsung.
Jim G.
2

Saya tidak setuju dengan semangat jawaban @ Péter Török karena mengasumsikan bahwa tim (atau individu) dapat meramalkan item paling berisiko di awal siklus hidup proyek. Misalnya, dalam kasus OP, tim tidak dapat melihat kompleksitas yang semakin meningkat yang melekat pada solusi multi-berulir sampai punggung mereka menempel ke dinding.

Pertanyaan OP adalah pertanyaan yang bagus, dan berbicara tentang masalah yang dimiliki oleh banyak toko pengembangan perangkat lunak.

Inilah cara saya menangani masalah:

  1. Ikuti saran Fred Brooks dan atur pengembang Anda seperti tim bedah .
  2. Pilih ahli bedah-ahli yang bijaksana dan "baik hati" yang dapat: A) Mengumpulkan kepercayaan dan rasa hormat dari rekan-rekannya; dan B) Membuat keputusan sulit tepat waktu.
  3. Harapkan dokter ahli bedah untuk mengurangi kerumitan di bagian depan dan belakang proses pengembangan.

Lebih lanjut tentang poin # 3:

  1. Master-ahli bedah harus melakukan upaya sadar untuk mengusulkan solusi paling sederhana yang akan berhasil. Pengalaman yang berarti selama bertahun-tahun harus menempatkan ahli bedah utama dalam posisi untuk melakukannya.
  2. Organisasi yang lebih luas, yaitu atasan ahli bedah-master, harus memberikan waktu dan sumber daya yang cukup bagi tim untuk mengurangi kompleksitas setelah tanggal pengiriman. Ini akan memungkinkan tim pengembangan untuk mengirimkan kode tepat waktu dan melakukan kaizen untuk mengurangi kompleksitas secara berkelanjutan.
Jim G.
sumber
IMHO dalam kasus OP, mereka seharusnya sudah mulai menguji sebelumnya, untuk mengungkap bagaimana (dan jika) arsitektur mereka bekerja dalam keadaan kehidupan nyata. Btw dengan menyarankan untuk memiliki "master ahli bedah", Anda tampaknya dasarnya menyiratkan bahwa ada yang orang yang bisa meramalkan risiko teknis proyek - titik yang tepat Anda mengaku tidak setuju dengan.
Péter Török
@ Péter Török: ... Dengan menyarankan untuk memiliki "ahli bedah ahli", pada dasarnya Anda menyiratkan bahwa ada orang yang dapat meramalkan risiko teknis proyek : Tidak, saya tidak. Saya mengatakan bahwa kedua orang ini adalah: A) Paling cocok untuk sepenuhnya menghindari kompleksitas di tempat pertama; dan B) Paling cocok untuk menggali tim dari kerumitan setelah kode dikirimkan.
Jim G.
IMHO kita berbicara tentang hal yang sama. Pengalaman yang membantu "ahli bedah utama" Anda memilih solusi paling sederhana yang mungkin dapat bekerja dibangun dari ingatan proyek dan solusi masa lalu, dan mengetahui solusi mana yang berhasil (atau tidak) dalam kasus spesifik mana. Dengan kata lain, dia melihat melalui solusi yang berlaku untuk masalah tertentu dan menilai potensi manfaat dan risiko masing-masing. Inilah yang membantu dia memilih yang tepat untuk situasi saat ini, sehingga menghindari jalan yang berisiko .
Péter Török
1
Ini mengingatkan saya pada sebuah kutipan dari pelatih kuda yang terlambat, hebat, Ray Hunt: "Bagaimana Anda mendapatkan penilaian yang baik? Pengalaman. Bagaimana Anda mendapatkan pengalaman? Keputusan yang buruk."
glenatron
1

Kode untuk antarmuka

Saat menulis fungsionalitas baru yang berinteraksi dengan fungsionalitas lain, buat batas dalam bentuk antarmuka (jenis Java) yang dilaluinya semuanya. Ini akan

  1. Pastikan Anda memiliki kontrol penuh atas fungsi apa yang digunakan
  2. memungkinkan Anda untuk memiliki beberapa implementasi dari fungsi yang sama.
  3. menjaga kompleksitas secara keseluruhan karena modul hanya terhubung sedikit dan bukannya saling terkait.

sumber
0

seseorang dapat mulai dengan premis dan model sederhana dan tiba-tiba memiliki eskalasi kompleksitas dengan baik ke dalam pengembangan proyek

Tidak mengherankan.

Ini adalah pengembangan perangkat lunak. Jika Anda tidak menemukan sesuatu yang baru, Anda mengunduh solusi yang sudah terbukti.

Ada sedikit jalan tengah.

Jika Anda menemukan sesuatu yang baru, maka harus ada setidaknya satu fitur yang Anda tidak sepenuhnya mengerti. (Untuk sepenuhnya memahaminya, Anda harus memiliki implementasi yang berfungsi, yang hanya akan Anda gunakan.)

Bagaimana cara mengaturnya?

  1. Miliki harapan yang realistis. Anda sedang menciptakan sesuatu yang baru. Ada harus menjadi bagian yang tidak Anda mengerti.

  2. Miliki harapan yang realistis. Jika tampaknya berfungsi dengan benar pertama kali, Anda telah mengabaikan sesuatu.

  3. Miliki harapan yang realistis. Jika itu sederhana, orang lain akan melakukannya terlebih dahulu, dan Anda bisa mengunduh solusi itu.

  4. Miliki harapan yang realistis. Anda tidak dapat memprediksi masa depan dengan baik.

S.Lott
sumber
2
Tunggu, jadi yang Anda katakan adalah: Punya harapan yang realistis?
glenatron
0

Desain dan kode dengan pikiran usang. Asumsikan bahwa apa yang Anda kode hari ini harus dipotong dan diganti besok.

Ian
sumber
0

Lingkungan harus menjadi bagian dari spesifikasi. Jadi perubahan ke lingkungan ADALAH perubahan pada spesifikasi. Sebaliknya, jika Anda mendasarkan prototipe dan desain Anda pada lingkungan selain dari apa yang ada dalam spesifikasi, Anda membuat kesalahan bodoh. Bagaimanapun, Anda menyedotnya dan menemukan cara paling murah untuk mengimplementasikan kompleksitas baru.

Edward Strange
sumber
0

Seperti kebanyakan masalah pemrograman, itu tergantung , menurut saya. Masalah ini sangat intrinsik untuk pekerjaan kreatif, sehingga Anda jangan lupa bahwa kegagalan akan terjadi, dan itu tidak masalah . Pemrograman adalah masalah yang jahat, dan Anda biasanya tidak tahu solusi yang tepat untuk masalah itu sampai Anda sudah menyelesaikannya.

Namun, ada sejumlah faktor lokal dan spesifik yang mungkin ikut berperan di sini, seperti:

  • Tujuan untuk sistem ini. Apakah ini satu hal? Apakah Anda bermaksud menjaga sistem ini bekerja untuk jangka menengah hingga panjang?

Untuk hal-hal jangka pendek, mungkin tidak layak untuk memikirkannya lebih dari cukup untuk menjalankannya. Refactoring itu mahal, dan itu sesuatu yang tidak membuat nilai akhir langsung untuk pengguna Anda. Namun, hampir tidak ada kasus yang bisa saya pikirkan selain dari perangkat lunak sekali pakai, di mana itu sangat singkat sehingga tidak layak untuk meningkatkan desain Anda. Jauh lebih penting untuk dapat memahami apa yang Anda lakukan, dan memperbaikinya dengan cepat, daripada menyelesaikannya sekarang. Jika itu untuk jangka panjang, maka kemungkinan besar akan terbayar pada akhirnya (dan mungkin jauh lebih cepat dari yang dipikirkan semua orang yang terlibat), atau kebalikannya (tidak melakukannya akan menimbulkan rasa sakit segera daripada "ketika kita harus memperbaikinya"). Saya hampir tergoda untuk mengatakan "selalu meluangkan waktu untuk membuatnya lebih baik", tetapi ada beberapa kasus di mana itu tidak mungkin.

  • Tujuan tim. Apakah ini lebih merupakan "lakukan sekarang, dengan biaya berapa pun", atau semacam "mari kita lakukan dengan benar"?

Ini akan sangat memengaruhi keputusan Anda. Tim Anda akan mendukung keputusan ini dengan memberi Anda sumber daya untuk mendesain ulang, atau mereka akan menuntut solusi cepat untuk dilakukan sekarang. Menurut pendapat saya, jika Anda menemukan bahwa tim mendorong Anda ke arah yang salah secara konsisten, itu adalah bendera merah besar. Saya telah melihat hal semacam ini berakhir dalam skenario di mana terjadi pemadaman api terus-menerus, di mana tidak pernah ada waktu untuk mendesain ulang karena Anda selalu memperbaiki masalah yang dihasilkan oleh desain buruk Anda. Mungkin juga ada jalan tengah: "lakban" sekarang, perbaiki secepatnya (tetapi sebenarnya lakukan).

  • Pemahaman Anda tentang masalah tersebut. Mengapa solusi sebelumnya tidak berhasil?

Sangat penting. Pikirkan tentang apa kesalahan atau masalahnya dan mengapa itu terjadi. Situasi semacam ini adalah peluang besar untuk menemukan asumsi, kendala, dan interaksi yang cacat (atau hilang). Secara umum, selalu lebih baik memahami masalah Anda lebih baik daripada menyelesaikan masalah saat ini. Ini mungkin pertahanan terbesar Anda melawan YAGNI / overengineering. Jika Anda memahami masalah Anda dengan cukup baik, maka Anda akan menyelesaikannya itu dan tidak masalah lainnya.

Akhirnya, cobalah membangun sesuatu dengan cara yang benar . Saya tidak berbicara tentang kesalahan dan masalah yang Anda hadapi ketika Anda lebih mengerti tentang masalah atau kesalahan manusiawi Anda. Maksud saya bukan "jangan membuat kesalahan dan membuatnya sempurna pertama kali" - itu tidak mungkin. Maksud saya, coba kelola kompleksitas dengan baik dalam pekerjaan sehari-hari Anda, perbaiki jendela yang rusak, pertahankan sesederhana mungkin, perbaiki kode dan pemikiran Anda sepanjang waktu. Dengan begitu ketika (tidak jika) berganti mengetuk pintu Anda, Anda dapat menyambutnya dengan tangan terbuka, bukan senapan.

Juan Carlos Coto
sumber