Ketika Murray Gell-Mann ditanya bagaimana Richard Feynman berhasil memecahkan begitu banyak masalah sulit Gell-Mann menjawab bahwa Feynman algoritma:
Gell-Mann mencoba untuk menjelaskan bahwa Feynman adalah jenis yang berbeda dari pemecah masalah dan tidak ada wawasan yang dapat diperoleh dari mempelajari metode. Aku merasakan hal yang sama tentang mengelola kompleksitas dalam medium/besar untuk proyek-proyek perangkat lunak. Orang-orang yang baik hanya inheren baik dan entah bagaimana berhasil untuk lapisan dan tumpukan berbagai abstraksi untuk membuat seluruh hal yang mudah dikelola tanpa memperkenalkan asing cruft.
Jadi Feynman algoritma satu-satunya cara untuk mengelola disengaja kompleksitas atau ada sebenarnya metode yang insinyur perangkat lunak yang dapat secara konsisten menerapkan untuk menjinakkan disengaja kompleksitas?
Ketika anda melihat langkah yang baik, carilah yang lebih baik.
—Emanuel Lasker, 27 tahun juara catur dunia
Dalam pengalaman saya, pendorong terbesar dari kecelakaan kompleksitas programmer menempel dengan draft pertama, hanya karena hal itu terjadi untuk bekerja. Ini adalah sesuatu yang bisa kita pelajari dari komposisi bahasa inggris kelas. Mereka membangun dalam waktu untuk pergi melalui beberapa konsep dalam tugas-tugas mereka, menggabungkan guru umpan balik. Kelas pemrograman, untuk beberapa alasan, don't.
Ada buku-buku yang penuh dengan beton dan tujuan cara untuk mengenali, mengartikulasikan, dan memperbaiki suboptimal kode: Clean Code, Bekerja secara Efektif dengan Warisan Code, dan banyak lainnya. Banyak programmer yang akrab dengan teknik ini, tapi don't selalu meluangkan waktu untuk menerapkannya. Mereka benar-benar mampu mengurangi kecelakaan kompleksitas, mereka hanya ingin't membuat suatu kebiasaan untuk coba.
Bagian dari masalah adalah kita don't sering melihat menengah kompleksitas dari orang lain's kode, kecuali telah melalui peer review pada tahap awal. Kode yang bersih terlihat seperti itu mudah untuk menulis, padahal sebenarnya itu biasanya melibatkan beberapa konsep. Anda menulis cara terbaik yang datang ke kepala anda pada awalnya, melihat kompleksitas yang tidak perlu memperkenalkan, maka "terlihat untuk bergerak lebih baik" dan refactor untuk menghapus orang-orang kompleksitas. Kemudian anda terus "mencari sebuah langkah yang lebih baik" sampai anda tidak dapat menemukan satu.
Namun, anda don't menempatkan kode untuk review sampai setelah semua yang churn, jadi eksternal ini terlihat seperti itu mungkin juga telah Feynman seperti proses. Anda memiliki kecenderungan untuk berpikir anda dapat't melakukan itu semua satu potongan seperti itu, sehingga anda don't repot-repot mencoba, tetapi kebenaran adalah penulis yang indah sederhana kode anda baru saja membaca biasanya dapat't menulis itu semua dalam satu potongan seperti itu, atau jika mereka bisa, it's hanya karena mereka memiliki pengalaman menulis kode yang sama berkali-kali sebelumnya, dan sekarang dapat melihat pola tanpa tahap-tahap peralihan. Either way, anda bisa't menghindari draft.
"arsitektur perangkat Lunak keterampilan tidak dapat diajarkan" adalah luas kekeliruan.
Sangat mudah untuk memahami mengapa banyak orang-orang percaya (orang-orang yang ingin percaya bahwa mereka're mistis khusus, dan orang-orang yang tidak't ingin percaya bahwa itu's bukan kesalahan mereka bahwa mereka're aren't.) Hal ini tetap salah, keterampilan agak lebih banyak latihan yang intensif dari perangkat lunak lain keterampilan (misalnya pemahaman loop, berurusan dengan pointer dll.)
Saya sangat percaya bahwa membangun sistem yang besar lebih rentan terhadap praktek berulang dan belajar dari pengalaman dengan cara yang sama bahwa menjadi seorang musisi besar atau pembicara publik adalah: jumlah minimum bakat adalah prasyarat, tetapi itu's tidak depresi besar minimal yang berada di luar jangkauan sebagian besar praktisi.
Berurusan dengan kompleksitas adalah keterampilan anda memperoleh sebagian besar dengan mencoba dan gagal beberapa kali. It's hanya bahwa banyak pedoman umum bahwa masyarakat telah ditemukan untuk pemrograman besar (menggunakan lapisan-lapisan, melawan duplikasi mana pun air mata kepalanya, mematuhi agama untuk 0/1/infinity...) yang tidak jelas benar dan perlu untuk pemula sampai mereka benar-benar melakukan program sesuatu yang lebih besar. Sampai anda benar-benar telah digigit oleh duplikasi yang menyebabkan masalah hanya beberapa bulan kemudian, anda hanya tidak bisa 'mendapatkan' pentingnya prinsip-prinsip tersebut.
Berpikir pragmatis oleh Andy Hunt membahas masalah ini. Hal ini mengacu pada Dreyfus model, sesuai dengan yang ada 5 tahap kemahiran dalam berbagai keterampilan. Pemula (tahap 1) membutuhkan instruksi yang tepat untuk dapat melakukan sesuatu dengan benar. Para ahli (tahap 5), sebaliknya, dapat menerapkan pola umum untuk masalah yang diberikan. Mengutip buku,
Hal ini sering sulit bagi para ahli untuk menjelaskan tindakan mereka untuk baik tingkat detail; banyak tanggapan mereka sangat baik dipraktekkan bahwa mereka menjadi preconscious tindakan. Pengalaman mereka yang luas ditambang oleh nonverbal, preconscious daerah otak, yang membuat sulit bagi kita untuk mengamati dan sulit bagi mereka untuk mengartikulasikan.
Ketika para ahli melakukan hal mereka, tampaknya hampir magis untuk sisa dari kita—aneh mantra, wawasan yang tampaknya muncul dari mana saja, dan tampaknya kemampuan luar biasa untuk mengetahui jawaban yang benar ketika kita bahkan tidak begitu yakin tentang pertanyaan. Ini bukan sihir, tentu saja, tapi cara itu para ahli memandang dunia, bagaimana mereka memecahkan masalah, mental model yang mereka gunakan, dan sebagainya, yang semua berbeda dari nonexperts.
Aturan umum ini melihat (dan sebagai hasilnya menghindari) isu-isu yang berbeda yang dapat diterapkan untuk secara khusus masalah disengaja kompleksitas. Memiliki satu set tertentu dari aturan isn't cukup untuk menghindari masalah ini. Akan selalu ada situasi yang isn't ditutupi oleh aturan-aturan. Kami perlu mendapatkan pengalaman untuk dapat meramalkan masalah atau mengidentifikasi solusi. Pengalaman adalah sesuatu yang tidak bisa diajarkan, hal ini hanya dapat diperoleh dengan konstan mencoba, gagal atau berhasil dan belajar dari kesalahan.
Pertanyaan dari tempat Kerja yang relevan dan IMHO akan menarik untuk dibaca dalam konteks ini.
Anda tidak mengejanya, tapi "kebetulan kompleksitas" didefinisikan sebagai kompleksitas yang tidak melekat untuk masalah ini, dibandingkan dengan "penting" kompleksitas. Teknik-teknik yang diperlukan untuk "Penjinakan" akan tergantung pada di mana anda mulai dari. Berikut ini sebagian besar mengacu pada sistem yang telah diperoleh kompleksitas yang tidak perlu.
Saya memiliki pengalaman dalam sejumlah besar multi-tahun proyek-proyek yang "kebetulan" komponen secara signifikan melebihi "penting" aspek, dan juga orang-orang di mana hal itu tidak.
Sebenarnya, Feynman algoritma berlaku untuk beberapa hal, tetapi itu tidak berarti bahwa "berpikir keras" berarti hanya keajaiban yang tidak dapat dikodifikasi.
Saya menemukan ada dua pendekatan yang harus diambil. Mengambil mereka – mereka yang tidak alternatif. Salah satunya adalah untuk mengatasi itu sedikit demi sedikit dan yang lainnya adalah untuk melakukan major ulang. Jadi tentu saja, "menuliskan masalah". Ini mungkin mengambil bentuk audit sistem – kode modul, keadaan mereka (bau, tingkat pengujian otomatis, berapa banyak staf klaim untuk memahaminya), secara keseluruhan arsitektur (ada satu, bahkan jika itu "memiliki masalah"), keadaan persyaratan, dll. dll.
Ini adalah sifat dari "kecelakaan" kompleksitas bahwa tidak ada satu masalah yang perlu ditangani. Jadi, anda perlu untuk triase. Mana yang sakit – dalam hal kemampuan untuk menjaga sistem dan kemajuan perkembangannya? Mungkin beberapa kode adalah benar-benar bau, tapi tidak prioritas dan penetapan dapat dilakukan untuk menunggu. Di sisi lain, mungkin ada beberapa kode yang akan cepat kembali waktu yang dihabiskan refactoring.
Menentukan rencana apa yang lebih baik arsitektur akan dan mencoba untuk memastikan pekerjaan baru sesuai dengan rencana yang – ini adalah pendekatan inkremental.
Juga, mengartikulasikan biaya masalah dan menggunakannya untuk membangun kasus bisnis untuk membenarkan refactor. Kuncinya di sini adalah bahwa baik architected sistem mungkin jauh lebih kuat dan yang dapat diuji dan dapat dihasilkan dalam waktu yang jauh lebih singkat (biaya dan jadwal) untuk menerapkan perubahan ini memiliki nilai riil.
Besar ulang tidak datang dalam "berpikir keras" kategori – anda perlu untuk mendapatkan yang benar. Ini adalah tempat yang memiliki "Feynman" (nah, sebagian kecil dari satu akan baik-baik saja) tidak melunasi sangat. Besar ulang yang tidak menghasilkan hasil yang lebih baik arsitektur dapat menjadi bencana. Full sistem penulisan ulang yang terkenal untuk ini.
Implisit dalam setiap pendekatan adalah mengetahui bagaimana membedakan yang "kebetulan" dari "penting" – yang adalah untuk mengatakan anda perlu untuk memiliki seorang arsitek besar (atau tim arsitek) yang benar-benar memahami sistem dan tujuannya.
Setelah mengatakan semua itu, hal yang penting bagi saya adalah pengujian otomatis. Jika anda memiliki cukup itu, sistem anda di bawah kontrol. Jika anda don't . . .
"Segala sesuatu harus dibuat sesederhana mungkin, tetapi tidak lebih sederhana."
— dikaitkan dengan Albert Einstein
Biar saya buat saya pribadi algoritma untuk berurusan dengan disengaja kompleksitas.
Seluruh desain sihir akan di Langkah 3: bagaimana anda mengatur kelas-kelas? Ini ternyata menjadi pertanyaan yang sama seperti: bagaimana apakah anda membayangkan bahwa anda memiliki solusi untuk masalah anda sebelum anda memiliki solusi untuk masalah anda?
Hebatnya, hanya membayangkan anda memiliki solusi tampaknya menjadi salah satu rekomendasi utama dari orang-orang yang menulis pada pemecahan masalah (disebut "angan-angan" oleh Abelson dan Sussman di Struktur dan Interpretasi dari Program Komputer dan "bekerja mundur" di Polya's Bagaimana untuk Menyelesaikannya)
Di sisi lain, tidak semua orang memiliki hal yang sama "rasa untuk membayangkan solusi": ada solusi yang hanya anda menemukan elegan, dan ada orang lain yang lebih mudah dipahami oleh khalayak yang lebih luas. Itulah mengapa anda perlu untuk peer-review kode anda dengan sesama pengembang: tidak begitu banyak untuk menyempurnakan kinerja, tetapi untuk menyepakati dipahami solusi. Biasanya hal ini menyebabkan re-desain dan, setelah beberapa iterasi, dengan yang jauh lebih baik kode.
Jika anda tetap dengan menulis minimal implementasi untuk lulus tes, dan tes menulis yang dipahami oleh banyak orang, anda harus berakhir dengan basis kode di mana hanya tereduksi kompleksitas tetap.
Pertanyaan awal (diparafrasekan) adalah:
Bagaimana arsitek mengelola disengaja kompleksitas dalam proyek-proyek perangkat lunak?
Kecelakaan kompleksitas muncul ketika orang-orang dengan arah yang lebih dari sebuah proyek yang memilih untuk menambahkan teknologi yang satu, dan bahwa strategi keseluruhan proyek's asli arsitek tidak berniat untuk membawa ke dalam proyek. Untuk alasan ini, penting untuk mencatat alasan di balik pilihan dalam strategi.
Disengaja kompleksitas dapat staved oleh kepemimpinan yang menempel pada mereka asli strategi sampai waktu seperti disengaja keberangkatan dari strategi itu rupanya menjadi diperlukan.
Berdasarkan tubuh dari pertanyaan, saya akan ulangi seperti ini:
Bagaimana arsitek mengelola kompleksitas dalam proyek-proyek perangkat lunak?
Ini mengulang lebih apropos ke tubuh pertanyaan, di mana Feynman algoritma itu kemudian dibawa masuk, memberikan konteks yang mengusulkan bahwa untuk arsitek terbaik, ketika dihadapkan dengan masalah, memiliki gestalt dari mana mereka kemudian terampil membangun sebuah solusi, dan bahwa kita tidak bisa berharap untuk belajar ini. Memiliki gestalt pemahaman tergantung pada kecerdasan subjek, dan kesediaan mereka untuk mempelajari fitur-fitur dari arsitektur pilihan yang bisa berada dalam ruang lingkup mereka.
Proses perencanaan untuk proyek ini akan menggunakan pembelajaran organisasi untuk membuat daftar persyaratan proyek, dan kemudian mencoba untuk membangun sebuah daftar dari semua pilihan yang mungkin, dan kemudian mendamaikan pilihan dengan persyaratan. Ahli's gestalt memungkinkan dia untuk melakukan ini dengan cepat, dan mungkin dengan sedikit jelas bekerja, sehingga muncul untuk datang dengan mudah untuk dia.
Saya serahkan kepada anda bahwa itu datang kepadanya karena persiapannya. Untuk memiliki ahli's gestalt membutuhkan keakraban dengan semua pilihan anda, dan pandangan ke depan untuk memberikan solusi yang mudah yang memungkinkan untuk meramalkan masa depan kebutuhan yang ditentukan proyek harus menyediakan, serta fleksibilitas untuk beradaptasi dengan perubahan kebutuhan dari proyek. Feynman's persiapan adalah bahwa ia memiliki pemahaman yang mendalam tentang berbagai pendekatan dalam teori dan terapan matematika dan fisika. Ia bawaan penasaran, dan cukup terang untuk membuat rasa hal-hal yang dia temukan tentang alam sekitar-nya.
Ahli teknologi arsitek akan memiliki rasa ingin tahu, menggambar pada pemahaman yang mendalam tentang dasar-dasar serta eksposur yang luas untuk keragaman teknologi. Dia (atau dia) akan memiliki kebijaksanaan untuk menggambar pada strategi-strategi yang telah sukses di seluruh domain (seperti prinsip-Prinsip dari Unix Programming) dan orang-orang yang berlaku untuk domain tertentu (seperti pola desain dan panduan gaya). Dia mungkin tidak erat luas dari setiap sumber daya, tapi dia akan tahu di mana untuk menemukan sumber daya.
Tingkat pengetahuan, pemahaman, dan kebijaksanaan, yang dapat ditarik dari pengalaman dan pendidikan, tetapi membutuhkan kecerdasan dan aktivitas mental untuk menempatkan bersama-sama gestalt strategis solusi yang bekerja bersama-sama dalam cara yang menghindari kecelakaan dan kompleksitas yang tidak perlu. Hal ini membutuhkan ahli untuk meletakkan dasar-dasar ini bersama-sama; mereka ini adalah para pekerja pengetahuan yang Drucker meramalkan ketika pertama kali menciptakan istilah.
Metode spesifik untuk menjinakkan disengaja kompleksitas dapat menemukan berikut macam sumber.
Berikut prinsip-Prinsip Unix Pemrograman untuk membuat program modular sederhana yang bekerja dengan baik dan kuat dengan interface umum. Mengikuti Pola Desain yang akan membantu anda membangun algoritma kompleks yang tidak lebih kompleks dari yang diperlukan. Berikut Panduan Gaya akan memastikan kode anda lebih mudah dibaca, dipelihara, dan optimal untuk bahasa yang anda kode yang tertulis. Para ahli akan terinternalisasi banyak dari prinsip-prinsip yang terdapat dalam sumber daya tersebut, dan akan mampu untuk menempatkan mereka bersama-sama dalam suatu kesatuan yang mulus fashion.
Ini mungkin pertanyaan yang sulit beberapa tahun yang lalu, tapi IMO tidak lagi sulit untuk menghilangkan disengaja kompleksitas saat ini.
Apa Kent Becksaid tentang dirinya, di beberapa titik: "aku'm tidak seorang programmer yang besar; aku'm hanya seorang programmer yang baik dengan kebiasaan."
Dua hal yang patut menyoroti, IMO: ia menganggap dirinya programmer, bukan seorang arsitek, dan fokusnya adalah pada kebiasaan, bukan pengetahuan.
Feynman's cara memecahkan masalah sulit adalah satu-satunya cara untuk melakukannya. Deskripsi isn't tentu sangat mudah untuk memahami, jadi saya'll membedahnya. Feynman's kepala tidak hanya penuh dengan pengetahuan, itu juga penuh dengan keterampilan untuk menerapkan pengetahuan tersebut. Bila anda memiliki pengetahuan dan keterampilan untuk menggunakannya, memecahkan masalah yang sulit adalah tidak sulit dan tidak mudah. It's satu-satunya hasil yang mungkin.
Ada's benar-benar non-magis cara menulis kode yang bersih, yang tidak mengandung disengaja kompleksitas, dan's kebanyakan mirip dengan apa yang Feynman lakukan: memperoleh semua pengetahuan yang diperlukan, kereta untuk mendapatkan digunakan untuk menempatkan untuk bekerja, bukan hanya karena itu disembunyikan di beberapa sudut otak anda, kemudian menulis kode yang bersih.
Sekarang, banyak programmer aren't bahkan menyadari semua pengetahuan yang diperlukan untuk menulis kode yang bersih. Muda programmer cenderung membuang pengetahuan tentang algoritma dan struktur data, dan yang paling tua programmer cenderung untuk melupakannya. Atau notasi O besar dan kompleksitas analisis. Tua programmer cenderung mengabaikan pola atau kode bau - atau bahkan tidak tahu bahwa mereka ada. Kebanyakan programmer dari setiap generasi, bahkan jika mereka tahu tentang pola, tidak ingat persis kapan harus menggunakan driver dan bagian. Beberapa programmer dari setiap generasi terus-menerus menilai kode mereka terhadap prinsip-prinsip yang SOLID. Banyak programmer campur semua kemungkinan tingkat abstraksi di semua tempat. I'm tidak menyadari salah satu rekan programmer, untuk saat ini, untuk terus-menerus menilai kode nya terhadap stenches dijelaskan oleh Fowler di refactoring buku. Meskipun beberapa proyek yang menggunakan beberapa metrik alat, yang paling banyak digunakan metrik kompleksitas, dari satu jenis atau yang lain, sementara dua lainnya metrik - kopling dan kohesi - untuk sebagian besar diabaikan, bahkan jika mereka sangat penting untuk kode yang bersih. Aspek lain hampir semua orang mengabaikan adalah beban kognitif. Beberapa programmer mengobati unit tes sebagai dokumentasi, dan bahkan lebih sedikit yang menyadari bahwa sulit untuk menulis atau untuk nama unit tes lagi kode bau busuk, yang biasanya menunjukkan buruk anjak piutang. Sebuah minoritas kecil menyadari domain driven design's mantra untuk menjaga kode model dan domain bisnis model seperti dekat satu sama lain, karena perbedaan terikat untuk membuat masalah di jalan. Semua ini perlu dipertimbangkan, sepanjang waktu, jika anda ingin kode anda bersih. Dan banyak lagi yang saya dapat't ingat sekarang.
Anda ingin menulis kode yang bersih? Ada's tidak ada sihir yang diperlukan. Hanya pergi belajar semua yang's diperlukan, kemudian menggunakannya untuk menilai kode's kebersihan, dan refactor sampai anda're bahagia. Dan terus belajar - perangkat lunak masih muda bidang, dan wawasan baru dan pengetahuan yang diperoleh dengan cepat.