Desain untuk perubahan di masa depan atau menyelesaikan masalah yang ada [tertutup]

37

Saat menulis kode atau selama desain Anda mencoba untuk menggeneralisasi masalah pada contoh pertama itu sendiri atau mencoba untuk menyelesaikan masalah yang sangat spesifik.

Saya menanyakan hal ini karena mencoba menyamaratakan masalah cenderung mempersulit hal-hal (yang mungkin tidak perlu) dan di sisi lain akan sangat sulit untuk memperluas solusi spesifik jika ada perubahan dalam persyaratan.

Saya kira solusinya adalah menemukan jalan tengah yang lebih mudah diucapkan daripada dilakukan. Bagaimana Anda mengatasi masalah jenis ini? Jika Anda mulai menggeneralisasikannya pada titik waktu yang Anda tahu bahwa generalisasi sebanyak ini sudah cukup?

Naveen
sumber
Ini menimbulkan pertanyaan yang sangat penting: dapatkah Anda benar-benar memprediksi bagaimana persyaratan akan berubah?
user16764
Banyak orang akan memberi tahu Anda YAGNI. Mereka adalah orang-orang yang Anda benci ketika Anda harus mengambil alih pekerjaan mereka.
Martin Maat

Jawaban:

60

Terlalu sering ketika Anda mencoba merancang untuk masa depan, prediksi Anda tentang kebutuhan masa depan ternyata salah. Biasanya lebih baik untuk refactor ketika Anda benar-benar tahu bagaimana kebutuhan telah berubah daripada mendesain ulang sistem Anda pada hari pertama. Pada saat yang sama, jangan tembak kaki Anda juga. Tentu saja ada jalan tengah, dan mengetahui di mana itu lebih merupakan seni daripada sains.

Untuk merebusnya menjadi satu aturan praktis: lebih sedikit lebih banyak.


sumber
17
+1 "Masa depan tidak seperti dulu."
Dan Lyons
19

Apakah Anda terbiasa dengan Agile? Salah satu prinsip besar Agile adalah YAGNI . Saya menemukan itu cara terbaik untuk mendekati sesuatu.

"Anda tidak akan membutuhkannya" ... adalah prinsip pemrograman ekstrem (XP) yang menyatakan seorang programmer tidak boleh menambahkan fungsionalitas sampai dianggap perlu. Ron Jeffries menulis, "Selalu laksanakan hal-hal ketika Anda benar-benar membutuhkannya, jangan pernah ketika Anda hanya meramalkan bahwa Anda membutuhkannya."

... YAGNI adalah prinsip di balik praktik XP "melakukan hal paling sederhana yang mungkin bisa berhasil" (DTSTTCPW). Ini dimaksudkan untuk digunakan dalam kombinasi dengan beberapa praktik lain, seperti refactoring berkelanjutan, pengujian unit otomatis kontinu dan integrasi berkelanjutan . Digunakan tanpa refactoring terus menerus, ini dapat menyebabkan kode berantakan dan pengerjaan ulang besar-besaran. Refactoring berkelanjutan pada gilirannya bergantung pada tes unit otomatis sebagai jaring pengaman (untuk mendeteksi bug yang tidak terduga) dan integrasi berkelanjutan untuk mencegah masalah integrasi yang lebih luas ...

YAGNI tidak diterima secara universal sebagai prinsip yang valid, bahkan dalam kombinasi dengan praktik pendukung. Kebutuhan untuk menggabungkannya dengan praktik pendukung, daripada menggunakannya sendiri, adalah bagian dari definisi asli XP ...

Matt Grande
sumber
3
Sementara saya setuju dengan YAGNI kurang lebih, saya tidak dapat menemukannya dalam prinsip-prinsip lincah: agilemanifesto.org/principles.html
Jens Schauder
"Kesederhanaan - seni memaksimalkan jumlah pekerjaan yang tidak dilakukan - sangat penting," akan berlaku untuk YAGNI dan beberapa praktik lincah lainnya.
tvanfosson
1
Meskipun tidak secara khusus mengatakan "YAGNI" dalam manifesto, saya pikir mereka sangat sejalan satu sama lain.
2
@Jens dan @Matt, YAGNI, dalam Agile melalui XP yang dibundel sebagai metodologi "gesit". Sebagaimana disebutkan dalam artikel Wikipedia prinsip YAGNI dikembangkan oleh Ron Jeffries sebagai bagian dari praktik inti XP.
1
Mungkin benar bahwa YAGNI adalah idiom pengembang, tetapi TDD adalah yang menerapkan dilema ini dengan cukup baik. Pada langkah di mana dikatakan bahwa Anda hanya harus menulis kode yang cukup untuk lulus ujian dan tidak lebih. Dan TDD adalah bagian dari gesit.
Robert Koritnik
12

Ini mungkin salah satu bagian paling sulit dari pengembangan perangkat lunak karena Anda harus melewati batas antara "YAGNI" dan "PYIAC" (Paint Yourself Into A Corner).

Sangat mudah untuk mengatakan "jangan menulis fitur kecuali Anda membutuhkannya". Bagian yang sulit adalah merancang kode Anda sehingga Anda dapat dengan mudah menambahkan fitur nanti ketika Anda membutuhkannya.

Kuncinya adalah untuk dapat merancang arsitektur yang dapat dikembangkan di mana Anda tidak menulis kode lebih dari yang Anda butuhkan saat ini. Kemampuan untuk melakukan ini dengan baik benar-benar berasal dari banyak pengalaman (dan rasa sakit).

17 dari 26
sumber
7

Saya menghabiskan waktu di muka untuk memikirkan arah umum desain - tidak terlalu banyak, tetapi cukup untuk membuat sketsa gambaran tingkat tinggi. Saya kemudian mengikuti metodologi tangkas berbasis cerita menggunakan TDD untuk mengembangkan solusi untuk cerita individu. Karena saya menerapkan melalui TDD, saya mengingat ikhtisar tingkat tinggi saya dan (a) mengarahkan implementasi khusus saya untuk mengikuti ikhtisar tingkat tinggi atau (b) refactor (dan meningkatkan) pemahaman / arahan tingkat tinggi saya berdasarkan apa yang saya pelajari selama pengujian / implementasi.

Saya pikir itu adalah kesalahan untuk tidak melakukan perencanaan dimuka, tetapi mungkin yang lebih besar untuk melakukan terlalu banyak. Sebisa mungkin saya ingin memberi saya pengalaman memandu saya dalam gambaran besar dan kemudian membiarkan desain tumbuh secara organik di sepanjang garis yang telah saya paparkan dalam pikiran saya tentang bagaimana aplikasi akan dikembangkan. Menggunakan TDD saya menemukan bahwa desain itu sendiri dipaksa menjadi prinsip-prinsip desain yang lebih baik (dipisahkan, tanggung jawab tunggal, dll) dan lebih mudah ditempa sehubungan dengan perubahan daripada jika saya mencoba untuk menyusun keseluruhan dan menyesuaikan pengembangan ke dalamnya.

tvanfosson
sumber
3

Desain yang bagus mengakomodasi perubahan di masa depan dan pasti layak untuk dilakukan. Pertimbangkan sistem operasi UNIX dan "semuanya adalah filosofi file". Keputusan desain itu diambil bukan untuk memenuhi beberapa kebutuhan mendesak tetapi dengan pandangan untuk persyaratan di masa depan. Seseorang ngeri membayangkan seperti apa sistem operasi yang didasarkan pada desain "gesit" itu.


sumber
2

Apa yang Anda coba selesaikan berkaitan dengan penggunaan kembali (yaitu generalisasi masalah yang Anda hadapi sekarang sehingga Anda dapat menggunakan kembali pekerjaan (kode) di masa mendatang). Saya sudah mengatakannya sebelumnya dan saya akan menautkannya lagi.

Saya pikir saya pernah mendengar orang lain mengatakan sesuatu dengan efek:

Saya memecahkan masalah pertama kali. Ketika saya mengulangi solusi saya pertama kali, saya mencatatnya. Ketika saya ulangi lagi, saya refactor.

Jason Punyon
sumber
2

Desain untuk "sekarang +1". Itu berarti, selesaikan masalah langsung yang ada, dan bangun fungsionalitas yang cukup sehingga pada saat mereka meminta perubahan, Anda sudah menyelesaikannya setengah jalan (atau lebih) dan memiliki pilihan a) menyelesaikannya segera dan refactoring nanti, atau b) menyelesaikan "sekarang +1" lagi (dengan setengah "sekarang" selesai)

Ini tergantung proyek, dan, singkatnya, pengalaman akan mengajarkan Anda apa "+1" itu.

Richard Levasseur
sumber
1

Filosofi YAGNI , Kamu Tidak Akan Membutuhkannya, dapat diringkas dengan (dari artikel):

Menurut mereka yang menganjurkan pendekatan YAGNI, godaan untuk menulis kode yang tidak perlu saat ini, tetapi mungkin di masa depan, memiliki kelemahan sebagai berikut:

  • Waktu yang dihabiskan diambil dari menambah, menguji atau meningkatkan fungsionalitas yang diperlukan.
  • Fitur baru harus didebug, didokumentasikan, dan didukung.
  • Setiap fitur baru memberikan batasan pada apa yang dapat dilakukan di masa depan, sehingga fitur yang tidak perlu sekarang dapat mencegah penerapan fitur yang diperlukan nanti.
  • Sampai fitur tersebut benar-benar diperlukan, sulit untuk sepenuhnya menentukan apa yang harus dilakukan dan mengujinya. Jika fitur baru tidak didefinisikan dan diuji dengan benar, mungkin tidak berfungsi dengan benar, bahkan jika pada akhirnya diperlukan.
  • Ini menyebabkan kode mengasapi; perangkat lunak menjadi lebih besar dan lebih rumit.
  • Kecuali ada spesifikasi dan semacam kontrol revisi, fitur tersebut mungkin tidak diketahui oleh programmer yang dapat memanfaatkannya.
  • Menambahkan fitur baru dapat menyarankan fitur baru lainnya. Jika fitur-fitur baru ini diimplementasikan juga, ini dapat mengakibatkan efek bola salju menuju creeping featureism.
JeffH
sumber
0

Saya sangat percaya merancang untuk masalah yang dihadapi dan tidak meniup desain Anda dengan mencoba menebak semua kasus yang harus Anda penuhi karena "suatu hari nanti kita mungkin membutuhkannya".

Pada dasarnya, diberikan daftar persyaratan khusus, desain yang bertentangan, namun, ini tidak berarti bahwa Anda tidak boleh:

  • jadikan aspek-aspek desain Anda lebih mudah dikonfigurasi daripada pengkodean keras aspek-aspek itu dalam solusi Anda. Baik melalui parameter yang diteruskan saat runtime atau melalui konfigurasi eksternal yang dibaca saat startup (atau setelah HUP'ing).
  • renda kode Anda dengan angka ajaib,
  • hindari melihat-lihat apakah ada sesuatu yang sudah ditulis yang dapat Anda gunakan kembali, mungkin setelah mengadaptasi solusi yang ada untuk memberikan pendekatan yang cocok untuk situasi yang ada serta untuk persyaratan baru.

Masalah utama dengan merancang untuk "kemungkinan masa depan" adalah bahwa Anda selalu hanya menebak. Mungkin membuat tebakan yang terpelajar, tetapi "ketika dorongan datang untuk mendorong" itu masih hanya serangkaian tebakan.

Dengan melakukan ini, Anda juga memiliki kemungkinan yang sangat nyata untuk memeras solusi Anda agar sesuai dengan kasus umum (s) daripada menyelesaikan masalah spesifik yang dihadapi sebagaimana ditentukan oleh persyaratan yang diketahui Anda.

Apa yang dikatakannya? "Ketika semua yang kamu miliki adalah palu, semuanya mulai terlihat seperti paku."

Saya berharap memiliki satu pound untuk setiap kali saya mendengar seseorang berkata, "Tapi itu solusi yang lebih mudah beradaptasi untuk kasus-kasus umum yang mungkin kita lihat di masa depan."

Rob Wells
sumber