Haruskah kita menghindari menggunakan pola desain dalam proyek yang terus berubah?

32

Seorang teman saya bekerja untuk sebuah perusahaan kecil di sebuah proyek yang dibenci oleh setiap pengembang: dia terdesak untuk melepaskan secepat mungkin, dia satu-satunya yang tampaknya peduli dengan utang teknis, pelanggan tidak memiliki latar belakang teknis, dll.

Dia menceritakan kepada saya sebuah kisah yang membuat saya berpikir tentang kesesuaian pola desain dalam proyek-proyek seperti ini. Begini ceritanya.

Kami harus memajang produk di berbagai tempat di situs web. Misalnya, manajer konten dapat melihat produk, tetapi juga pengguna akhir atau mitra melalui API.

Kadang-kadang, informasi hilang dari produk: misalnya, banyak dari mereka tidak memiliki harga ketika produk baru saja dibuat, tetapi harga belum ditentukan. Beberapa tidak memiliki deskripsi (deskripsi menjadi objek yang kompleks dengan riwayat modifikasi, konten yang dilokalkan, dll.). Beberapa kekurangan informasi pengiriman.

Terinspirasi oleh bacaan saya baru-baru ini tentang pola desain, saya pikir ini adalah kesempatan yang bagus untuk menggunakan pola Obyek Null yang ajaib . Jadi saya melakukannya, dan semuanya lancar dan bersih. Seseorang hanya perlu menelepon product.Price.ToString("c")untuk menampilkan harga, atau product.Description.Currentuntuk menunjukkan deskripsi; tidak diperlukan hal-hal bersyarat. Hingga, suatu hari, pemangku kepentingan diminta untuk menampilkannya secara berbeda di API, dengan memiliki nulldi JSON. Dan juga berbeda untuk pengelola konten dengan menunjukkan "Harga [Ubah] tidak ditentukan". Dan saya harus membunuh pola Objek Null tercinta saya, karena tidak perlu lagi.

Dengan cara yang sama, saya harus menghapus beberapa pabrik abstrak dan beberapa pembangun, saya akhirnya mengganti pola Fasad saya yang indah dengan panggilan langsung dan jelek, karena antarmuka yang mendasarinya berubah dua kali per hari selama tiga bulan, dan bahkan Singleton meninggalkan saya ketika persyaratan mengatakan bahwa objek yang bersangkutan harus berbeda tergantung pada konteksnya.

Pekerjaan lebih dari tiga minggu terdiri dari menambahkan pola desain, lalu merobeknya satu bulan kemudian, dan kode saya akhirnya menjadi spageti yang cukup untuk tidak mungkin dipertahankan oleh siapa pun, termasuk saya. Bukankah lebih baik tidak pernah menggunakan pola itu sejak awal?

Memang, saya harus bekerja sendiri pada jenis-jenis proyek di mana persyaratan berubah terus-menerus, dan ditentukan oleh orang-orang yang tidak benar-benar memikirkan kohesi atau koherensi produk. Dalam konteks ini, tidak masalah seberapa gesitnya Anda, Anda akan datang dengan solusi elegan untuk suatu masalah, dan ketika Anda akhirnya mengimplementasikannya, Anda belajar bahwa persyaratannya berubah secara drastis, sehingga solusi elegan Anda tidak cocok lebih lama lagi.

Apa yang akan menjadi solusi dalam kasus ini?

  • Tidak menggunakan pola desain, berhenti berpikir, dan menulis kode secara langsung?

    Akan menarik untuk melakukan pengalaman di mana tim menulis kode secara langsung, sementara yang lain berpikir dua kali sebelum mengetik, mengambil risiko harus membuang desain asli beberapa hari kemudian: siapa tahu, mungkin kedua tim akan memiliki hutang teknis yang sama. Dengan tidak adanya data seperti itu, saya hanya akan menegaskan bahwa rasanya tidak benar untuk mengetik kode tanpa berpikir sebelumnya ketika mengerjakan proyek 20 man-month.

  • Pertahankan pola desain yang tidak masuk akal lagi, dan coba tambahkan lebih banyak pola untuk situasi yang baru dibuat?

    Sepertinya ini juga tidak benar. Pola digunakan untuk menyederhanakan pemahaman kode; terlalu banyak pola, dan kode akan berantakan.

  • Mulai memikirkan desain baru yang mencakup persyaratan baru, lalu perlahan-lahan memperbaiki desain lama menjadi yang baru?

    Sebagai ahli teori dan orang yang menyukai Agile, saya benar-benar menyukainya. Dalam praktiknya, ketika Anda tahu bahwa Anda harus kembali ke papan tulis setiap minggu dan mengulang kembali sebagian besar desain sebelumnya dan bahwa pelanggan tidak memiliki cukup dana untuk membayar Anda untuk itu, juga tidak cukup waktu untuk menunggu. , ini mungkin tidak akan berhasil.

Jadi, ada saran?

Arseni Mourzenko
sumber
43
Saya pikir ini adalah dilema yang salah. Menurut pengakuan teman Anda sendiri, kode sekarang menjadi sepiring spageti yang tidak dapat dipelihara. Itu bukan kesalahan pola perangkat lunak; itu adalah ketidakmampuan teman Anda untuk menggunakan pola-pola itu dengan benar, dengan cara yang meningkatkan rawatan, bukan menguranginya. Ketika saya dapat memberikan contoh spesifik, saya akan memposting jawaban yang tepat.
Robert Harvey
5
Juga, FWIW, setiap pelanggan yang tidak memiliki toleransi untuk biaya drifting mungkin tidak boleh melakukan Agile, kecuali ada biaya tambahan untuk biaya pemindahan persyaratan.
Robert Harvey
5
Saya menduga bahwa tanpa pola desain, kode akan mencapai keadaan yang tidak dapat dipastikan lebih cepat
Steven A. Lowe
28
Pertanyaan ini tidak masuk akal. Satu-satunya cara untuk "menghindari pola desain" adalah tidak menulis perangkat lunak sama sekali. Hal-hal seperti "Pola XYZ" hanyalah nama-nama yang diberikan untuk strategi pengkodean umum agar kami programmer dapat menyampaikan informasi dan saran tentang struktur kode dan pilihan satu sama lain dengan lebih nyaman. Setiap pilihan desain dalam kode Anda dapat diberi nama dan disebut "pola desain", meskipun belum tentu yang dikenal luas (kecuali, saya kira, Anda bangga dengan desain unik Anda dan cukup termotivasi untuk memberikan nama dan blog tentang itu atau sesuatu).
Jason C
9
Yaitu Anda dapat menghindari menyebut kaki Anda "kaki" tetapi Anda masih memiliki kaki itu, hanya saja lebih sulit untuk membicarakannya dengan seseorang jika Anda tidak menyebutnya "kaki". Anda mungkin berpikir Anda "menghindari pola desain" tetapi jika Anda datang dengan desain yang layak yang berfungsi kemudian melangkah mundur dan melihatnya, Anda mungkin akan menemukan bahwa desain Anda akhirnya cocok dengan salah satu pola yang umum disebut, apakah Anda menyebutnya begitu atau tidak.
Jason C

Jawaban:

86

Saya melihat beberapa asumsi yang salah dalam pertanyaan ini:

  • kode dengan pola desain, meskipun diterapkan dengan benar, membutuhkan lebih banyak waktu untuk diimplementasikan daripada kode tanpa pola itu.

Pola desain tidak ada akhirnya, mereka harus melayani Anda, bukan sebaliknya. Jika pola desain tidak membuat kode lebih mudah untuk diimplementasikan, atau setidaknya evolvable lebih baik (itu berarti: lebih mudah diadaptasi dengan mengubah persyaratan), maka pola tersebut meleset dari tujuannya. Jangan menerapkan pola saat mereka tidak membuat "hidup" lebih mudah bagi tim. Jika pola objek Null baru melayani teman Anda saat ia menggunakannya, maka semuanya baik-baik saja. Jika itu harus dihilangkan nanti, maka ini bisa juga ok. Jika pola objek Null memperlambat implementasi (benar) ke bawah, maka penggunaannya salah. Catatan, dari bagian cerita ini orang tidak dapat menyimpulkan penyebab "kode spageti" sejauh ini.

  • pelanggan harus disalahkan karena dia tidak memiliki latar belakang teknis dan tidak peduli tentang kohesi atau koherensi produk

Itu bukan pekerjaannya atau kesalahannya! Tugas Anda adalah peduli tentang kohesi dan koherensi. Ketika persyaratan berubah dua kali sehari, solusi Anda tidak boleh mengorbankan kualitas kode. Beri tahu pelanggan berapa lama, dan jika Anda pikir Anda perlu lebih banyak waktu untuk mendapatkan desain yang "benar", maka tambahkan margin keamanan yang cukup besar untuk estimasi apa pun. Terutama ketika Anda memiliki pelanggan yang mencoba menekan Anda, gunakan "Prinsip Scotty" . Dan ketika berdebat dengan pelanggan non-teknis tentang upaya tersebut, hindari istilah seperti "refactoring", "unit-tes", "pola desain" atau "dokumentasi kode" - hal-hal yang tidak dia pahami dan mungkin anggap sebagai "tidak perlu" omong kosong "karena dia tidak melihat nilai di dalamnya. atau setidaknya dapat dimengerti oleh pelanggan (fitur, sub-fitur, perubahan perilaku, dokumen pengguna, perbaikan kesalahan, pengoptimalan kinerja, dan sebagainya).

  • solusi untuk persyaratan perubahan cepat adalah dengan cepat mengubah kode

Jujur, jika "antarmuka yang mendasarinya berubah dua kali per hari selama tiga bulan", maka solusinya seharusnya tidak bereaksi dengan mengubah kode dua kali sehari. Solusi sebenarnya adalah bertanya mengapa persyaratan sering berubah dan apakah mungkin untuk melakukan perubahan pada bagian proses itu. Mungkin beberapa analisis dimuka akan membantu. Mungkin antarmuka terlalu luas karena batas antar komponen dipilih salah. Kadang-kadang membantu untuk meminta informasi lebih lanjut mengenai bagian mana dari persyaratan yang stabil, dan mana yang masih dalam diskusi (dan sebenarnya menunda implementasi untuk hal-hal yang sedang dibahas). Dan kadang-kadang beberapa orang hanya harus "ditendang dalam keledai mereka" karena tidak mengubah pikiran mereka dua kali sehari.

Doc Brown
sumber
30
+1 - Anda tidak dapat memecahkan masalah orang dengan solusi teknis.
Telastyn
1
+1, tetapi "atau setidaknya evolvable yang lebih baik (itu berarti: lebih mudah disesuaikan dengan perubahan persyaratan)" - Saya memenuhi syarat dengan persyaratan yang berubah secara wajar , bukan?
Fuhrmanator
1
@ Fuhrmanator: Saya pikir ini sulit untuk dibahas secara umum. IMHO jelas bahwa tidak ada pola desain yang akan membantu Anda ketika persyaratan pertama Anda adalah "kami membutuhkan pengolah kata" dan ini berubah menjadi "kami membutuhkan simulator penerbangan". Untuk perubahan persyaratan yang tidak terlalu drastis, tidak selalu mudah untuk memutuskan apa yang akan membantu Anda menjaga perangkat lunak Anda terus berkembang. Yang terbaik adalah IMHO untuk tidak menerapkan terlalu banyak pola, tetapi beberapa prinsip - terutama prinsip SOLID dan YAGNI. Dan saya setuju 100% dengan Telastyn- ketika persyaratan terlalu sering berubah, itu mungkin bukan masalah teknis.
Doc Brown
4
+1 - "Jujur, jika 'antarmuka yang mendasarinya berubah dua kali per hari selama tiga bulan', maka solusinya seharusnya tidak bereaksi dengan mengubah kode dua kali sehari. Solusi sebenarnya adalah bertanya mengapa persyaratan sering berubah, dan jika adalah mungkin untuk melakukan perubahan pada bagian proses itu. "Jika Anda terus-menerus diberikan arahan baru, yang terbaik adalah duduk bersama semua pemangku kepentingan dan menegaskan kembali apa harapannya. Atasi perbedaan Anda, dan semoga tidak menyia-nyiakan waktu dan uang semua orang dengan memberikan proyek tujuan yang lebih jelas.
krillgar
1
@Cornelius Doc Brown berkata sulit tanpa konkret. Persyaratan dari pengolah kata ke simulator penerbangan tidak masuk akal; tidak ada pola desain yang membantu. Ada banyak area abu-abu di antara contohnya dan, katakanlah, menambahkan format file baru ke fungsi Simpan pengolah kata (yang sangat masuk akal). Tanpa spesifik, sulit untuk didiskusikan. Juga, bukan itu yang tidak ingin diubah. Perubahan seperti itu sulit, jika Anda sudah membuat pilihan desain sejak dini berdasarkan persyaratan. Pengolah kata vs. sim penerbangan merupakan contoh pilihan awal yang bagus.
Fuhrmanator
43

Pendapat saya yang sederhana adalah bahwa Anda tidak boleh menghindari atau tidak-menghindari menggunakan pola desain.

Pola desain hanyalah solusi terkenal dan tepercaya untuk masalah umum, yang diberi nama. Mereka tidak berbeda secara teknis daripada solusi atau desain lain yang dapat Anda pikirkan.

Saya pikir akar masalahnya mungkin karena teman Anda berpikir dalam hal "menerapkan atau tidak menerapkan pola desain", alih-alih berpikir dalam hal "apa solusi terbaik yang dapat saya pikirkan, termasuk tetapi tidak terbatas pada pola Aku tahu".

Mungkin pendekatan ini membuatnya menggunakan pola sebagian atau buatan, di tempat-tempat yang bukan milik mereka. Dan inilah yang menyebabkan kekacauan.

Aviv Cohn
sumber
13
+1 "Pola desain hanyalah solusi terkenal dan tepercaya untuk masalah umum, yang diberi nama. Mereka tidak berbeda secara teknis daripada solusi atau desain lain yang dapat Anda pikirkan." Persis. Orang-orang begitu terperangkap dalam pola desain yang dinamai sehingga mereka lupa ini tidak lebih dari nama yang diberikan untuk berbagai strategi untuk memudahkan kita programmer untuk saling berkomunikasi tentang kode kita dan pilihan desain kita. Sikap ini sangat sering dikaitkan dengan upaya untuk memaksa "pola" yang tidak tepat pada masalah yang tidak selalu menguntungkan - kekacauan besar.
Jason C
14

Dalam contoh Anda menggunakan pola Obyek Null, saya percaya itu akhirnya gagal karena memenuhi kebutuhan programmer dan bukan kebutuhan pelanggan. Pelanggan perlu menampilkan harga dalam bentuk yang sesuai dengan konteksnya. Programmer perlu menyederhanakan beberapa kode tampilan.

Jadi, ketika pola desain tidak memenuhi persyaratan, apakah kita mengatakan bahwa semua pola desain adalah buang-buang waktu atau kita mengatakan bahwa kita memerlukan pola desain yang berbeda?

BobDalgleish
sumber
9

Akan muncul kesalahan lebih untuk menghapus objek pola, daripada menggunakannya. Dalam desain awal, Objek Null tampaknya telah memberikan solusi untuk suatu masalah. Ini mungkin bukan solusi terbaik.

Menjadi satu-satunya orang yang mengerjakan proyek memberi Anda kesempatan untuk mengalami seluruh proses pengembangan. Kerugian besar adalah tidak memiliki seseorang untuk menjadi mentor Anda. Meluangkan waktu untuk belajar dan menerapkan praktik terbaik atau lebih baik cenderung membuahkan hasil dengan cepat. Caranya adalah mengidentifikasi latihan mana yang harus dipelajari kapan.

Referensi rantai dalam bentuk produk.Harga.toString ('c') melanggar Hukum Demeter . Saya telah melihat segala macam masalah dengan praktik ini, banyak yang berhubungan dengan nol. Metode seperti product.displayPrice ('c') dapat menangani harga nol secara internal. Demikian juga product.Description.Current dapat ditangani oleh product.displayDescription (), product.displayCurrentDescription (). atau product.diplay ('Lancar').

Menangani persyaratan baru untuk manajer dan penyedia konten perlu ditangani dengan menanggapi konteks. Ada berbagai pendekatan yang bisa digunakan. Metode pabrik dapat menggunakan kelas produk yang berbeda tergantung pada kelas pengguna mereka akan ditampilkan. Pendekatan lain adalah metode tampilan kelas produk untuk membangun data yang berbeda untuk pengguna yang berbeda.

Kabar baiknya adalah teman Anda menyadari bahwa segala sesuatunya menjadi tidak terkendali. Mudah-mudahan, dia memiliki kode dalam kontrol revisi. Ini akan memungkinkan dia untuk mundur dari keputusan yang buruk, yang akan selalu dia buat. Bagian dari pembelajaran adalah mencoba pendekatan yang berbeda, beberapa di antaranya akan gagal. Jika dia bisa menangani beberapa bulan ke depan, dia mungkin menemukan pendekatan yang menyederhanakan hidupnya dan membersihkan spageti. Dia bisa mencoba memperbaiki satu hal setiap minggu.

BillThor
sumber
2
Ini juga dapat mengindikasikan lebih lanjut, melihat bahwa Anda "harus" melanggar hukum Demeter, bahwa model yang digunakan di permukaan tidak sesuai. Mengapa "model tampilan" (digunakan dalam arti longgar) tidak hanya memiliki deskripsi untuk ditampilkan? (Yaitu mengapa ada lebih dari sekedar desain saat ini di tingkat UI?) Lapisan bisnis dapat menyiapkan objek yang diisi dengan tepat ke lapisan UI yang sudah memiliki konten yang berbeda tergantung pada apakah itu manajer atau tidak.
Cornelius
7

Pertanyaannya tampaknya salah pada banyak hal. Tapi yang mencolok adalah:

  • Untuk Pola Objek Null yang Anda sebutkan, setelah persyaratan berubah, Anda mengubah sedikit kode. Itu baik-baik saja tetapi itu tidak berarti Anda 'membunuh' Pola Obyek Null (btw, berhati-hatilah dengan kata-kata Anda, ini terdengar terlalu ekstrim, beberapa orang yang terlalu paranoid tidak akan melihat ini sebagai lucu sama sekali).

Banyak orang mengatakan dengan benar, pola desain sangat banyak tentang pelabelan dan penamaan praktik umum. Jadi pikirkan tentang kemeja, kemeja memiliki kerah, untuk beberapa alasan Anda melepas kerah atau bagian dari kerah. Penamaan dan pelabelan berubah, tetapi pada dasarnya masih merupakan kemeja. Inilah yang terjadi di sini, perubahan kecil pada detail yang tidak berarti Anda telah 'membunuh' pola itu. (lagi-lagi pikirkan kata-kata ekstrem)

  • Desain yang Anda bicarakan buruk karena ketika perubahan persyaratan datang sebagai hal-hal kecil, Anda membuat perubahan desain strategis besar-besaran di semua tempat. Kecuali jika masalah bisnis tingkat tinggi berubah, Anda tidak dapat membenarkan membuat perubahan desain besar-besaran.

Dari pengalaman saya, ketika persyaratan kecil datang, Anda hanya perlu mengubah sebagian kecil basis kode. Beberapa mungkin agak sedikit macet, tetapi tidak ada yang terlalu serius untuk secara substansial mempengaruhi kemampuan pemeliharaan atau keterbacaan dan sering beberapa baris komentar untuk menjelaskan bagian yang diretas akan cukup. Ini adalah praktik yang sangat umum juga.

InformedA
sumber
7

Mari kita berhenti sejenak dan melihat masalah mendasar di sini - Merancang sistem di mana model arsitektur terlalu digabungkan dengan fitur tingkat rendah dalam sistem, menyebabkan arsitektur sering rusak dalam proses pengembangan.

Saya pikir kita harus ingat bahwa penggunaan arsitektur dan pola desain yang terkait dengannya harus diletakkan pada level yang sesuai, dan bahwa analisis level apa yang tepat tidak sepele. Di satu sisi, Anda dapat dengan mudah menjaga arsitektur sistem Anda pada tingkat yang terlalu tinggi dengan hanya kendala yang sangat mendasar seperti "MVC" atau sejenisnya, yang dapat menyebabkan peluang yang terlewatkan seperti dalam panduan dan pengungkitan kode yang jelas, dan di mana kode spageti dapat dengan mudah berkembang di semua ruang bebas itu.

Di sisi lain, Anda mungkin juga mendesain sistem Anda secara berlebihan, seperti dalam menetapkan batasan pada level terperinci, di mana Anda menganggap Anda dapat mengandalkan kendala yang pada kenyataannya lebih mudah berubah daripada yang Anda harapkan, terus-menerus memecahkan kendala Anda dan memaksa Anda untuk terus-menerus merombak dan membangun kembali, hingga Anda mulai putus asa.

Perubahan persyaratan untuk suatu sistem akan selalu ada, pada tingkat yang lebih rendah atau lebih besar. Dan manfaat potensial dari penggunaan arsitektur dan pola desain akan selalu ada, jadi sebenarnya tidak ada pertanyaan untuk menggunakan pola desain atau tidak, tetapi pada level apa Anda harus menggunakannya.

Ini mengharuskan Anda tidak hanya untuk memahami persyaratan saat ini dari sistem yang diusulkan, tetapi juga untuk mengidentifikasi aspek-aspek apa yang dapat dilihat sebagai sifat-sifat inti yang stabil dari sistem, dan sifat-sifat apa yang mungkin akan berubah selama pengembangan.

Jika Anda merasa harus terus-menerus bertarung dengan kode spageti yang tidak terorganisir, Anda mungkin tidak cukup arsitektur, atau pada tingkat yang lebih tinggi. Jika Anda menemukan bahwa arsitektur Anda sering rusak, Anda mungkin melakukan arsitektur yang terlalu rinci.

Penggunaan pola arsitektur dan desain bukanlah sesuatu yang Anda bisa "melapisi" suatu sistem, seperti jika Anda akan melukis meja. Mereka adalah teknik yang harus diterapkan secara serius, pada tingkat di mana kendala yang Anda butuhkan memiliki kemungkinan tinggi untuk menjadi stabil, dan di mana teknik-teknik ini sebenarnya sepadan dengan kesulitan pemodelan arsitektur dan menerapkan kendala aktual / arsitektur / pola sebagai kode.

Terkait dengan masalah arsitektur yang terlalu terperinci, Anda dapat juga berupaya keras dalam arsitektur di mana arsitektur tersebut tidak memberikan banyak nilai. Lihat arsitektur berbasis risiko untuk referensi, saya suka buku ini - Cukup Arsitektur Perangkat Lunak , mungkin Anda juga akan melakukannya.

Edit

Menjelaskan jawaban saya sejak saya menyadari bahwa saya sering menyatakan diri saya sebagai "arsitektur terlalu banyak", di mana saya benar-benar berarti "arsitektur terlalu detail", yang tidak persis sama. Arsitektur yang terlalu detail mungkin sering dianggap sebagai arsitektur "terlalu banyak", tetapi bahkan jika Anda menjaga arsitektur pada tingkat yang baik dan menciptakan sistem yang paling indah yang pernah dilihat manusia, ini mungkin masih terlalu banyak upaya pada arsitektur jika prioritasnya adalah pada fitur dan waktu ke pasar.

Alex
sumber
+1 Ini adalah pemikiran yang sangat baik tentang tingkat yang sangat tinggi. Saya pikir Anda harus melihat dalam suatu sistem, tetapi seperti yang Anda katakan, itu membutuhkan banyak pengalaman dalam desain perangkat lunak.
Samuel
4

Teman Anda tampaknya menghadapi banyak headwinds berdasarkan anekdotnya. Sangat disayangkan, dan bisa menjadi lingkungan yang sangat sulit untuk bekerja. Meskipun kesulitan, dia berada di jalur yang benar dalam menggunakan pola untuk membuat hidupnya lebih mudah, dan sangat disayangkan dia meninggalkan jalan itu. Kode spageti adalah hasil akhir.

Karena ada dua bidang masalah yang berbeda, teknis dan interpersonal, saya akan membahas masing-masing secara terpisah.

Interpersonal

Perjuangan yang dialami teman Anda adalah dengan persyaratan yang berubah dengan cepat, dan bagaimana hal itu memengaruhi kemampuannya untuk menulis kode yang dapat dipertahankan. Saya pertama-tama akan mengatakan bahwa persyaratan berubah dua kali sehari, setiap hari untuk jangka waktu yang lama adalah masalah yang lebih besar, dan memiliki harapan implisit yang tidak realistis. Persyaratan berubah lebih cepat daripada kode dapat berubah. Kami tidak dapat mengharapkan kode, atau programmer, untuk mengikuti. Laju perubahan yang cepat ini merupakan gejala dari konsepsi yang tidak lengkap dari produk yang diinginkan pada tingkat yang lebih tinggi. Ini adalah sebuah masalah. Jika mereka tidak tahu apa yang sebenarnya mereka inginkan, mereka akan membuang banyak waktu dan uang untuk tidak pernah mendapatkannya.

Mungkin baik untuk menetapkan batasan untuk perubahan. Kelompokkan bersama-sama perubahan menjadi set setiap dua minggu, kemudian bekukan selama dua minggu saat mereka diimplementasikan. Buat daftar baru untuk periode dua minggu ke depan. Saya merasa beberapa perubahan ini tumpang tindih atau bertentangan (ex, bolak-balik antara dua opsi). Ketika perubahan datang dengan cepat dan marah, mereka semua memiliki prioritas utama. Jika Anda membiarkan mereka terakumulasi dalam daftar, Anda dapat bekerja dengan mereka untuk mengatur dan memprioritaskan apa yang paling penting untuk memaksimalkan upaya dan produktivitas. Mereka mungkin melihat bahwa beberapa perubahan mereka konyol atau kurang penting, memberi teman Anda ruang bernapas.

Masalah ini seharusnya tidak membuat Anda berhenti menulis kode yang baik. Kode buruk menyebabkan masalah yang lebih buruk. Mungkin perlu waktu untuk memperbaiki dari satu solusi ke solusi yang lain, tetapi fakta bahwa dimungkinkan menunjukkan manfaat dari praktik pengkodean yang baik melalui pola dan prinsip.

Dalam lingkungan yang sering berubah, utang teknis akan jatuh tempo di beberapa titik. Jauh lebih baik untuk melakukan pembayaran ke arah itu daripada menyerah dan menunggu sampai menjadi terlalu besar untuk diatasi. Jika sebuah pola tidak lagi berguna, refactor saja, tetapi jangan kembali ke cara pengkodean koboi.

Teknis

Teman Anda tampaknya memiliki pemahaman yang baik tentang pola desain dasar. Objek kosong adalah pendekatan yang baik untuk masalah yang dia hadapi. Sebenarnya, itu masih merupakan pendekatan yang baik. Di mana ia tampaknya memiliki tantangan adalah memahami prinsip-prinsip di balik pola, mengapa hal itu terjadi. Kalau tidak, saya tidak percaya dia akan meninggalkan pendekatannya.

(Berikut ini adalah serangkaian solusi teknis yang tidak diminta dalam pertanyaan awal, tetapi itu menunjukkan bagaimana kami dapat mematuhi pola untuk tujuan ilustrasi.)

Prinsip di balik objek nol adalah ide merangkum apa yang bervariasi . Kami menyembunyikan perubahan apa sehingga kami tidak harus menghadapinya di tempat lain. Di sini, objek nol adalah enkapsulasi varians dalam product.Pricecontoh (Saya akan menyebutnya Priceobjek, dan harga objek nol akan NullPrice). Priceadalah objek domain, konsep bisnis. Terkadang, dalam logika bisnis kami, kami belum tahu harganya. Ini terjadi. Kasing penggunaan sempurna untuk objek nol. Prices memiliki ToStringmetode yang mengeluarkan harga, atau string kosong jika tidak diketahui (atau, NullPrice#ToStringmengembalikan string kosong). Ini adalah perilaku yang masuk akal. Kemudian persyaratan berubah.

Kita harus menampilkan a nullke tampilan API atau string lain ke tampilan manajer. Bagaimana ini memengaruhi logika bisnis kita? Ya tidak. Dalam pernyataan di atas, saya menggunakan kata 'view' dua kali. Kata ini mungkin tidak diucapkan secara eksplisit, tetapi kita harus melatih diri untuk mendengar kata-kata yang tersembunyi dalam persyaratan. Jadi mengapa 'pandangan' begitu penting? Karena itu memberi tahu kita di mana perubahan harus benar - benar terjadi: dalam pandangan kita.

Selain itu : apakah kita menggunakan kerangka kerja MVC atau tidak tidak relevan di sini. Sementara MVC memiliki arti yang sangat spesifik untuk 'Tampilan', saya menggunakannya dalam arti yang lebih umum (dan mungkin lebih berlaku) dari sepotong kode presentasi.

Jadi kita benar-benar harus memperbaikinya dalam tampilan. Bagaimana kita bisa melakukan itu? Cara termudah untuk melakukan ini adalah ifpernyataan. Saya tahu objek nol dimaksudkan untuk menghilangkan semua ifs, tetapi kita harus pragmatis. Kami dapat memeriksa string untuk melihat apakah itu kosong, dan beralih:

if(product.Price.ToString("c").Length == 0) { // one way of many
    writer.write("Price unspecified [Change]");
} else {
    writer.write(product.Price.ToString("c"));
}

Bagaimana ini mempengaruhi enkapsulasi? Bagian terpenting di sini adalah logika tampilan dienkapsulasi dalam tampilan . Kita dapat menjaga logika bisnis / objek domain sepenuhnya terisolasi dari perubahan logika tampilan dengan cara ini. Itu jelek, tapi berhasil. Ini bukan satu-satunya pilihan.

Kita dapat mengatakan bahwa logika bisnis kita telah berubah sedikit karena kita ingin menghasilkan string default jika tidak ada harga yang ditetapkan. Kita dapat membuat sedikit perubahan pada Price#ToStringmetode kita (sebenarnya membuat metode kelebihan beban). Kami dapat menerima nilai pengembalian default dan mengembalikannya jika tidak ada harga yang ditetapkan:

class Price {
    ...
    // A new ToString method
    public string ToString(string c, string default) {
        return ToString(c);
    }
    ...
}

class NullPrice {
    ...
    // A new ToString method
    public string ToString(string c, string default) {
        return default;
    }
    ...
}

Dan sekarang kode tampilan kita menjadi:

writer.write(product.Price.ToString("c", "Price unspecified [Change]"));

Syaratnya hilang. Namun, melakukan ini terlalu banyak dapat memperbanyak metode kasus khusus ke objek domain Anda, jadi ini hanya masuk akal jika hanya ada beberapa contoh saja.

Sebagai gantinya, kita dapat membuat IsSetmetode untuk Pricemengembalikan boolean:

class Price {
    ...
    public bool IsSet() {
        return return true;
    }
    ...
}

class NullPrice {
    ...
    public bool IsSet() {
        return false;
    }
    ...
}

Lihat logika:

if(product.Price.IsSet()) {
    writer.write(product.Price.ToString("c"));
} else {
    writer.write("Price unspecified [Change]");
}

Kami melihat kembalinya persyaratan dalam pandangan, tetapi kasus lebih kuat untuk logika bisnis yang mengatakan jika harga ditetapkan. Kita dapat menggunakan di Price#IsSettempat lain sekarang kita sudah tersedia.

Akhirnya, kita dapat merangkum gagasan menyajikan harga seluruhnya dalam penolong untuk tampilan. Ini akan menyembunyikan persyaratan, sambil mempertahankan objek domain sebanyak yang kita inginkan:

class PriceStringHelper {
    public PriceStringHelper() {}

    public string PriceToString(Price price, string default) {
        if(price.IsSet()) { // or use string length to not change the Price class at all
           return price.ToString("c");
        } else {
            return default;
        }
    }
}

Lihat logika:

writer.write(new PriceStringHelper().PriceToString(product.Price, "Price unspecified [Change]"));

Ada banyak lagi cara untuk membuat perubahan (kita bisa menggeneralisasi PriceStringHelpermenjadi objek yang mengembalikan default jika string kosong), tetapi ini adalah beberapa yang cepat yang mempertahankan (sebagian besar) pola dan prinsip, seperti serta aspek pragmatis dari melakukan perubahan seperti itu.

cbojar
sumber
3

Kompleksitas pola desain dapat menggigit Anda jika masalah yang seharusnya diselesaikan tiba-tiba menghilang. Sayangnya, karena antusiasme dan popularitas pola desain, risiko ini jarang dibuat eksplisit. Anekdot teman Anda banyak membantu menunjukkan bagaimana pola tidak memberikan hasil. Jeff Atwood memiliki beberapa kata pilihan tentang topik tersebut.

Dokumentasikan poin variasi (itu adalah risiko) dalam persyaratan

Banyak pola desain yang lebih kompleks (Obyek Null tidak begitu banyak) mengandung konsep variasi yang dilindungi , yaitu "Identifikasi poin variasi yang diperkirakan atau ketidakstabilan; tetapkan tanggung jawab untuk membuat antarmuka yang stabil di sekitar mereka." Adaptor, Pengunjung, Fasad, Lapisan, Pengamat, Strategi, Dekorator, dll. Semuanya memanfaatkan prinsip ini. Mereka "membayar" ketika perangkat lunak perlu diperluas dalam dimensi variabilitas yang diharapkan, dan asumsi "stabil" tetap stabil.

Jika persyaratan Anda sangat tidak stabil sehingga "variasi prediksi" Anda selalu salah, maka pola yang Anda terapkan akan menyebabkan Anda merasa sakit atau menjadi kompleksitas yang tidak dibutuhkan.

Craig Larman berbicara tentang dua peluang untuk menerapkan variasi yang dilindungi:

  • poin variasi - dalam sistem atau persyaratan yang ada, saat ini, seperti beberapa antarmuka yang harus didukung, dan
  • titik evolusi - titik spekulatif variasi yang tidak ada dalam persyaratan yang ada.

Keduanya seharusnya didokumentasikan oleh pengembang, tetapi Anda mungkin harus memiliki komitmen pelanggan untuk poin variasi.

Untuk mengelola risiko, Anda dapat mengatakan bahwa pola desain yang menerapkan PV harus ditelusuri ke titik variasi dalam persyaratan yang ditandatangani oleh pelanggan. Jika pelanggan mengubah titik variasi dalam persyaratan, desain Anda mungkin harus berubah secara radikal (karena Anda kemungkinan berinvestasi dalam [pola] desain untuk mendukung variasi itu). Tidak perlu menjelaskan kohesi, penggandengan, dll.

Misalnya, pelanggan Anda menginginkan perangkat lunak tersebut bekerja dengan tiga sistem inventaris lawas yang berbeda. Itu adalah titik variasi yang Anda desain. Jika pelanggan menjatuhkan persyaratan itu, maka tentu saja Anda memiliki banyak infrastruktur desain yang tidak berguna. Pelanggan perlu tahu bahwa poin variasi memerlukan biaya.

CONSTANTS dalam kode sumber adalah bentuk sederhana dari PV

Analogi lain untuk pertanyaan Anda adalah dengan menanyakan apakah menggunakan CONSTANTSkode sumber adalah ide yang bagus. Mengacu pada contoh ini , katakanlah pelanggan menghilangkan kebutuhan akan kata sandi. Dengan demikian, MAX_PASSWORD_SIZEpenyebaran konstan ke seluruh kode Anda akan menjadi tidak berguna dan bahkan menjadi penghalang bagi pemeliharaan dan keterbacaan. Apakah Anda menyalahkan penggunaan CONSTANTSsebagai alasannya?

Fuhrmanator
sumber
2

Saya pikir itu setidaknya sebagian tergantung pada sifat situasi Anda.

Anda menyebutkan persyaratan yang terus berubah. Jika pelanggan mengatakan "Saya ingin aplikasi pemelihara lebah ini juga bekerja dengan tawon" maka itu tampak seperti situasi di mana desain yang cermat akan membantu kemajuan, bukan menghambatnya (terutama ketika Anda menganggap bahwa di masa depan ia mungkin ingin simpan juga lalat buah.)

Di sisi lain, jika sifat perubahannya lebih seperti "Saya ingin aplikasi pemelihara lebah ini mengelola penggajian konglomerat binatu saya", tidak ada jumlah kode yang akan menggali Anda keluar dari lubang Anda.

Tidak ada yang baik tentang pola desain. Mereka alat seperti yang lain - kami hanya menggunakannya untuk membuat pekerjaan kami lebih mudah dalam jangka menengah hingga panjang. Jika alat yang berbeda (seperti komunikasi atau penelitian ) lebih bermanfaat maka kita menggunakannya.

Benjamin Hodgson
sumber