“Praktik terbaik” populer apa yang tidak selalu terbaik, dan mengapa? [Tutup]


100

"Praktik terbaik" ada di mana-mana di industri kami. Sebuah pencarian Google pada "coding praktek terbaik" muncul hampir 1,5 juta hasil. Gagasan itu tampaknya membawa kenyamanan bagi banyak orang; cukup ikuti instruksi, dan semuanya akan baik-baik saja.

Ketika saya membaca tentang praktik terbaik - misalnya, saya baru saja membaca beberapa di Kode Bersih baru-baru ini - saya merasa gugup. Apakah ini berarti saya harus selalu menggunakan latihan ini? Apakah ada syarat yang terlampir? Apakah ada situasi di mana itu mungkin bukan praktik yang baik? Bagaimana saya bisa tahu pasti sampai saya belajar lebih banyak tentang masalahnya?

Beberapa praktik yang disebutkan dalam Kode Bersih tidak cocok dengan saya, tetapi sejujurnya saya tidak yakin apakah itu karena berpotensi buruk, atau jika itu hanya bias pribadi saya yang berbicara. Saya tahu bahwa banyak orang terkemuka di industri teknologi tampaknya berpikir bahwa tidak ada praktik terbaik , jadi setidaknya keraguan saya yang mengganggu membuat saya berada di perusahaan yang baik.

Jumlah praktik terbaik yang saya baca terlalu banyak untuk dicantumkan di sini atau ajukan pertanyaan individual, jadi saya ingin mengatakan ini sebagai pertanyaan umum:

Praktik pengkodean mana yang secara populer dilabeli sebagai "praktik terbaik" dapat menjadi sub-optimal atau bahkan berbahaya dalam keadaan tertentu? Keadaan apa itu dan mengapa mereka menjadikan praktik itu miskin?

Saya lebih suka mendengar tentang contoh dan pengalaman spesifik.


8
Apa praktik yang tidak Anda setujui ?, hanya ingin tahu.
Sergio Acosta

Siapa pun dapat menulis buku, dan saya tidak harus menyetujuinya - sesederhana itu.
Ayub

Satu hal yang saya sukai dari buku "Code Complete" karya Steve McConnell adalah bahwa ia mendukung semua tipnya dengan bukti dan penelitian keras. Katakan saja '
JW01

5
@Walter: Ini telah terbuka selama berbulan-bulan, sudah pasti konstruktif, mengapa tutup itu?
Orbling

2
Melihat bagaimana nama saya disebutkan di sini, saya kira saya harus menambahkan: Saya percaya bahwa jawaban di sini berharga, tetapi pertanyaan itu dapat disusun kembali menjadi sesuatu yang kurang seperti polling tanpa membatalkan salah satu jawaban. Judul contoh: "Praktik terbaik 'populer mana yang kadang-kadang bisa berbahaya, dan kapan / mengapa?"
Aaronaught

Jawaban:


125

Saya pikir Anda telah memukul kepala dengan pernyataan ini

Aku benci mengambil sesuatu dari nilai nominal dan tidak memikirkannya secara kritis

Saya mengabaikan hampir semua Praktik Terbaik ketika tidak disertai dengan penjelasan mengapa itu ada

Raymond Chen mengedepankannya dalam artikel ini ketika dia mengatakan

Nasihat yang baik datang dengan alasan sehingga Anda bisa tahu kapan itu menjadi nasihat yang buruk. Jika Anda tidak memahami mengapa sesuatu harus dilakukan, maka Anda telah jatuh ke dalam perangkap pemrograman kultus kargo, dan Anda akan terus melakukannya bahkan ketika itu tidak lagi diperlukan atau bahkan menjadi merusak.


4
Kutipan indah.
David Thornley

Paragraf berikutnya dari kutipan Raymond Chen mungkin menggambarkan notasi Hongaria! Sebagian besar perusahaan yang saya lihat menggunakannya tanpa alasan kuat yang dapat mereka jelaskan.
Craig

3
Saya harap orang tidak menganggap ini sebagai alasan untuk tidak mencari tahu apa alasan di balik praktik terbaik itu. ;) Sayangnya, saya telah melihat pengembang dengan sikap ini.
Vetle

3
Alasannya bagus. Penelitian lebih baik.
Jon Purdy

7
Benar sekali, dan saya sudah mengatakan hal yang sama sebelumnya. Mungkin standar pertama dalam dokumen "Standar" harus berbunyi, "Demi berbagi pengetahuan dan memberikan informasi yang diperlukan untuk membatalkan standar di kemudian hari, semua standar harus menyertakan alasan keberadaannya."
Scott Whitlock

95

Mungkin juga melemparkan ini ke atas ring:

Premature optimization is the root of all evil.

Tidak, tidak.

Kutipan lengkap:

"Kita harus melupakan efisiensi kecil, katakanlah sekitar 97% dari waktu: optimasi prematur adalah akar dari semua kejahatan. Namun kita tidak boleh melewatkan peluang kita dalam 3% kritis itu."

Itu berarti bahwa Anda mengambil keuntungan dari peningkatan kinerja strategis spesifik selama proses desain Anda. Ini berarti bahwa Anda menggunakan struktur data dan algoritma yang konsisten dengan tujuan kinerja. Ini berarti bahwa Anda menyadari pertimbangan desain yang memengaruhi kinerja. Tetapi itu juga berarti bahwa Anda tidak mengoptimalkan secara sembrono ketika melakukan hal itu akan memberi Anda keuntungan kecil dengan biaya pemeliharaan.

Aplikasi harus dirancang dengan baik, sehingga tidak jatuh pada akhirnya ketika Anda menerapkan sedikit beban padanya, dan kemudian Anda akhirnya menulis ulang. Bahaya dengan kutipan singkat adalah bahwa, terlalu sering, pengembang menggunakannya sebagai alasan untuk tidak memikirkan kinerja sama sekali sampai akhir, ketika mungkin sudah terlambat untuk melakukan sesuatu tentang hal itu. Lebih baik untuk membangun kinerja yang baik sejak awal, asalkan Anda tidak fokus pada hal-hal kecil.

Katakanlah Anda sedang membangun aplikasi waktu-nyata pada sistem tertanam. Anda memilih Python sebagai bahasa pemrograman, karena "Optimalisasi prematur adalah akar dari semua kejahatan." Sekarang saya tidak menentang Python, tetapi ini adalah bahasa yang ditafsirkan. Jika daya pemrosesan terbatas, dan sejumlah pekerjaan harus diselesaikan dalam waktu-nyata atau mendekati waktu-nyata, dan Anda memilih bahasa yang membutuhkan daya pemrosesan lebih untuk pekerjaan daripada yang Anda miliki, Anda secara kacau mengacau, karena Anda sekarang harus memulai kembali dengan bahasa yang mampu.


4
+1 untuk yang kuat Tidak, bukan.
Stephen

21
Tetapi jika Anda sudah menyadari bahwa satu optimasi tertentu dalam kritis 3% itu, apakah Anda terlalu dini dalam mengoptimalkannya?
Yohanes

7
@ Robert: Lalu apa gunanya ketidaksetujuan dengan pernyataan bahwa "Optimalisasi prematur adalah akar dari semua kejahatan"?
Yohanes

8
Tidak pernah terlalu dini untuk mengoptimalkan desain tingkat tinggi dan keputusan teknis seperti pilihan bahasa. Namun sering kali hanya setelah Anda menyelesaikan sebagian besar desain yang inefisiensi menjadi jelas, itulah sebabnya Fred Brooks mengatakan bahwa sebagian besar tim menulis versi membuang apakah mereka mau atau tidak. Argumen lain untuk membuat prototipe.
Dominique McDonnell

8
@Robert, kutipan Knuth dioptimalkan sebelum waktunya ...

94

Satu pengembalian per fungsi / metode.


7
Saya akan meletakkan ini. Saya suka saya beberapa pernyataan kembali awal.
Carson Myers

4
Benar! Orang-orang menyusun alur program yang cukup menarik untuk menghindari returnpernyataan awal . Entah struktur kontrol yang sangat bersarang atau pemeriksaan berkelanjutan. Ini benar-benar dapat mengasapi suatu metode ketika if returnbenar-benar dapat menyederhanakan masalah ini.
snmcdonald

4
Jika Anda perlu beberapa pengembalian dalam suatu fungsi (selain dari penjaga) fungsi Anda mungkin terlalu lama.
EricSchaefer

18
Tidak ada gunanya memiliki kata kunci kembali kecuali jika itu dimaksudkan untuk muncul di banyak tempat. Kembali lebih awal, sering kembali. Itu hanya akan berfungsi untuk menyederhanakan kode Anda lebih lanjut. Jika orang dapat memahami bagaimana pernyataan break / continue bekerja, mengapa mereka berjuang untuk kembali?
Evan Plaice

7
Saya pikir ini adalah praktik terbaik yang sudah ketinggalan zaman. Saya tidak berpikir itu praktik terbaik modern.
Skilldrick

87

Jangan menemukan kembali roda adalah dogma yang banyak digunakan. Idenya adalah bahwa jika ada solusi yang cocok, gunakanlah alih-alih membuat sendiri; sebagai tambahan dari upaya penghematan, solusi yang ada kemungkinan lebih baik diimplementasikan (bebas bug, efisien, teruji) daripada apa yang Anda dapatkan pada awalnya. Sejauh ini bagus.

Masalahnya adalah bahwa solusi yang cocok 100% jarang ada. Solusi yang cocok 80% mungkin ada, dan menggunakannya mungkin baik-baik saja. Tapi bagaimana dengan 60% yang cocok? 40%? Di mana Anda menggambar garis? Jika Anda tidak menarik garis, Anda bisa memasukkan pustaka yang membengkak ke proyek Anda karena Anda menggunakan 10% fitur-fiturnya - hanya karena Anda ingin menghindari "menciptakan kembali roda".

Jika Anda menemukan kembali roda, Anda akan mendapatkan apa yang Anda inginkan. Anda juga akan belajar cara membuat roda. Belajar dengan melakukan seharusnya tidak diremehkan. Dan pada akhirnya, roda custom mungkin lebih baik daripada roda generik off-the-shelf.


3
Saya pernah mengalami hal sebaliknya. Saya membangun komponen grid ajax saya sendiri karena pada saat itu tidak ada yang melakukan apa yang saya inginkan, tetapi kemudian menggantinya dengan grid Ext JS. Ini membantu saya membuat asumsi dari awal bahwa lapisan tampilan akan diganti.
Joeri Sebrechts

20
Sepakat. Jika tidak ada yang pernah menemukan kembali kemudi, maka kita semua akan mengendarai mobil kami dengan ban kayu.
Apprentice Dr. Wily

6
Saya selalu merasa seperti 10% contoh Anda ketika saya menambahkan Boost ke proyek C ++. Saya selalu membutuhkan kurang dari 10% dari itu, secara langsung, tetapi tentu saja fungsi saya perlu mengimpor modul lain yang mengimpor modul lain yang ...
Roman Starkov

3
+1: baru minggu ini, saya menemukan kembali roda (mis. Ganti plugin jquery yang kembung namun populer yang kami gunakan dengan sesuatu yang sesuai dengan kebutuhan kami namun modular) dan menghasilkan keuntungan kinerja yang sangat besar. Juga, ada orang yang tugasnya benar-benar menciptakan kembali roda: ambil Michelin misalnya, mereka melakukan R&D untuk memperbaiki ban.
wildpeaks

2
@Dr. Wily, roda itu tidak diciptakan kembali, mereka di refactored!

78

"Unit Uji Segalanya."

Saya sering mendengar bahwa semua kode harus memiliki unit test, suatu hal yang tidak saya setujui. Ketika Anda memiliki tes untuk suatu metode, setiap perubahan pada output atau struktur dari metode itu harus dilakukan dua kali (sekali dalam kode, sekali dalam tes).

Dengan demikian, tes unit harus, menurut pendapat saya, proporsional dengan stabilitas struktural kode. Jika saya menulis sistem berlapis dari bawah ke atas, lapisan akses data saya akan melakukan tes wazoo; lapisan logika bisnis saya akan diuji dengan cukup baik, lapisan presentasi saya akan memiliki beberapa tes, dan pandangan saya akan memiliki sedikit atau tanpa pengujian.


7
Saya menduga bahwa "Unit Test Everything" telah menjadi klise, seperti kutipan "optimasi prematur". Saya biasanya setuju dengan proporsi Anda, dan telah melihat banyak contoh pengembang melalui upaya monumental untuk mengejek objek lapisan aplikasi, upaya yang mungkin lebih baik dihabiskan dengan melakukan pengujian penerimaan.
Robert Harvey

36
Jika perubahan pada struktur metode menyebabkan perubahan dalam tes Anda, Anda mungkin melakukan pengujian yang salah. Tes unit tidak boleh memverifikasi implementasi, hanya hasilnya.
Adam Lear

7
@Anna Lear: Saya pikir dia sedang berbicara tentang melakukan perubahan desain / struktural (refactoring). Karena desainnya tidak cukup matang, ketika Anda menemukan cara yang lebih baik untuk melakukannya, Anda mungkin harus memodifikasi banyak tes di jalan. Saya setuju bahwa ketika Anda adalah tester yang lebih ahli, Anda mungkin lebih mudah melihat di mana tes akan menjadi ide yang buruk (karena alasan ini, dan lain-lain) tetapi jika desainnya tidak benar-benar matang, Anda mungkin masih memiliki beberapa tes di cara.
n1ckp

13
Saya pikir ini juga mengapa ide "do test first" tidak berfungsi Untuk melakukan tes terlebih dahulu, Anda harus memiliki desain yang tepat. Tetapi memiliki desain yang tepat mengharuskan Anda mencoba sesuatu dan melihat cara kerjanya sehingga Anda dapat meningkatkannya. Jadi, Anda tidak dapat benar-benar melakukan tes sebelum memiliki desain, dan mendapatkan desain yang tepat mengharuskan Anda membuat kode dan melihat cara kerjanya. Kecuali jika Anda punya arsitek yang benar-benar uber, saya tidak benar-benar melihat bagaimana ide itu akan bekerja.
n1ckp

13
@ n1ck TDD sebenarnya bukan latihan pengujian sebanyak latihan desain. Idenya adalah Anda mengembangkan desain Anda melalui pengujian (karena dengan cepat mengekspos API yang masuk akal untuk barang-barang Anda) daripada menyesuaikan tes dengan desain yang ada (yang mungkin buruk / tidak cukup). Jadi tidak, Anda tidak harus memiliki hak desain untuk melakukan tes terlebih dahulu.
Adam Lear

57

Selalu programkan ke antarmuka.

Terkadang hanya akan ada satu implementasi. Jika kita menunda proses ekstraksi antarmuka sampai saat kita melihat kebutuhan untuk itu, kita akan sering menemukan itu tidak perlu.


4
Setuju, Anda memprogram ke antarmuka saat Anda membutuhkan antarmuka (yaitu API stabil untuk bekerja).
Robert Harvey

45
Dalam bacaan saya aturan ini bukan tentang antarmuka sebagai bahasa membangun. Ini berarti Anda tidak boleh membuat asumsi tentang cara kerja kelas ketika memanggil metode-metodenya, dan hanya bergantung pada kontrak API.
Zsolt Török

2
Oke, ini pertanyaan yang menarik - Saya terutama pengembang .NET, jadi bagi saya antarmuka saya seperti IBusinessManager atau IServiceContract. Bagi saya ini sangat mudah dinavigasi (dan saya biasanya menjaga antarmuka saya di namespace lain [atau bahkan proyek lain]). Ketika saya telah menggunakan Java, saya benar-benar menemukan ini membingungkan (umumnya implementasi antarmuka yang saya lihat di-suffix dengan .impl - dan antarmuka tidak memiliki penggambaran). Jadi mungkinkah ini masalah standar kode? Tentu saja antarmuka di java membuat kode terlihat berantakan - mereka terlihat persis sama dengan kelas normal pada pandangan pertama.
Watson

5
@Watson: satu biaya adalah bahwa setiap kali saya menekan F3 ('lompat ke deklarasi') pada pemanggilan metode di Eclipse, saya lompat ke antarmuka, bukan satu implementasi. Saya kemudian harus mengontrol-T, panah bawah, kembali untuk mendapatkan implementasi. Ini juga memblokir beberapa refactoring otomatis - Anda tidak dapat menguraikan metode melintasi definisi antarmuka, misalnya.
Tom Anderson

4
@ Tom: Baiklah Pak, saya dengan senang hati akan melibatkan Anda dalam perang itu, Eclipse vs Intellij - namun saya memiliki kode moral yang luar biasa yang mencegah saya terlibat dalam konfrontasi fisik dengan seseorang yang memiliki cacat yang jelas. LEDAKAN. Saya tidak mengatakan Eclipse itu buruk, saya mengatakan bahwa jika kekuatan Axis telah menggunakannya untuk membangun atau merancang mesin perang mereka, WWII sekarang akan dikenal sebagai "Kerutan dua hari". Serius meskipun, saya telah menemukan bahwa itu tidak memiliki beberapa polesan yang saya dapatkan di IDE (Intellij / VS + ReSharper). Saya mendapati diri saya bertarung lebih dari satu kali - yang terlalu banyak.
Watson

46

Jangan gunakan sumber terbuka apa pun (atau non-Microsoft untuk Anda. Pengembang NET)

Jika Microsoft tidak mengembangkannya - kami tidak menggunakannya di sini. Ingin menggunakan ORM - EF, ingin menggunakan IOC - Unity, ingin log - blok aplikasi logging perusahaan. Ada begitu banyak perpustakaan yang lebih baik - namun saya selalu terjebak memesan dari menu dolar dunia pengembangan. Saya bersumpah setiap kali saya mendengar Praktik Terbaik Microsoft, saya rasa "Pedoman Gizi McDonald's". Tentu, Anda mungkin akan hidup jika mengikuti mereka, tetapi Anda juga akan kekurangan gizi dan kelebihan berat badan.

  • Perhatikan ini mungkin bukan praktik terbaik Anda , tetapi ini adalah praktik umum yang diikuti hampir di semua tempat saya bekerja.

13
Kedengarannya mengerikan ... = (Tapi saya mungkin terlalu banyak di sisi lain, saya menghindari M $ sebanyak mungkin.
Lizzan

Seharusnya tidak seperti itu. Perpustakaan harus dipilih karena nilainya, tidak hanya mempertimbangkan siapa yang membuatnya. Misalnya, saya suka EF tetapi saya punya pengalaman buruk dengan Enterprise Library, dan menemukan alat yang lebih baik untuk validasi dan pencatatan, seperti FluentValidation, log4net, dan Elmah.
Matteo Mosca

4
Anda tidak akan dipecat karena membeli IBM ^ wMicrosoft
Christopher Mahan

17
Ada juga versi mirror-image, yaitu Jangan pernah menggunakan apa pun Microsoft, atau tidak pernah menggunakan apa pun yang harus Anda bayar.
Richard Gadsden

5
Saya cukup beruntung untuk bekerja di sebuah organisasi di mana ini bukan dogma yang dipegang secara luas, tetapi di tempat-tempat di mana kami telah mengadopsi solusi komersial, tentu ada banyak rasa sakit. Masalahnya muncul ketika beberapa bagian dari solusi komersial tidak cukup berhasil. Ketika ini open source, Anda dapat melihat sumbernya (Dokumentasi utama) dan mencari tahu apa yang salah. Dengan sumber tertutup, Anda harus membayar untuk mendapatkan hak istimewa untuk mengakses pengetahuan tentang dukungan teknis yang mengetahui lebih sedikit tentang produk yang Anda lakukan. Dan itulah satu-satunya 'perbaikan' yang tersedia.
SingleNegationElimination

40

Orientasi objek

Ada asumsi, hanya karena kode "berorientasi objek", secara ajaib bagus. Jadi orang terus memeras fungsi ke dalam kelas dan metode, hanya untuk menjadi berorientasi objek.


7
Saya tidak dapat membayangkan membangun sistem perangkat lunak dengan ukuran signifikan tanpa mengambil keuntungan dari organisasi yang menyediakan Orientasi Objek.
Robert Harvey

18
Robert. Unix tidak berorientasi objek, dan tentu saja memenuhi syarat sebagai sistem perangkat lunak dengan ukuran yang signifikan. Tampaknya juga cukup populer (pikirkan Mac OSX, iPhone, ponsel Android, dll)
Christopher Mahan

7
Yang saya maksudkan adalah bahwa saya pikir kita harus menggunakan metodologi yang paling tepat. Saya telah melihat orang-orang menggunakan metode dan kelas yang rumit dan tidak masuk akal, hanya karena "itu berorientasi objek". Itu pemujaan kargo.
LennyProgrammers

8
Tidak ada peluru perak. Pemrograman Fungsional (Haskell) cukup berhasil tanpa berorientasi objek. Pada akhirnya, Anda memiliki banyak alat dan itu adalah tugas Anda untuk memilih bermacam-macam tugas terbaik yang ada.
Matthieu M.

9
Lucunya, bahwa selain menggunakan kelas, polimorfisme dan sejenisnya, sebagian besar kode berorientasi objek sebenarnya kode prosedural.
Oliver Weiler

35

Semua kode harus dikomentari.

Tidak, seharusnya tidak. Beberapa waktu Anda memiliki kode yang jelas, misalnya setter tidak boleh dikomentari, sampai mereka melakukan sesuatu yang istimewa. Juga, mengapa saya harus mengomentari ini:

/** hey you, if didn't get, it's logger. */
private static Logger logger = LoggerFactory.getLogger(MyClass.class);

13
Semua kode harus dapat dimengerti . Komentar adalah alat utama dalam hal itu, tetapi jauh dari satu-satunya.
Trevel

Secara keliru, kode harus dapat dimengerti. Tetapi tidak ada alasan tunggal untuk menulis komentar yang tidak akan menambahkan apa pun, misalnya, nama metode. Jika Anda menulis /** sets rank. */ void setRank(int rank) { this.rank = rank; }saya menganggap komentar sebagai yang bodoh. Mengapa ini ditulis?
Vladimir Ivanov

2
Dokumentasi yang dihasilkan. Untuk itulah /** */formatnya alih-alih /* */komentar format. Atau untuk .NET, mungkin///
Berin Loritsch

10
Menggunakan }//end if, }//end for, }//end whileadalah contoh terbaik dari boros berkomentar yang pernah saya temui. Saya telah melihat ini berkali-kali di mana brace pembuka tidak lebih dari 2 baris di atas. IMHO jika Anda memerlukan komentar ini maka kode Anda perlu anjak piutang ... atau Anda perlu menambah $ 20 dan membeli editor IDE / Teks yang menyoroti kawat gigi yang cocok.
scunliffe

7
Kode mengatakan "bagaimana". Komentar perlu mengatakan "mengapa".

32

Metodologi, khususnya scrum. Saya tidak bisa menjaga wajah lurus ketika saya mendengar orang dewasa menggunakan frasa "Scrum Master". Saya bosan mendengar protes pengembang sehingga beberapa aspek dari Metodologi X tidak bekerja untuk perusahaan mereka, hanya untuk diberitahu oleh Guru Si-dan-Jadi bahwa alasan itu tidak berfungsi adalah karena mereka tidak, pada kenyataannya, praktisi sejati Metodologi X. "Scrum lebih keras, Anda harus, Padawan pelajar saya!"

Ada nugget kebijaksanaan dalam metodologi lincah --- banyak dari mereka --- tetapi mereka sering terbungkus dalam begitu banyak kotoran sehingga saya tidak bisa melawan refleks muntah saya. Ambil bit ini dari halaman scrum Wikipedia :

Sejumlah peran didefinisikan dalam Scrum. Semua peran terbagi dalam dua kelompok yang berbeda — babi dan ayam — berdasarkan sifat keterlibatan mereka dalam proses pembangunan.

Benarkah? Babi dan ayam, katamu? Menarik! Tidak sabar untuk melempar yang ini ke bos saya ...


Menarik. Saya setuju hingga batasan tertentu. Dengan bagian terakhir itu: panggil mereka apa yang Anda inginkan, itu mnemonik, itu saja.
Steven Evers

12
+1 ... Anda benar, sulit untuk menganggapnya serius. <big booming voice> * I AM THE SCRUMMASTER * </voice>
GrandmasterB

2
Dan perumpamaan. Itu mengingatkan saya pada khotbah-khotbah gereja, atau jenis-jenis anekdot yang terkenal oleh para guru swadaya (dan komedian): "Ambillah temanku Steve. Steve terus-menerus berdebat dengan istrinya Sheryl. Keduanya akan melakukannya berjam-jam, untuk titik di mana pernikahan mereka dalam bahaya nyata. Kemudian, suatu hari ... "Benang didaktik semacam ini tidak mengganggu saya di bidang lain, tapi saya benci melihat mereka berkembang biak dalam ilmu teknik.
evadeflow

2
Bagaimana dengan Scrum Ninja?
Berin Loritsch

1
Saya tidak setuju dengan perbandingan "Babi dan Ayam" ... ia terbang langsung di hadapan Agile Manifesto. Yaitu "Kolaborasi pelanggan atas negosiasi kontrak". Pelanggan memiliki hak (jika bukan lebih) dalam keberhasilan proyek sebagai tim proyek. Memanggil beberapa babi peran dan ayam peran lainnya membentuk mentalitas "kami versus mereka" yang IMHO adalah penghalang terbesar untuk proyek yang sukses.
Michael Brown

25

Pemetaan Relasional Objek ... http://en.wikipedia.org/wiki/Object-relational_mapping

Saya tidak ingin diabstraksi dari data saya, saya juga tidak ingin kehilangan kontrol dan optimisasi yang tepat. Pengalaman saya dengan sistem ini sangat buruk ... Pertanyaan yang dihasilkan oleh lapisan abstraksi ini bahkan lebih buruk daripada apa yang saya lihat dari off-shoring.


19
Optimalisasi prematur adalah akar dari semua kejahatan. Kode lambat, dalam kehidupan nyata, hanya sangat jarang menjadi masalah jika dibandingkan dengan kode yang tidak dapat dipelihara. Gunakan ORM, kemudian potong abstraksi hanya jika Anda membutuhkannya.
Fishtoaster

28
ORM adalah alat 80-20. Mereka dimaksudkan untuk menangani 80% CRUD yang menjadi sangat melelahkan untuk menulis semua kode pipa tanpa akhir setelah beberapa saat. 20% lainnya dapat dilakukan dengan cara yang lebih "konvensional" seperti menggunakan prosedur tersimpan dan menulis pertanyaan SQL biasa.
Robert Harvey

18
@Fishtoaster: Bukankah maksud Anda, "Kita harus melupakan efisiensi kecil, katakanlah sekitar 97% dari waktu: optimasi prematur adalah akar dari semua kejahatan. Namun kita tidak boleh melewatkan peluang kita dalam 3% kritis itu."?
Robert Harvey

5
@Robert Harcey: Ada alasan saya tidak menggunakan kutipan langsung. Saya pikir sebagian besar programmer terlalu berfokus pada efisiensi - ini adalah masalah yang hanya beberapa di antaranya yang perlu dipecahkan. Memang, ada domain tertentu di mana itu lebih penting daripada yang lain, tetapi pemeliharaan dan ekstensibilitas adalah masalah di mana-mana. Kutipan lain yang dimodifikasi: "Jadikan itu berhasil, buatlah itu dapat dipertahankan, buatlah itu dapat dibaca, buatlah dapat diperluas, buatlah itu dapat diuji, dan kemudian , jika Anda punya waktu dan ternyata Anda membutuhkannya, buatlah dengan cepat."
Fishtoaster

12
@Craig: Bagaimana Anda tidak mengenali ironi dalam pernyataan Anda? Membutuhkan satu tahun untuk belajar bagaimana mendapatkan kinerja yang baik dari ORM adalah argumen yang sangat baik terhadap ORM , seperti kebutuhan untuk "mengontrol" SQL yang diproduksi dan menyuntikkan prosedur tersimpan. Jika Anda memiliki pengetahuan untuk itu, Anda memiliki pengetahuan untuk memotong ORM sepenuhnya.
Nicholas Knight

22

Menulis nama fungsi seolah-olah itu adalah kalimat bahasa Inggris:

Draw_Foo()
Write_Foo()
Create_Foo()

dll. Ini mungkin terlihat hebat, tetapi itu menyebalkan ketika Anda mempelajari API. Seberapa mudah untuk mencari indeks untuk "Segala sesuatu yang dimulai dengan Foo"?

Foo_Draw()
Foo_Write()
Foo_Create()

dll.


2
Mungkin tentang semudah mengetik Foo di daftar fungsi TM.
Josh K

68
Kedengarannya seperti Anda benar-benar menginginkannya Foo.Draw(), Foo.Write()dan Foo.Create(), sehingga Anda bisa melakukan Foo.methods.sortatauFoo.methods.grep([what I seek]).sort
Inaimathi

7
Dimulai dengan 'Dapatkan' adalah contoh lain.
JeffO

1
Saya berasal dari dunia objektif-c, dan sangat kehilangan nama metode verbose dan notasi infiks ketika saya melakukan java (kehidupan saya yang lain). Karena penyelesaian kode mulai berfungsi, saya juga belum menemukan tambahan masalah pengetikan.

2
@Scott Whitlock: Tidak yang out of date untuk beberapa pengembang NET, iirc, VS 2008 tidak melakukan itu. 2010 melakukannya, dan itu fantastis.
Steven Evers

22

MVC - saya sering menemukan bahwa menyoalkan banyak masalah desain web ke dalam pendekatan MVC lebih tentang membuat kerangka kerja (rails dll) bahagia daripada tentang kesederhanaan atau struktur. MVC adalah favorit "astronot arsitektur" yang tampaknya menghargai perancah berlebihan atas kesederhanaan. ymmv.

OO berbasis kelas - dalam pendapat saya mendorong struktur kompleks negara yang bisa berubah. satu-satunya kasus yang menarik yang saya temukan untuk OO berbasis kelas selama bertahun-tahun adalah contoh "bentuk-> persegi panjang-> norak yang membentuk bab 1 dari buku OO apa pun


4
Saya telah melakukan pengembangan web di ASP.NET dan ASP.NET MVC dan, meskipun MVC memang terlihat sangat membingungkan, saya lebih memilihnya daripada ASP.NET, karena banyak alasan: kesederhanaan, perawatan, dan kendali yang sangat baik atas markup. Segala sesuatu memiliki tempatnya dan, meskipun semuanya tampak berulang-ulang, itu adalah kegembiraan untuk dipertahankan. Ini sepenuhnya dapat dikustomisasi, jadi jika Anda tidak menyukai perilaku di luar kotak, Anda dapat mengubahnya.
Robert Harvey

1
Sejauh menyangkut OO, ada cara baik dan buruk untuk melakukannya. Warisan terlalu dilebih-lebihkan, dan digunakan lebih hemat di dunia nyata daripada yang Anda yakini; saat ini ada kecenderungan menuju gaya pengembangan yang lebih fungsional dan tidak berubah, bahkan di dunia OO.
Robert Harvey

1
+1 untuk menyebutkan MVC. Sementara konsep MVC (memisahkan logika lapisan data, logika presentasi, dan logika latar belakang adalah ide yang bagus) secara fisik memisahkan mereka ke dalam hierarki folder yang kompleks dengan campuran file yang berisi potongan kode adalah bodoh. Saya menyalahkan seluruh fenomena ini pada kurangnya dukungan namespace PHP dan pengembang pemula yang mengagungkan teknik yang sudah berumur puluhan tahun sebagai 'hal terbaru'. Sangat sederhana, buat namespace untuk pengakses database, GUI, dan logika latar belakang (dan sub-namespace jika diperlukan).
Evan Plaice

3
Sedangkan untuk OO, Anda tidak akan benar-benar melihat manfaatnya sampai proyek Anda tumbuh ke ukuran di mana pengelolaan kompleksitas menjadi penting. Ikuti prinsip tanggung jawab tunggal sedapat mungkin dan jika kode Anda dapat diakses oleh publik (mis. Untuk .dll) sembunyikan implementasi internal kelas / metode / properti sedapat mungkin untuk membuat kode lebih aman dan untuk menyederhanakan API.
Evan Plaice

1
Saya pribadi menemukan contoh bentuk-> persegi panjang-> persegi menjadi salah satu argumen paling elegan terhadap oop. misalnya, Square(10).Draw()cukup untuk Rectangle(10, 10).Draw(). jadi saya kira itu berarti persegi adalah subkelas dari persegi panjang. Tapi mySquare.setWidthHeight(5,10)omong kosong (IE, itu gagal prinsip substitusi Liskov), persegi tidak dapat memiliki tinggi dan lebar yang berbeda, meskipun persegi panjang bisa, sehingga menyiratkan bahwa persegi panjang adalah subkelas dari persegi. Ini dikenal dalam konteks lain sebagai "Lingkaran, masalah Ellipse"
SingleNegationElimination

22

YAGNI

( Kamu tidak akan membutuhkannya )

Pendekatan ini memakan waktu berjam-jam ketika saya harus mengimplementasikan fitur pada basis kode yang ada, di mana perencanaan yang cermat akan menyertakan fitur-fitur ini sebelumnya.

Gagasan saya sering ditolak karena YAGNI, dan sebagian besar kali seseorang harus membayar untuk keputusan itu nanti.

(Tentu saja orang dapat berargumen bahwa basis kode yang dirancang dengan baik juga akan memungkinkan fitur ditambahkan nanti, tetapi kenyataannya berbeda)


15
Saya setuju dengan YAGNI, tapi saya mengerti maksud Anda. Maksud dari YAGNI adalah berurusan dengan orang-orang yang ingin merencanakan semuanya di muka hingga ke detail terkecil. Sembilan dari sepuluh, itu digunakan sebagai alasan untuk kode insinyur atau benar-benar melewatkan perencanaan.
Jason Baker

12
P.Floyd, @Jason Baker: +1 Benar sekali. Pepatah lama berlaku di sini "berbulan-bulan di lab dapat menghemat berjam-jam di perpustakaan"
Steven Evers

Spesifikasi sering kali akan (dan sebagian besar harus) meninggalkan sebagian besar implemnentation, dan beberapa antarmuka terbuka. semuanya tidak ada dalam spesifikasi secara langsung, tetapi diperlukan untuk mengimplementasikan spesifikasi, apakah keputusan implementasi, antarmuka yang dapat dilihat pengguna, atau apa pun, juga merupakan persyaratan tidak langsung dari spesifikasi tersebut. Jika fitur tidak ada dalam spesifikasi, dan tidak tersirat oleh spesifikasi, maka Anda tidak memerlukannya. Bagaimana ini bisa membingungkan?
SingleNegationElimination

1
@TokenMacGuy aspek penting adalah yang tersirat oleh bagian spesifikasi . Di situlah pendapat sangat berbeda.
Sean Patrick Floyd

20

Untuk SQL

  1. Jangan gunakan pemicu
  2. Selalu sembunyikan tabel di belakang tampilan

Dalam urutan:

  1. Mereka adalah fitur yang memiliki tempat itu. Anda memiliki beberapa jalur pembaruan ke sebuah tabel, atau memerlukan audit 100%?

  2. Kenapa? Saya akan melakukannya jika saya refactoring untuk mempertahankan kontrak, tetapi tidak ketika saya membaca bahwa orang mengubah pandangan agar sesuai dengan perubahan tabel apa pun

Sunting:

Nomor 3: Menghindari * dengan EXIS. Coba 1/0. Berhasil. Daftar kolom tidak dievaluasi sesuai standar SQL. Halaman 191


3
# 2 adalah praktik terbaik?
Hogan


1
@Hogan: Tampilan yang hanya mencerminkan tabel dasar tidak menambah keamanan saat menggunakan tabel dasar secara langsung. Jika Anda bergabung dengan tabel pengguna keamanan, atau menutupi beberapa kolom maka cukup adil. Tapi PILIH setiap kolom dari tabel atau tampilan: tidak ada perbedaan. Secara pribadi, saya memang menggunakan procs yang tersimpan.
gbn

3
@Hogan: Saya tahu sesuatu tentang SQL Server :-) stackoverflow.com/users/27535/gbn Apa yang saya maksud adalah GRANT SELECT di atas meja tidak berbeda dengan GRANT SELECT ON VIEW jika tampilan SELECT * FROM TABLE
gbn

1
@ gbn: Saya setuju. Tidak ada perbedaan di sana. Saya pikir kita mungkin mengatakan hal yang sama. Saya kira komentar asli saya ("# 2 adalah praktik terbaik?") Lebih didasarkan pada pengalaman pribadi saya bahwa pandangan (seperti pemicu) lebih sering salah digunakan daripada digunakan dengan benar. Jadi praktik terbaik semacam itu hanya akan mengarah pada pelecehan, bukan peningkatan. Jika itu dianggap praktik terbaik, Anda 100% benar itu adalah praktik yang buruk.
Hogan

20

Pola Desain kebanyakan. Mereka terlalu banyak digunakan dan kurang dimanfaatkan.


13
+1 Saya masih tidak melihat bagaimana Pola Desain adalah solusi yang indah atau elegan. Mereka adalah solusi untuk kekurangan bahasa, tidak lebih.
Oliver Weiler

2
Lihat saja sebagai upaya menghilangkan bau bahasa dengan menggunakan bahasa itu sendiri.
Filip Dupanović

15

Prinsip Tanggung Jawab Tunggal

("setiap kelas seharusnya hanya memiliki satu tanggung jawab tunggal; dengan kata lain, setiap kelas harus memiliki satu, dan hanya satu, alasan untuk berubah")

Saya tidak setuju. Saya pikir suatu metode seharusnya hanya memiliki satu alasan untuk berubah, dan semua metode dalam suatu kelas harus memiliki hubungan logis satu sama lain , tetapi kelas itu sendiri mungkin benar - benar melakukan beberapa hal (terkait).

Dalam pengalaman saya, prinsip ini terlalu sering diterapkan terlalu bersemangat, dan Anda berakhir dengan banyak kelas kecil satu metode. Kedua toko tangkas tempat saya bekerja telah melakukan ini.

Bayangkan jika pencipta .Net API memiliki mentalitas seperti ini: daripada List.Sort (), List.Reverse (), List.Find () dll., Kita akan memiliki kelas ListSorter, ListReverser, dan ListSearcher!

Daripada berdebat lagi melawan SRP (yang secara teori tidak mengerikan) , saya akan membagikan beberapa pengalaman anekdot saya yang bertele-tele:


Di satu tempat saya bekerja, saya menulis sebuah pemecah aliran maks yang sangat sederhana yang terdiri dari lima kelas: satu simpul, satu grafik, satu pembuat grafik, satu pembuat grafik, dan satu kelas untuk menggunakan pembuat grafik / pemecah untuk menyelesaikan suatu masalah dunia nyata. Tidak ada yang sangat kompleks atau panjang (solver adalah yang terpanjang di ~ 150 baris). Namun, diputuskan bahwa kelas-kelas tersebut memiliki "tanggung jawab" terlalu banyak, sehingga rekan kerja saya mulai memperbaiki kode itu. Ketika mereka selesai, 5 kelas saya telah diperluas menjadi 25 kelas, yang total baris-kode-nya lebih dari tiga kali lipat dari aslinya. Alur kode tidak lagi jelas, juga bukan tujuan dari unit-tes baru; Saya sekarang kesulitan mencari tahu apa yang kode saya lakukan.


Di tempat yang sama, hampir setiap kelas hanya memiliki satu metode (satu-satunya "tanggung jawab"). Mengikuti alur dalam program hampir tidak mungkin, dan sebagian besar unit-test terdiri dari pengujian bahwa kelas ini memanggil kode dari kelas lain , yang tujuannya sama-sama merupakan misteri bagi saya. Ada ratusan kelas di mana seharusnya (IMO) hanya puluhan. Setiap kelas hanya melakukan satu "hal" , tetapi bahkan dengan konvensi penamaan seperti "AdminUserCreationAttemptorFactory" , sulit untuk mengatakan hubungan antara kelas.


Di tempat lain (yang juga memiliki mentalitas kelas-seharusnya-hanya-memiliki-satu-metode ), kami mencoba mengoptimalkan metode yang menghabiskan 95% waktu selama operasi tertentu. Setelah (agak bodoh) mengoptimalkannya sedikit, saya mengalihkan perhatian saya mengapa itu disebut bajillion kali. Itu disebut dalam loop di kelas ... yang metodenya disebut dalam loop di kelas lain .. yang juga disebut dalam loop ..

Semua mengatakan, ada lima tingkat loop yang tersebar di 13 kelas (serius). Apa yang sebenarnya dilakukan oleh satu kelas tidak mungkin ditentukan hanya dengan melihatnya - Anda harus membuat sketsa grafik mental tentang metode apa yang disebutnya, dan metode apa yang disebut metode itu, dan seterusnya. Jika semuanya disatukan dalam satu metode, panjangnya hanya sekitar 70 baris dengan metode-masalah kita bersarang dalam lima tingkat loop yang jelas.

Permintaan saya untuk mengubah 13 kelas menjadi satu kelas ditolak.


6
Kedengarannya seperti seseorang mendapat "Pattern Fever" atau dalam hal ini "Principle Fever" di pekerjaan itu. Kelas daftar tidak melanggar SRP. Semua fungsinya melayani satu tujuan, memanipulasi kumpulan objek. Hanya memiliki satu fungsi di dalam kelas yang kedengarannya berlebihan bagi saya. Prinsip di balik SRP adalah bahwa unit kode (baik metode, kelas, atau perpustakaan) harus memiliki satu tanggung jawab yang dapat dinyatakan dengan sukses.
Michael Brown

3
Saya sudah mulai melihat kegilaan semacam ini dari orang-orang yang merasa tidak mungkin menulis kode fungsional polos murni. Terlalu banyak mendidik bahwa setiap masalah di dunia dapat diselesaikan dari sebuah buku pola. Tidak cukup memikirkan pragmatisme. Seperti Anda, saya telah melihat beberapa kode OO berbasiskan kelas yang begitu mengerikan sehingga mengikutinya benar-benar mustahil. Dan itu besar dan bengkak.
cepat

3
2 komentar di sini. Banyak "prinsip" yang diterapkan secara berlebihan. Ada banyak hal yang merupakan ide bagus, di mana melakukan hal yang sebaliknya kadang tepat. Pemrogram yang baik tahu kapan melanggar aturan. Karena aturan bukanlah "aturan", mereka adalah pernyataan "praktik yang baik sebagian besar waktu kecuali ketika itu adalah ide yang sangat bodoh."
cepat

"Bayangkan jika pembuat .Net API memiliki mentalitas seperti ini: daripada List.Sort (), List.Reverse (), List.Find () dll., Kami akan memiliki kelas ListSorter, ListReverser, dan ListSearcher ! " Inilah yang dilakukan di C ++, dan ini luar biasa . Algoritma dipisahkan dari struktur data, jadi jika saya menulis wadah saya sendiri, semua algoritma yang bekerja dengan pustaka standar hanya bekerja dengan wadah baru saya. Pasti mengerikan di .Net land, menulis fungsi penyortiran baru untuk setiap wadah baru yang ingin Anda sortir.
Mankarse

14

Sekarang setelah Anda menyebutkan Kode Bersih, sementara itu berisi beberapa ide bagus, saya pikir obsesinya untuk memperbaiki semua metode menjadi submethods dan yang menjadi sububmethods dll diambil terlalu jauh. Alih-alih beberapa metode sepuluh-baris Anda seharusnya memilih dua puluh (seharusnya nama baik) satu-liners. Jelas seseorang berpikir itu bersih, tetapi bagi saya tampaknya jauh lebih buruk daripada versi aslinya.

Juga, mengganti hal-hal sederhana seperti SD

0 == memberArray.length

dalam kelas dengan panggilan ke metode kelas sendiri seperti

isEmpty()

adalah IMHO "perbaikan" dipertanyakan. Tambahan: Perbedaannya adalah bahwa pemeriksaan pertama tidak persis seperti yang dikatakan: memeriksa apakah panjang array adalah 0. Oke, isEmpty()mungkin memeriksa panjang array juga. Tetapi bisa juga diimplementasikan seperti ini:

return null != memberArray ? 0 == memberArray.length : true;

Yaitu, itu termasuk cek kosong implisit! Ini mungkin perilaku yang baik untuk metode publik - jika arraynya nol, maka ada sesuatu yang benar-benar kosong - tetapi ketika ketika kita berbicara tentang internal class, ini tidak begitu baik. Sementara enkapsulasi ke luar adalah suatu keharusan, internal kelas harus tahu persis apa yang terjadi di dalam kelas. Anda tidak dapat merangkum kelas dari dirinya sendiri . Eksplisit lebih baik daripada implisit.


Ini bukan untuk mengatakan bahwa memecah metode panjang atau perbandingan logis yang terlibat tidak baik; tentu saja, tetapi sampai sejauh mana melakukannya - di mana sweet spot - jelas merupakan masalah selera. Memecah metode yang panjang menghasilkan lebih banyak metode, dan itu tidak gratis. Anda harus melompat-lompat kode sumber untuk melihat apa yang sebenarnya terjadi, ketika Anda bisa melihatnya sekilas jika semua itu ada dalam satu metode.

Saya bahkan akan mengatakan bahwa dalam beberapa kasus metode 1-line terlalu pendek untuk pantas menjadi metode.


6
Saya jarang melihat ini sebagai masalah. Kebanyakan itu karena saya biasanya melihat terlalu banyak dalam satu metode, tidak terlalu sedikit. Namun, menurut beberapa penelitian kompleksitas yang sangat rendah dalam metode juga memiliki tingkat bug yang sedikit lebih tinggi daripada kompleksitas yang cukup rendah. enerjy.com/blog/?p=198
MIA

Ya, ini jelas merupakan masalah dalam Kode Bersih saja. Dalam kehidupan nyata metode cenderung terlalu lama, seperti yang Anda katakan. Tapi menarik melihat kurva itu! Memang, segala sesuatunya harus dibuat sesederhana mungkin, tetapi tidak lebih sederhana.
Joonas Pulakka

1
Saya menemukan contoh kedua Anda jauh lebih mudah dibaca, dan bentuk itu (atau sesuatu yang serupa, seperti properti Panjang di kelas itu sendiri) adalah suatu keharusan jika Anda membuatnya publik.
Robert Harvey

@ Robert Harvey: Contoh kedua adalah metode publik yang bagus, tetapi memanggilnya dari dalam kelas itu sendiri dipertanyakan, karena Anda tidak tahu persis apa yang dilakukannya sebelum Anda melihat bagaimana penerapannya. Itu bisa memeriksa nol, misalnya. Lihat tambahan saya di atas.
Joonas Pulakka

@Joonas: Cukup adil.
Robert Harvey

13

"Jadilah liberal dengan komentar"

Komentar jelas merupakan hal yang baik, tetapi terlalu banyak sama buruknya jika tidak lebih buruk daripada tidak cukup. Mengapa? Yah, orang cenderung mengabaikan komentar jika mereka melihat terlalu banyak komentar yang tidak perlu. Saya tidak mengatakan bahwa Anda dapat memiliki kode dokumentasi diri yang sempurna, tetapi lebih baik daripada kode yang membutuhkan komentar untuk penjelasan.


1
kode self-dokumentasi pasti bagus. Meskipun, saya suka memiliki komentar di samping sesuatu seperti perhitungan sederhana (untuk mengekspresikan apa tipe pengembalian atau nilai kembali). Namun, jika komentar Anda membutuhkan lebih banyak kata daripada kode itu sendiri, mungkin sudah waktunya untuk menulis ulang kode tersebut.
sova

6
Saya harus setuju dengan cara sova menempatkan yang satu ini. Kode bersih lebih disukai daripada komentar.
riwalk

4
Anda masih membutuhkan "mengapa" ada di sana!

Saya lebih suka memiliki komentar yang menjelaskan alasannya. Itu berarti saya harus BERPIKIR kurang dalam rekayasa balik maksud kode ketika saya datang untuk melihatnya.
cepat,

12

GoTo Dianggap Berbahaya

Jika Anda menerapkan mesin negara, pernyataan GOTO dapat lebih masuk akal (keterbacaan dan kode efisien) daripada pendekatan "pemrograman terstruktur". Ini benar-benar mengkhawatirkan beberapa rekan kerja ketika potongan kode pertama yang saya tulis dalam sebuah pekerjaan baru tidak hanya mencakup satu tetapi beberapa pernyataan. Untungnya mereka cukup pintar untuk menyadari bahwa itu sebenarnya solusi terbaik dalam kasus khusus ini.

"Praktik terbaik" apa pun yang tidak memungkinkan pengecualian yang masuk akal dan terdokumentasi pada aturannya hanyalah menakutkan.


16
Saya akan pemrograman sembilan tahun tanpa pernyataan goto tunggal (termasuk beberapa mesin negara, seperti yang Anda sebutkan). Luaskan pikiran Anda ke ide-ide baru.
riwalk

3
@Mathieu M. - setuju - mencampur GOTO dengan pernyataan kontrol terstruktur tidak masuk akal. (Ini murni C dan itu bukan masalah.
MZB

1
@ Stargazer2 - dengan FSM sederhana, itu tergantung apakah menempatkan negara dalam variabel dan menggunakannya sebagai indeks untuk memanggil prosedur (bukankah itu sama dengan GOTO yang dihitung?) Memberikan kode yang lebih jelas / lebih cepat daripada menggunakan penghitung program sebagai negara FSM. Saya tidak menganjurkan ini sebagai solusi terbaik di sebagian besar keadaan, hanya solusi terbaik dalam beberapa keadaan. Perluas pikiran Anda dengan pendekatan alternatif.
MZB

5
@ MZB, tidakkah Anda setuju bahwa panggilan fungsi juga hanya GOTO yang dihitung? Hal yang sama berlaku untuk / sementara / jika / lain / beralih konstruksi, antara lain. Desainer bahasa mengabstraksikan perubahan langsung ke penghitung program karena suatu alasan. Jangan gunakan goto.
riwalk

3
Mengimplementasikan statemachine secara langsung mungkin merupakan antipattern. Ada banyak cara untuk memiliki mesin negara tanpa mengekspresikan keadaan dan transisi secara harfiah. misalnya,import re
SingleNegationElimination

12

Pengorbanan yang kami lakukan untuk membuat kode dapat diuji

Saya melompati banyak rintangan untuk membuat kode saya dapat diuji, tetapi saya tidak berpura-pura bahwa saya tidak akan jika diberi pilihan. Namun, saya sering mendengar orang-orang mendorong gagasan bahwa ini adalah "praktik terbaik." Praktik-praktik ini termasuk (ditulis dalam bahasa .Net, tetapi juga berlaku untuk bahasa lain) :

  • Membuat antarmuka untuk setiap kelas. Ini menggandakan jumlah kelas (file) untuk menangani, dan menggandakan kode. Ya, pemrograman antarmuka itu baik, tetapi itulah yang dimaksudkan untuk specifier publik / swasta.
  • Setiap kelas yang tidak dipakai pada saat startup membutuhkan pabrik. Jelas, new MyClass()jauh lebih sederhana daripada menulis sebuah pabrik, tetapi sekarang metode yang membuatnya tidak dapat diuji secara terpisah. Kalau bukan karena fakta ini, saya hanya akan membuat 1/20 jumlah kelas pabrik yang saya lakukan sekarang.
  • Jadikan setiap kelas publik, yang mengalahkan tujuan memiliki penentu akses pada kelas sama sekali. Namun, kelas non-publik tidak dapat diakses (dan dengan demikian, diuji) dari proyek lain, sehingga satu-satunya pilihan lain adalah memindahkan semua kode pengujian ke proyek yang sama (dan dengan demikian melepaskannya dengan produk akhir).
  • Injeksi Ketergantungan. Jelas harus memberi setiap kelas lain saya menggunakan bidang dan parameter-konstruktor secara signifikan lebih berfungsi daripada hanya membuat mereka ketika saya membutuhkannya; tapi kemudian saya tidak bisa lagi menguji kelas ini secara terpisah.
  • Prinsip Tanggung Jawab Tunggal, yang telah menyebabkan saya sangat sakit kepala, saya memindahkannya ke jawabannya sendiri .

Jadi apa yang bisa kita lakukan untuk memperbaikinya? Kami membutuhkan perubahan drastis dalam arsitektur bahasa:

  • Kami membutuhkan kemampuan untuk mengejek kelas
  • Kami membutuhkan kemampuan untuk menguji metode privat dari kelas internal, dari proyek lain (ini mungkin terlihat seperti kerentanan keamanan, tapi saya tidak melihat masalah jika peserta ujian dipaksa untuk menyebutkan kelas penguji) .
  • Injeksi ketergantungan (atau lokasi layanan), serta sesuatu yang setara dengan pola pabrik kami yang ada, harus menjadi bagian inti dari bahasa tersebut.

Singkatnya, kita membutuhkan bahasa yang dirancang dari bawah ke atas dengan kemampuan untuk diuji .


Saya kira Anda belum pernah mendengar tentang TypeMock ? Ini memungkinkan kelas mengejek, privat, statika (pabrik), apa saja.
Allon Guralnek

@ Allon: Sudah, tapi masih jauh dari gratis , menjadikannya bukan pilihan bagi kebanyakan orang.
BlueRaja - Danny Pflughoeft

Jika Anda harus menulis banyak kelas pabrik maka Anda melakukan sesuatu yang salah. Perpustakaan Smart DI (mis. Autofac untuk C #) dapat memanfaatkan Fungsi <T>, Malas <T>, Delegasi, dll. Untuk pabrik, tanpa menulis sendiri pelat lantai.
gix

10

Memisahkan aplikasi menjadi Tiers; Lapisan Data, Lapisan Bisnis, Lapisan UI

Alasan utama saya tidak suka ini adalah karena sebagian besar tempat yang mengikuti metode ini, menggunakan kerangka kerja yang sangat rapuh untuk menyelesaikannya. IE UI Layer adalah kode tangan untuk menangani objek lapisan bisnis, objek lapisan bisnis kode tangan untuk berurusan dengan aturan dan basis data bisnis, basis data adalah SQL dan sudah cukup rapuh dan dikelola oleh kelompok "DBA" yang tidak menyukai perubahan.

Mengapa ini buruk? Permintaan peningkatan yang paling umum adalah "Saya perlu bidang pada layar X yang memiliki Y." Bang! Anda hanya memiliki fitur baru yang memengaruhi setiap layer, dan jika Anda memisahkan layer dengan programmer yang berbeda, itu hanya menjadi masalah besar yang melibatkan banyak orang dan grup, untuk perubahan yang sangat sederhana.

Selain itu, saya tidak tahu sudah berapa kali saya bertengkar seperti ini. "Bidang nama terbatas pada panjang maksimal 30, apakah ini lapisan UI, atau lapisan bisnis, atau masalah lapisan data?" Dan ada seratus argumen, dan tidak ada jawaban yang benar. Jawabannya sama, itu mempengaruhi semua lapisan, Anda tidak ingin membuat UI bodoh dan harus melalui semua lapisan, dan gagal di basis data, hanya saja pengguna mengetahui entrinya terlalu panjang. Jika Anda mengubahnya, itu mempengaruhi semua lapisan, dll.

"Lapisan" cenderung bocor juga; Jika ada lapisan yang secara fisik dipisahkan oleh batas proses / mesin (IE web UI dan logika backend bisnis), aturan akan diduplikasi untuk membuat semuanya berfungsi dengan baik. Yaitu beberapa logika bisnis berakhir di UI, meskipun itu adalah "aturan bisnis", karena pengguna perlu UI untuk responsif.

Jika kerangka kerja yang digunakan, atau arsitektur yang digunakan, tahan terhadap perubahan dan kebocoran kecil, yaitu berdasarkan data meta, dan disesuaikan secara dinamis melalui semua lapisan, itu bisa kurang menyakitkan. Tetapi sebagian besar kerangka kerja ini adalah masalah besar, membutuhkan perubahan UI, perubahan lapisan bisnis, dan perubahan basis data, untuk setiap perubahan kecil, dan menyebabkan lebih banyak pekerjaan dan lebih sedikit bantuan daripada teknik yang seharusnya dihasilkan.

Saya mungkin akan dibanting karena ini, tapi itu dia :)


+1, sepertinya tempat kerja terakhir saya hingga detail paling menit! Saya menghormati aplikasi berjenjang pada prinsipnya tetapi terlalu banyak orang memperlakukannya seperti peluru perak ketika itu tidak masuk akal. Sebagian besar perangkat lunak bisnis memiliki jumlah logika bisnis yang sangat rendah dan apa yang dimilikinya relatif sederhana. Ini dapat membuat logika bisnis layering mimpi buruk dari kode boilerplate. Sering kali garis menjadi kabur antara akses data dan logika bisnis karena kueri ADALAH logika bisnis.
maple_shaft

... lebih lanjut, sebagian besar toko benar-benar gagal mengenali logika UI atau logika Presentasi. Karena mereka tidak mengerti betapa sedikit logika bisnis yang ada dalam aplikasi CRUD yang khas, mereka merasa seolah-olah mereka melakukan sesuatu yang salah ketika mayoritas logika mereka berada di lapisan presentasi sebagai logika presentasi. Ia secara palsu diidentifikasi sebagai logika bisnis dan kemudian orang-orang mendorongnya ke server untuk panggilan server lain. Thin Client dapat dan harus memiliki logika Presentasi, Eg. (Sembunyikan textField2 jika option1 dipilih di dropDown3).
maple_shaft


7

Kisah Pengguna / Kasus Penggunaan / Persona

 

Saya memahami kebutuhan akan ini ketika Anda memprogram untuk industri yang tidak Anda kenal, tetapi saya pikir ketika mereka diterapkan dengan kekuatan penuh mereka menjadi terlalu korporat dan menjadi buang-buang waktu.


7

Batas 80 char / line bodoh

Saya memahami bahwa beberapa kompromi perlu dibuat agar sesuai dengan kecepatan pelari paling lambat di sisi GUI (batasan resolusi layar, dll.) Tetapi, mengapa aturan itu berlaku untuk pemformatan kode?

Lihat ... Ada penemuan kecil ini yang disebut bilah gulir horizontal yang dibuat untuk mengelola ruang layar virtual di luar batas piksel paling kanan. Mengapa tidak pengembang, yang telah berhasil membuat alat peningkatan produktivitas yang hebat seperti penyorotan sintaksis dan pelengkapan otomatis menggunakannya?

Tentu, ada editor CLI yang digunakan secara religius oleh dinosaurus * nix yang mengikuti batasan lama yang lelah dari terminal VT220 mereka, tetapi mengapa kita semua berpegang pada standar yang sama?

Saya katakan, sekrup batas 80 char. Jika dinosaurus cukup epik untuk meretas emacs / vim sepanjang hari, mengapa tidak bisa harus mampu membuat ekstensi yang secara otomatis membungkus garis atau memberikan kemampuan gulir horizontal ke IDE CLI mereka?

Monitor piksel 1920x1080 pada akhirnya akan menjadi norma dan pengembang di seluruh dunia masih hidup di bawah batasan yang sama tanpa memedulikan mengapa mereka melakukannya kecuali, itulah yang mereka perintahkan untuk dilakukan oleh orang tua mereka ketika mereka baru saja mulai memprogram.

Batas char bukan merupakan praktik terbaik tetapi praktik khusus untuk sebagian kecil programmer dan harus diperlakukan seperti itu.

Sunting:

Dapat dimengerti bahwa banyak pengembang tidak menyukai bilah gulir horizontal karena memerlukan gerakan mouse jadi ... Mengapa tidak menambah batas lebar kolom ke angka yang lebih tinggi (dari 80) bagi kita yang menggunakan layar modern.

Ketika monitor komputer 800x600 menjadi norma bagi sebagian besar pengguna, pengembang web meningkatkan lebar situs web mereka untuk mengakomodasi mayoritas ... Mengapa pengembang tidak dapat melakukan hal yang sama.


1
@Orbling Logika GWB yang bagus dengan ___ adalah sudut yang jahat. Jadi Anda membenci hScroll, apakah Anda memiliki alasan yang valid mengapa col-width harus dibatasi hingga 80 karakter? Kenapa tidak 160 atau 256? Saya pikir kita semua bisa berasumsi bahwa sebagian besar pengembang telah pensiun terminal VT220 mereka dan menggantinya dengan puTTY sehingga mereka mampu memperluas lebar secara terprogram pula.
Evan Plaice

4
Saya lebih suka bahwa kita tetap pada batas 80 karakter. Segera setelah Anda memberi saya lebih banyak ruang horisontal, saya akan mencoba untuk membuka dokumen tambahan berdampingan dengan yang lain. Aku benci harus menggulir empat cara. Juga, saya sering memperhatikan bahwa saya dipaksa untuk menulis kode yang lebih mudah dibaca dengan tutup char 80.
Filip Dupanović

2
bagaimana Anda mencetaknya?

5
Maaf - harus menyetujui ini. Saya benar-benar benci garis panjang - itu membutuhkan lebih banyak gerakan mata, itu membutuhkan gerakan mouse untuk menggulir, lebih sulit untuk melihat hal-hal kecil yang halus di ujung garis. Dalam sekitar 99% kasus ada cara-cara bersih untuk membuat barang-barang tergilas pada beberapa baris (lebih pendek) yang lebih jelas dan lebih mudah dibaca. 80 Chars mungkin sewenang-wenang dan "karena memang seperti itu di hari kartu punch" tetapi masih kerangka kerja yang masuk akal untuk bekerja di dalam - sebagian besar waktu - untuk alasan di atas.
cepat,

3
Diindentasi oleh 2 spasi. Dan gunakan editor dengan pelacak indentasi otomatis. Saya sudah melakukannya seperti itu selama bertahun-tahun, bukan masalah besar. (Emacs dengan mode yang tepat membantu di sini.)
quick_now

5

Mengukur, Mengukur, Mengukur

Sangat bagus, ukur saja, tetapi untuk mengisolasi bug kinerja, pengukuran bekerja serta eliminasi berturut-turut. Inilah metode yang saya gunakan.

Saya sudah berusaha melacak sumber "kebijaksanaan" ukuran-ukuran. Seseorang dengan kotak sabun yang cukup tinggi mengatakannya, dan sekarang ia bepergian.


5

Guru saya menuntut saya memulai semua pengidentifikasi saya (tidak termasuk konstanta) dengan huruf kecil, misalnya myVariable.

Saya tahu ini sepertinya hal kecil, tetapi banyak bahasa pemrograman memerlukan variabel untuk memulai dengan huruf besar. Saya menghargai konsistensi, jadi kebiasaan saya memulai semuanya dengan huruf besar.


9
Saya punya guru yang memerlukan camelCase karena dia bersikeras bahwa itulah yang digunakan orang di dunia nyata ... Pada saat yang sama saya memprogram dalam dua kelompok berbeda di tempat kerja saya - kedua kelompok bersikeras pada under_scores. Yang penting adalah apa yang digunakan grup Anda. Dia bisa mendefinisikan dirinya sebagai programmer utama dan semua akan baik-baik saja di buku saya - kita mengikuti konvensi-nya - tetapi dia selalu memberikan pendapatnya sebagai "cara dilakukan di dunia nyata" seolah-olah tidak ada yang lain yang valid cara.
xnine

@ xnine Saya belum punya cukup perwakilan di situs ini untuk menilai komentar Anda, jadi saya hanya akan membalas dengan komentar persetujuan ini.
Maks.

5
Casing unta (huruf kecil pertama) adalah konvensi yang cukup umum serta huruf Pascal (huruf pertama dari setiap kata ditulis dengan huruf besar). Dalam sebagian besar bahasa, camelCase digunakan pada variabel pribadi / internal di mana PascalCase digunakan pada kelas, metode, properti, ruang nama, variabel publik. Ini bukan praktik yang buruk untuk terbiasa hanya siap untuk proyek yang mungkin menggunakan skema penamaan yang berbeda.
Evan Plaice

2
Hanya FYI. Beberapa bahasa menyimpulkan makna dari apakah huruf pertama suatu variabel adalah kapital atau bukan. Dalam satu bahasa seperti itu, jika huruf pertama adalah huruf kapital variabel diperlakukan sebagai konstanta - setiap upaya untuk mengubahnya akan menimbulkan kesalahan.
Berin Loritsch

1
Di Go , metode umum dan anggota di kelas dimulai dengan huruf besar; yang pribadi dengan huruf kecil.
Jonathan Leffler

5

Gunakan Lajang

Ketika Anda hanya harus memiliki satu contoh dari sesuatu. Saya tidak bisa tidak setuju lagi. Jangan pernah menggunakan singleton dan hanya mengalokasikannya sekali dan melewati pointer / objek / referensi yang diperlukan. Sama sekali tidak ada alasan untuk tidak melakukan ini.


2
Itu sejumlah negatif yang membuat saya agak bingung tentang sikap Anda yang sebenarnya tentang lajang.
Paul Butcher

1
@Paul Butcher: Saya benci lajang dan itu tidak boleh digunakan

1
@ rwong: Secara pribadi saya tidak berpikir alasan apa pun adalah alasan yang sah. Tulis saja sebagai kelas normal. Sungguh, tidak ada alasan untuk menggunakan singleton selain kemalasan dan untuk mempromosikan kebiasaan atau desain yang buruk.

6
Siapa bilang menggunakan Singeltons adalah praktik terbaik?
Phil Mander

2
Lajang memang memiliki tempat mereka, terutama dalam kasus di mana struktur operasional dialokasikan dan diisi pada startup, maka pada dasarnya menjadi hanya dibaca sepanjang waktu menjalankan program. Dalam hal ini, itu hanya menjadi cache di sisi lain dari sebuah pointer.
Tim Post

5

Menggunakan unsigned int sebagai iterator

Kapan mereka akan belajar bahwa menggunakan int yang ditandatangani jauh lebih aman dan lebih sedikit rawan bug. Mengapa sangat penting bahwa indeks array hanya dapat berupa angka positif, sehingga semua orang senang mengabaikan kenyataan bahwa 4 - 5 adalah 4294967295?


Oke, sekarang saya ingin tahu - mengapa Anda mengatakan itu? Saya merasa sedikit bodoh - dapatkah Anda memberikan beberapa contoh kode untuk mendukung pernyataan Anda?
Paul Nathan

4
@ Paul Nathan: sejauh buggyness berikut adalah salah satu contoh: untuk (unsigned int i = 0; i <10; i ++) {int crash_here = my_array [maks (i-1,0)];}
AareP

@AareP: Yang pasti - saya kira Anda merujuk fakta bahwa ketika int unsigned 0dikurangi oleh 1, Anda benar-benar berakhir dengan nilai positif maksimum yang disimpan oleh int unsigned?
Adam Paynter

1
@Adam Paynter: ya. Ini mungkin tampak normal untuk programmer c ++, tetapi mari kita hadapi itu, "unsigned int" adalah salah satu "implementasi" buruk dari angka positif saja.
AareP

Bukan ide yang baik pada mesin embedded kecil - int yang sering tidak ditandatangani akan menghasilkan kode yang lebih kecil dan lebih cepat. Tergantung pada kompiler dan prosesor.
cepat,

4

Metode seharusnya tidak lebih dari satu layar

Saya setuju dengan prinsip tanggung jawab tunggal sepenuhnya tetapi mengapa orang menganggapnya berarti "suatu fungsi / metode tidak dapat lebih dari satu tanggung jawab tunggal pada tingkat granularitas logis terbaik"?

Idenya sederhana. Fungsi / metode harus menyelesaikan satu tugas. Jika bagian dari fungsi / metode itu dapat digunakan di tempat lain, potonglah ke fungsi / metode itu sendiri. Jika itu dapat digunakan di tempat lain pada proyek, pindahkan ke kelasnya sendiri atau kelas utilitas dan membuatnya dapat diakses secara internal.

Memiliki kelas yang berisi 27 metode pembantu yang hanya dipanggil satu kali dalam kode adalah bodoh, buang-buang ruang, peningkatan kompleksitas yang tidak perlu, dan tenggang waktu yang sangat besar. Kedengarannya lebih seperti aturan yang baik untuk orang-orang yang ingin terlihat sibuk mengembalikan kode tetapi tidak menghasilkan banyak.

Ini peraturan saya ...

Tulis fungsi / metode untuk mencapai sesuatu

Jika Anda menemukan diri Anda akan menyalin / menempelkan beberapa kode, tanyakan pada diri Anda apakah akan lebih baik untuk membuat fungsi / metode untuk kode itu. Jika suatu fungsi / metode hanya dipanggil satu kali pada fungsi / metode lain, apakah benar-benar ada gunanya memilikinya di tempat pertama (akan lebih sering dipanggil di masa depan). Apakah berharga untuk menambahkan lebih banyak lompatan keluar / keluar dari fungsi / metode selama debugging (Yaitu, apakah lompatan yang ditambahkan membuat debugging lebih mudah atau lebih sulit)?

Saya sepenuhnya setuju bahwa fungsi / metode yang lebih besar dari 200 baris perlu diteliti tetapi beberapa fungsi hanya menyelesaikan satu tugas dalam banyak baris dan tidak mengandung bagian yang berguna yang dapat diabstraksi / digunakan pada sisa proyek.

Saya melihatnya dari perspektif pengembang API ... Jika pengguna baru melihat diagram kelas dari kode Anda, berapa banyak bagian dari diagram itu yang masuk akal dalam keseluruhan proyek yang lebih besar dan berapa banyak yang akan ada hanya sebagai pembantu ke bagian lain di dalam proyek.

Jika saya memilih antara dua programmer: yang pertama memiliki kecenderungan untuk menulis fungsi / metode yang mencoba melakukan terlalu banyak; yang kedua memecah setiap bagian dari setiap fungsi / metode ke tingkat granularity terbaik; Saya akan memilih tangan pertama ke bawah. Yang pertama akan mencapai lebih banyak (yaitu, menulis lebih banyak daging dari aplikasi), kodenya akan lebih mudah untuk di-debug (karena lebih sedikit lompatan masuk / keluar dari fungsi / metode selama debugging), dan dia akan membuang lebih sedikit waktu melakukan pekerjaan yang sibuk menyempurnakan cara kode terlihat vs menyempurnakan cara kerja kode.

Batasi abstraksi yang tidak perlu dan jangan mencemari autocomplete.


Ini. Saya pernah refactored beberapa fungsi panjang menjadi beberapa, hanya untuk menyadari bahwa hampir semua dari mereka membutuhkan hampir semua parameter dari kode asli. Penanganan parameter sangat menyakitkan sehingga lebih mudah untuk kembali ke kode lama.
l0b0

3
Saya pikir satu argumen kontra untuk ini adalah bahwa refactoring bagian dari metode besar menjadi panggilan terpisah dapat membuat metode yang lebih besar lebih mudah dibaca. Bahkan jika metode ini hanya dipanggil sekali.
Jeremy Heiler

1
@ Jeremy Bagaimana? Bagaimana caranya, mengabstraksi bagian kode dan menempatkannya dalam metode sendiri membuatnya lebih mudah dibaca daripada hanya menempatkan komentar satu baris di bagian atas potongan kode yang menggambarkan apa yang dilakukannya? Dengan asumsi bahwa blok kode hanya digunakan satu kali di bagian kode itu. Apakah benar - benar sulit bagi sebagian besar programmer untuk menguraikan bagian-bagian yang berfungsi dari kode ketika mereka membacanya dan / atau menempatkan beberapa komentar satu baris untuk mengingatkan mereka apa yang dilakukannya jika mereka tidak bisa?
Evan Plaice

4
@ Evan: Menempatkan potongan kode ke dalam fungsi secara efektif memberi mereka nama , semoga menjelaskan apa yang dilakukan potongan kode itu. Sekarang, di mana pun potongan kode itu dipanggil, Anda dapat melihat nama yang menjelaskan apa yang dilakukan kode tersebut , alih-alih harus menganalisis dan memahami algoritme itu sendiri. Jika dilakukan dengan baik, ini dapat memudahkan membaca dan memahami kode dengan luar biasa.
sbi

1
+1 dan saya akan memberi lebih banyak jika saya bisa. Sama sekali tidak ada yang salah dengan segumpal kode C yang 1000 baris dalam satu fungsi (misalnya parser dengan saklar besar ()) DIBERIKAN maksudnya jelas dan sederhana. Menghancurkan semua bagian kecil dan memanggil mereka hanya membuat hal itu lebih sulit untuk dipahami. Tentu saja ada batasan untuk ini juga .... penilaian yang masuk akal adalah segalanya.
cepat,
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.