Jadilah liberal dalam apa yang Anda terima ... atau tidak?


45

[Penafian: pertanyaan ini subjektif, tapi saya lebih suka mendapatkan jawaban yang didukung oleh fakta dan / atau refleksi]

Saya pikir semua orang tahu tentang Prinsip Robustness , biasanya disimpulkan oleh Hukum Postel:

Bersikaplah konservatif dalam apa yang Anda kirim; menjadi liberal dalam apa yang Anda terima.

Saya setuju bahwa untuk desain protokol komunikasi yang luas ini mungkin masuk akal (dengan tujuan memungkinkan ekstensi mudah), namun saya selalu berpikir bahwa penerapannya pada HTML / CSS adalah kegagalan total, setiap browser menerapkan tweak diam sendiri deteksi / perilaku, membuatnya hampir tidak mungkin untuk mendapatkan rendering yang konsisten di beberapa browser.

Saya perhatikan bahwa ada RFC protokol TCP yang dianggap "Kegagalan Diam" dapat diterima kecuali ditentukan lain ... yang merupakan perilaku yang menarik, untuk sedikitnya.

Ada contoh lain dari penerapan prinsip ini di seluruh perdagangan perangkat lunak yang secara teratur muncul karena mereka telah menggigit pengembang, dari atas kepala saya:

  • Penyisipan semi-kolon Javascript
  • C (diam) konversi bawaan (yang tidak akan terlalu buruk jika tidak terpotong ...)

dan ada alat untuk membantu menerapkan perilaku "pintar":

Namun saya menemukan bahwa pendekatan ini, walaupun mungkin bermanfaat ketika berhadapan dengan pengguna non-teknis atau untuk membantu pengguna dalam proses pemulihan kesalahan, memiliki beberapa kelemahan ketika diterapkan pada desain antarmuka perpustakaan / kelas:

  • agak subyektif apakah algoritme menebak "benar", dan karena itu mungkin bertentangan dengan Prinsip Ketertinggalan Terkecil
  • itu membuat implementasi lebih sulit, sehingga lebih banyak peluang untuk memperkenalkan bug (pelanggaran YAGNI ?)
  • itu membuat perilaku lebih rentan terhadap perubahan, karena setiap modifikasi dari rutinitas "tebak" dapat merusak program lama, hampir tidak termasuk kemungkinan refactoring ... sejak awal!

Dan inilah yang membawa saya ke pertanyaan berikut:

Saat mendesain antarmuka (perpustakaan, kelas, pesan), apakah Anda condong ke arah prinsip kekokohan atau tidak?

Saya sendiri cenderung cukup ketat, menggunakan validasi input yang luas pada antarmuka saya, dan saya bertanya-tanya apakah saya mungkin terlalu ketat.


Saya bertanya-tanya apa perbedaan antara HTML dan data umum? Prinsip ketahanan adalah tentang komunikasi. Satu menulis - satu membaca. Mengapa komunikasi jaringan berbeda dari visual atau API? Saya memiliki contoh API di mana prinsip menjadi liberal dengan apa yang kami terima menyederhanakan kehidupan pengguna yang merupakan programmer , mengurangi ukuran kode dan, karenanya, meningkatkan kinerja + menghilangkan bug. Lihat stackoverflow.com/questions/18576849
Val

@ Val: sebenarnya, contoh Anda tidak cocok. "menjadi liberal dalam apa yang Anda terima" bukan hanya masalah basis / turunan, itu lebih dari itu dan juga menerima (dan menafsirkan) input yang sedikit keliru.
Matthieu M.

Bagaimana menunjukkan beberapa kasus tidak menunjukkan kasus itu?
Val

Jawaban:


34

Saya akan mengatakan ketahanan ketika itu tidak menimbulkan ambiguitas .

Misalnya: Saat menguraikan daftar yang dipisahkan koma, ada atau tidaknya spasi sebelum / sesudah koma tidak mengubah makna semantik.

Saat mem-parsing string guide, ia harus menerima sejumlah format umum (dengan atau tanpa tanda hubung, dengan atau tanpa kurung kurawal di sekitarnya).

Sebagian besar bahasa pemrograman kuat dengan penggunaan ruang putih. Khususnya di mana saja yang tidak memengaruhi arti kode. Bahkan di Python di mana spasi putih relevan, itu masih fleksibel ketika Anda berada di dalam daftar atau deklarasi kamus.

Saya benar-benar setuju bahwa jika sesuatu dapat diartikan dengan berbagai cara atau jika tidak 100% jelas apa yang dimaksud maka terlalu banyak ketahanan dapat berakhir menjadi rasa sakit, tetapi ada banyak ruang untuk ketahanan tanpa menjadi ambigu.


1
Saya setuju, kekokohan ketika tidak membutuhkan banyak biaya adalah berharga.
Matthieu M.

2
Bahkan daftar yang dipisahkan koma menyebabkan masalah, seperti: mesin javascript chrome dan firefox tampaknya menerima {"key": "value",}valid, IE tidak. Saya sering menemukan masalah khusus ini sampai saya meningkatkan proses pembangunan saya dengan JSlint.
keppla

2
@keppla itu masalah implementasi daripada desain. Saya tidak yakin apakah itu legal oleh spesifikasi javascript dan IE tidak mengikuti, atau jika itu adalah "fitur bagus" yang ditambahkan FF dan Chrome, tetapi dalam Python itu ditentukan untuk valid dan diimplementasikan seperti itu. Jika itu ditetapkan sebagai valid dan tidak berfungsi, maka itu adalah implementasi yang salah. Jika tidak ditentukan maka seharusnya tidak benar-benar diandalkan (meskipun sebagai kepraktisan jika tidak bekerja di browser utama, mungkin juga dianggap tidak ada dalam spesifikasi jika Anda tidak mengontrol pengguna)
Davy8

7
@ Davy8: Trailing koma tampaknya ilegal ( stackoverflow.com/questions/5139205/… ). Saya tidak ingin mengandalkan ini, maksud saya adalah, ketika cukup banyak orang menerima input, itu menjadi standar de-facto (karena orang tidak melihat bahwa itu adalah kesalahan), yang mengarah ke sesuatu yang kami temui dalam HTML: bahwa kesalahan menjadi begitu biasa sehingga Anda tidak bisa mengabaikannya sebagai input yang buruk lagi.
keppla

1
@keppla, itu seharusnya gagal di bulan lalu dan Chrome. Sebagai JS dev utama, itu membuatku kesal bahwa itu tidak (dulu di Moz setidaknya). Itu membuat debug lebih sulit, tidak mudah. IE melakukan apa yang seharusnya dilakukan. Gagal @ kode buruk. HTML adalah satu hal. Kami tidak perlu omong kosong ini dalam bahasa scripting. Ini adalah contoh penerapan mengerikan dari prinsip Robust, yang merupakan keunggulan vendor browser.
Erik Reppen

15

Tentu saja tidak. Teknik seperti pemrograman defensif mengaburkan bug, membuat penampilan mereka lebih kecil kemungkinannya dan lebih acak yang membuat deteksi mereka lebih sulit yang membuat mengisolasi mereka lebih sulit.

Writing Solid Code yang jauh di bawah rata-rata luar biasa dalam berulang kali menekankan perlunya, dan teknik, membuat bug sebagai sulit untuk diperkenalkan atau disembunyikan. Melalui penerapan prinsip-prinsipnya seperti, "Menghilangkan perilaku acak. Memaksa serangga untuk direproduksi." dan, "Selalu mencari, dan menghilangkan, cacat pada antarmuka Anda." pengembang akan sangat meningkatkan kualitas perangkat lunak mereka dengan menghilangkan ambiguitas dan efek samping yang tidak terkendali yang bertanggung jawab atas sejumlah besar bug.


9

Penerapan Robustness yang berlebihan menyebabkan Anda menebak apa yang diinginkan pengguna, yang baik-baik saja sampai Anda salah. Ini juga membutuhkan keyakinan yang sepenuhnya salah arah bahwa pelanggan Anda tidak akan menyalahgunakan kepercayaan Anda dan menciptakan omong kosong acak yang kebetulan bekerja, tetapi Anda tidak akan dapat mendukung dalam versi 2.

Penerapan Berlebihan yang berlebihan menyebabkan Anda menyangkal pelanggan Anda memiliki hak untuk membuat kesalahan kecil, yang baik-baik saja sampai mereka mengeluh bahwa barang-barang mereka berfungsi dengan baik pada produk pesaing Anda, dan memberi tahu Anda apa yang dapat Anda lakukan dengan standar 5.000 halaman Anda yang memiliki kata. "DRAFT" masih tertulis di sampul dalam krayon, dan setidaknya 3 ahli mengklaim secara mendasar cacat, dan 200 ahli yang lebih jujur ​​mengatakan mereka tidak sepenuhnya mengerti.

Solusi pribadi saya selalu usang. Anda mendukung mereka, tetapi memberi tahu mereka bahwa mereka melakukan kesalahan, dan (jika mungkin) jalan termudah menuju kebenaran. Dengan begitu, ketika Anda mematikan fitur bug 10 tahun ke depan, Anda setidaknya memiliki jejak kertas untuk menyatakan bahwa "kami memperingatkan Anda bahwa ini mungkin terjadi."


1 untuk penghentian , itu memang konsep yang penting dan saya terkejut bahwa itu diabaikan sampai sekarang.
Matthieu M.

9

Sayangnya apa yang disebut "prinsip ketahanan" tidak mengarah pada ketahanan. Ambil HTML sebagai contoh. Banyak masalah, air mata, buang-buang waktu dan energi bisa dihindari jika browser telah benar-benar mem-parsing HTML dari awal alih-alih mencoba menebak arti konten yang cacat.

Browser seharusnya hanya menampilkan pesan kesalahan daripada mencoba memperbaikinya di bawah selimut. Itu akan memaksa semua bunglers untuk memperbaiki kekacauan mereka.


Mengutip diri saya sendiri (pasti sudah tua): "namun saya selalu berpikir bahwa penerapannya pada HTML / CSS adalah kegagalan total"
Matthieu M.

3
Benar, tetapi toleransi kesalahan yang sama juga membantu membuat web begitu populer.
MaR

Vendor browser gagal pada yang itu. Dengan DOCTYPE kami memiliki kemampuan untuk membuat pilihan kami sendiri dalam hal ini, tetapi pada akhirnya mereka semuanya cukup banyak berperilaku dengan cara yang sama selama Anda memiliki DOCTYPE dinyatakan. Sekarang mereka berpikir seperangkat aturan menuntut yang sangat rumit untuk diikuti sehubungan dengan bagaimana menangani kegagalan adalah solusinya? Saya pikir mereka gagal mengidentifikasi masalah.
Erik Reppen

Anda mengatakan bahwa kegagalan-cepat, yang merupakan kebalikan dari "robust" lebih efisien.
Val

@ MAr: Begitukah? Sangat diperdebatkan, jauh lebih besar kemungkinan fitur-fiturnya penting.
Deduplicator

6

Saya membagi antarmuka menjadi beberapa grup (tambahkan lebih banyak jika Anda suka):

  1. mereka yang berada di bawah kendali Anda harus ketat (kelas biasanya)
  2. API perpustakaan, yang juga harus pada sisi yang ketat, tetapi validasi tambahan disarankan
  3. antarmuka publik yang harus menangani setiap jenis penyalahgunaan yang datang (biasanya protokol, input pengguna, dll). Di sini ketahanan input benar-benar terbayar, Anda tidak bisa berharap semua orang akan memperbaiki barang-barang mereka. Dan ingat bagi pengguna itu akan menjadi kesalahan Anda jika aplikasi tidak berfungsi, bukan pihak yang mengirim omong kosong berformat buruk.

Keluaran harus selalu ketat.


5

Saya pikir HTML dan World Wide Web telah memberikan uji skala dunia nyata dari Prinsip Robustness dan menunjukkannya sebagai kegagalan besar. Ini secara langsung bertanggung jawab atas kekacauan membingungkan dari hampir-standar HTML bersaing yang membuat hidup sengsara bagi pengembang Web (dan pengguna mereka) dan menjadi lebih buruk dengan setiap rilis Internet Explorer baru.

Kami sudah tahu sejak 1950-an cara memvalidasi kode dengan benar. Jalankan melalui parser ketat dan jika ada sesuatu yang tidak benar secara sintaksis, lemparkan kesalahan dan batalkan. Jangan lulus pergi, jangan mengumpulkan $ 200, dan untuk cinta semua yang biner jangan biarkan beberapa program komputer mencoba membaca pikiran pembuat kode jika ia membuat kesalahan!

HTML dan JavaScript telah menunjukkan kepada kita apa yang terjadi ketika prinsip-prinsip itu diabaikan. Tindakan terbaik adalah belajar dari kesalahan mereka dan tidak mengulanginya.


4
@ChaosPandion: masalahnya bukan terletak pada Internet Explorer itu sendiri, saya pikir, tetapi dengan semua halaman web non-standar yang diterima oleh versi sebelumnya dan bahwa setiap orang sekarang harus hidup dengan ... dan mencoba untuk mengakomodasi lebih atau kurang berhasil.
Matthieu M.

5
Saya benar-benar berpikir tim IE berada dalam posisi terburuk dari semua pengembang browser. Joel meringkas pikiranku dengan cukup baik .
Dean Harding

3
Ini mungkin telah membuat hidup sengsara bagi para pengembang dan perancang, tetapi kemudian kita akan terjebak dengan standar yang sangat lambat berkembang dan statis - Saya ragu web akan seperti sekarang. Pemenang sebenarnya adalah orang-orang yang menelusuri web dan pada akhirnya mereka adalah orang-orang yang menghitung.
FinnNk

4
Juga, sementara prinsip Robustness dapat membuat hidup sulit bagi Pengembang Web, sulit untuk menyebut World Wide Web (sekarang menjadi bagian integral dari hampir setiap lembaga besar di planet ini) KEGAGALAN masif .
deworde

3
"Kami sudah tahu sejak 1950-an cara memvalidasi kode dengan benar. Jalankan melalui parser ketat dan jika ada sesuatu yang tidak benar secara sintaksis, lemparkan kesalahan dan batalkan." Untuk menerapkan ini pada skenario dunia nyata: Jika saya telah mengacaukan satu ikon di ujung kanan halaman saya tepat di bawah potongan, menyerah pada seluruh halaman adalah cara yang sangat baik untuk mengirim seseorang mencari ke tempat lain, karena masalah mereka bahkan tidak akan memperhatikan. Ya, Anda dapat berdebat bahwa saya seharusnya tidak melakukan kesalahan. Tapi itu agaknya mengandaikan saya belum pergi ke pesaing Anda yang lebih kuat dan tidak lagi menerima telepon Anda.
deworde

3

Sebagai tandingan dengan contoh Mason, pengalaman saya dengan Protokol Inisiasi Sesi adalah bahwa sementara tumpukan yang berbeda akan menafsirkan RFC yang relevan secara berbeda (dan saya menduga ini terjadi dengan setiap standar yang pernah ditulis), menjadi (cukup) liberal dalam apa yang Anda terima berarti Anda sebenarnya dapat membuat panggilan antara dua perangkat. Karena perangkat ini adalah hal-hal fisik biasa yang bertentangan dengan perangkat lunak pada desktop, Anda hanya harus liberal dalam apa yang Anda terima, atau ponsel Anda tidak dapat memanggil telepon lain dari merek tertentu. Itu tidak membuat ponsel Anda terlihat bagus!

Tetapi jika Anda menulis perpustakaan, Anda mungkin tidak memiliki masalah banyak pihak yang menafsirkan standar umum dengan cara yang tidak kompatibel satu sama lain. Dalam hal ini, saya akan mengatakan tegas dalam apa yang Anda terima, karena menghilangkan ambiguitas.

File Jargon juga memiliki cerita horor tentang "menebak" maksud pengguna.


Cerita yang sangat lucu :) Saya menyadari bahwa Anda mungkin perlu lebih banyak waktu luang ketika mencoba berinteraksi dengan sistem yang ada, karena jika tidak berhasil Anda akan disalahkan.
Matthieu M.

Faktanya, jika ponsel Anda tidak berfungsi dengan kebanyakan ponsel lain, ponsel Anda buruk .
SamB

1
@SamB: Ganti buruk dengan rusak .
deworde

3

Anda benar, aturan berlaku untuk protokol, dan bukan pemrograman. Jika Anda membuat kesalahan ketik saat pemrograman, Anda akan mendapatkan kesalahan segera setelah dikompilasi (atau dijalankan, jika Anda salah satu dari tipe dinamis itu). Tidak ada yang bisa diperoleh dengan membiarkan komputer menebak untuk Anda. Berbeda dengan rakyat biasa, kami adalah insinyur dan mampu mengatakan dengan tepat apa yang saya maksud. ;)

Jadi, ketika merancang API, saya akan mengatakan jangan ikuti Prinsip Robustness. Jika pengembang membuat kesalahan, mereka harus segera mengetahuinya. Tentu saja, jika API Anda menggunakan data dari sumber luar, seperti file, Anda harus bersikap lunak. Pengguna perpustakaan Anda harus mencari tahu tentang kesalahannya sendiri, tetapi bukan kesalahan orang lain.

Sebagai tambahan, saya akan menebak bahwa "kegagalan diam" diperbolehkan dalam protokol TCP karena jika tidak, jika orang melempar paket yang salah kepada Anda, Anda akan dibombardir dengan pesan kesalahan. Itu perlindungan DoS sederhana di sana.


1
"Jika Anda membuat kesalahan ketik saat pemrograman, Anda akan mendapatkan kesalahan segera setelah Anda kompilasi" Saya menyajikan kepada Anda jutaan kompiler PERINGATAN kompiler standar akan meludahkan, sambil tetap menghasilkan tugas yang dapat dieksekusi dengan sempurna.
deworde

1

IMO, ketahanan adalah satu sisi trade-off desain bukan prinsip "prefer". Seperti yang telah ditunjukkan banyak orang, tidak ada yang berbau seperti meniup empat jam mencoba mencari tahu di mana JS Anda salah hanya untuk menemukan masalah sebenarnya adalah hanya satu browser melakukan hal yang benar dengan XHTML Strict. Itu membiarkan halaman berkeping-keping ketika sebagian dari HTML yang disajikan adalah bencana total.

Di sisi lain, siapa yang ingin mencari dokumentasi untuk metode yang membutuhkan 20 argumen dan bersikeras mereka berada dalam urutan yang sama persis dengan tempat kosong atau nol nilai tempat yang ingin Anda lewati? Cara kuat yang sama buruknya untuk menangani metode itu adalah dengan memeriksa setiap arg dan mencoba menebak mana yang berdasarkan posisi dan tipe relatif dan kemudian gagal diam-diam atau mencoba "melakukan" dengan arg yang tidak bermakna.

Atau Anda dapat memanggang fleksibilitas ke dalam proses dengan melewati daftar pasangan objek literal / kamus / nilai kunci dan menangani keberadaan setiap arg saat Anda mendapatkannya. Untuk tradeoff perf sangat kecil, itu kue dan memakannya juga skenario.

Membebani argumen dengan cara yang cerdas dan konsisten antarmuka adalah cara cerdas untuk menjadi tangguh dalam hal-hal. Begitu pula memanggang redundansi ke dalam sistem di mana diasumsikan pengiriman paket akan secara rutin gagal dikirim dalam jaringan yang sangat besar yang dimiliki dan dijalankan oleh semua orang di bidang teknologi yang sedang berkembang dengan berbagai macam sarana potensial untuk transmisi.

Namun, toleransi kegagalan hina, terutama dalam sistem yang Anda kontrol, tidak pernah merupakan pertukaran yang baik. Sebagai contoh, saya harus mengambil nafas untuk menghindari melemparkan desisan dalam pertanyaan lain tentang menempatkan JS di bagian atas atau bawah halaman. Beberapa orang bersikeras bahwa lebih baik untuk menempatkan JS di atas karena jika halaman gagal memuat sepenuhnya, Anda masih berpotensi memiliki beberapa fungsi. Halaman setengah bekerja lebih buruk daripada payudara lengkap. Paling-paling, mereka menghasilkan lebih banyak pengunjung ke situs Anda dengan benar dengan asumsi Anda tidak kompeten sebelum Anda mengetahuinya daripada jika halaman rusak hanya terpental ke halaman kesalahan setelah gagal itu sendiri validasi cek diikuti oleh email otomatis untuk seseorang yang bisa melakukan sesuatu.

Mencoba untuk memberikan fungsionalitas 2010 pada browser 1999 ketika Anda bisa memberikan halaman teknologi yang lebih rendah adalah contoh lain dari tradeoff desain yang bodoh. Peluang meledak dan uang yang saya lihat terbuang pada waktu yang dihabiskan pengembang untuk mengatasi bug hanya untuk mendapatkan sudut bulat pada elemen melayang di atas latar belakang gradien! @ # $ Ing misalnya, telah benar-benar mengejutkan saya. Dan untuk apa? Untuk memberikan halaman teknologi lebih tinggi yang berkinerja buruk ke technophobes yang terbukti sambil membatasi pilihan Anda pada browser yang lebih tinggi.

Agar itu menjadi pilihan yang tepat, pilihan untuk menangani input dengan cara yang kuat harus selalu membuat hidup lebih mudah di kedua sisi masalah, dalam jangka pendek dan jangka panjang IMO.


4
"untuk metode yang membutuhkan 20 argumen"> tidak perlu melihat lebih jauh, setelah 5/6 metode tersebut salah . Terima kasih atas jawabannya :)
Matthieu M.

1

Jangan pernah gagal diam-diam . Selain itu, mencoba menebak apa yang diinginkan pengguna API / perpustakaan, tidak terdengar seperti ide yang buruk. Saya tidak akan mengikutinya; memiliki persyaratan yang ketat, dapat mengekspos bug dalam kode panggilan dan / atau salah tafsir tentang API / perpustakaan Anda.

Lebih jauh, seperti yang telah ditunjukkan, itu tergantung pada seberapa sulit untuk benar-benar menebak apa yang diharapkan pengguna. Jika sangat mudah, maka Anda memiliki dua kasus:

  1. Pustaka Anda harus dirancang sedikit berbeda (ubah nama beberapa fungsi atau bagi dua), sehingga pengguna dapat mengharapkan apa yang sebenarnya Anda berikan.
  2. Jika Anda yakin bahwa perpustakaan Anda dirancang dengan benar, artinya penamaan yang jelas / langsung, maka Anda dapat mencoba menyimpulkan apa yang dimaksudkan pengguna.

Dalam hal apapun itu tidak 100% jelas dan deterministik, bahwa satu input harus dikonversi ke yang lain, Anda tidak boleh melakukan konversi, karena sejumlah alasan yang telah disebutkan (melanggar kompatibilitas pada refactoring, paling mengejutkan pengguna).

Ketika berhadapan dengan pengguna akhir, mencoba memperbaiki input / tebakan mereka sangat disambut baik. Dia diharapkan memasukkan informasi yang tidak valid; kasus ini sama sekali tidak eksklusif. Pengembang lain, bukan pengguna non teknis yang sederhana. Dia memiliki keahlian untuk memahami kesalahan, dan kesalahan itu dapat memiliki arti / bermanfaat baginya. Jadi, saya setuju dengan Anda untuk merancang API yang ketat, sementara -tentu saja- ketegasan disertai dengan kejelasan dan kesederhanaan.

Saya akan merekomendasikan agar Anda membaca pertanyaan saya ini , dari kasus serupa.

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.