Mengapa saya tidak boleh menggunakan "Notasi Hungaria"?

122

Saya tahu apa yang dimaksud dengan bahasa Hongaria - memberikan informasi tentang variabel, parameter, atau tipe sebagai awalan untuk namanya. Setiap orang tampaknya sangat menentangnya, meskipun dalam beberapa kasus tampaknya itu ide yang bagus. Jika saya merasa bahwa informasi yang berguna sedang diberikan, mengapa saya tidak meletakkannya di tempat yang tersedia?

Lihat juga: Apakah orang menggunakan konvensi penamaan Hongaria di dunia nyata?

Shog9
sumber

Jawaban:

174

Kebanyakan orang menggunakan notasi Hongaria dengan cara yang salah dan mendapatkan hasil yang salah.

Bacalah artikel luar biasa ini oleh Joel Spolsky: Membuat Kode yang Salah Terlihat Salah .

Singkatnya, Notasi Hongaria di mana Anda mengawali nama variabel Anda dengan type(string) (Bahasa Hungaria Sistem) buruk karena tidak berguna.

Notasi Hungaria seperti yang dimaksudkan oleh pembuatnya di mana Anda memberi awalan nama variabel dengan nya kind(menggunakan contoh Joel: string aman atau string tidak aman), yang disebut Apps Hungarian memiliki kegunaannya dan masih berharga.

Ilya Kochetov
sumber
5
Tautan bagus, ringkasan bagus tentang apa yang ada di balik tautan, dan tidak ada fanatisme. Luar biasa.
Dustman
12
Perhatikan bahwa contoh Joels ada di VBScript, bahasa yang lama tidak memiliki kelas yang ditentukan pengguna. Dalam bahasa-OO Anda hanya perlu membuat tipe-HtmlEncodedString dan metode Write menerima itu saja. "Apps hungarian" hanya berguna dalam bahasa tanpa jenis yang ditentukan pengguna.
JacquesB
4
Microsoft dikenal karena penyalahgunaan notasi Hongaria di masa lalu. Mempersiapkan informasi jenis untuk pengenal tidak hanya tidak berguna tetapi juga dapat membahayakan. Pertama, keterbacaan kurang lancar. Kedua, dalam bahasa yang mendukung polimorfisme atau pengetikan bebek, informasi yang salah disampaikan.
wilhelmtell
9
Saya masih suka menggunakan notasi Hungaria jika saya melakukan pengembangan C langsung dengan IDE yang lebih lama ... dengan cara itu saya tahu tidak ada masalah jenis casting.
Bip bip
3
@Krumia: Ini biasanya dicegah dengan memiliki nama variabel deskriptif sejak awal. Tetapi jika Anda ingin memastikan, akan jauh lebih aman untuk membuat tipe yang berbeda (mis. Struct) untuk panjang, bobot, dll. Dan menggunakan kelebihan beban operator untuk memastikan bahwa hanya operasi yang valid yang mungkin.
JacquesB
277

vMenggunakan adjHungarian nnotation vmake nreading ncode adjdifficult.

Mark Stock
sumber
101
Analogi yang bagus, meski sedikit tidak adil. Bandingkan: vMenggunakan adjHungarian nNotation vMakes nReading nCode adjDifficult.
Chris Noe
27
Dalam kalimat tersebut, Using dan Reading adalah gerund. Tapi saya mengerti maksud Anda ...
simpanse
28
@ simpanse: itu membuat segalanya menjadi lebih jelas. sekarang setelah Anda menemukan kesalahan dalam jenis, apakah Anda akan mengganti nama semua referensi atau membiarkannya sebagaimana adanya, memberikan informasi yang salah? Anda kalah dengan cara apa pun. tapi tentu saja, ini adalah cara yang SALAH dalam menerapkan notasi Hongaria.
wilhelmtell
1
@ Chris Noe: untuk gaya membaca tertentu (parse awalan dan akhiran dengan melihat ke tengah), contoh Anda hanya memperburuk keadaan. Saya melihat "vUsing" dan mendengar "voosing" di kepala saya.
Bob Cross
3
@ Jon: jika Anda memiliki nama variabel yang tidak sepenuhnya memberikan apa yang diwakilinya, maka fokusnya haruslah mengubah namanya menjadi sesuatu yang lebih deskriptif (dan notasi Hongaria bukanlah peningkatan, di bagian paling, sangat kasus terbaiknya adalah memperbaiki gejala - bukan menyelesaikan masalah).
hlovdal
104

Joel salah, dan inilah alasannya.

Informasi "aplikasi" yang dia bicarakan harus dikodekan dalam sistem tipe . Anda tidak boleh bergantung pada membalik nama variabel untuk memastikan Anda tidak meneruskan data yang tidak aman ke fungsi yang memerlukan data aman. Anda harus membuatnya menjadi kesalahan tipe, sehingga tidak mungkin untuk melakukannya. Setiap data yang tidak aman harus memiliki jenis yang ditandai tidak aman, sehingga tidak bisa diteruskan ke fungsi aman. Untuk mengubah dari tidak aman ke aman harus memerlukan pemrosesan dengan beberapa jenis fungsi sanitasi.

Banyak hal yang Joel sebut sebagai "jenis" bukanlah jenis; mereka sebenarnya adalah tipe.

Namun, yang tidak dimiliki sebagian besar bahasa adalah sistem tipe yang cukup ekspresif untuk memaksakan perbedaan semacam ini. Misalnya, jika C memiliki sejenis "strong typedef" (di mana nama typedef memiliki semua operasi jenis dasar, tetapi tidak dapat diubah ke dalamnya) maka banyak masalah ini akan hilang. Misalnya, jika Anda dapat mengatakan, strong typedef std::string unsafe_string;untuk memperkenalkan tipe baru unsafe_stringyang tidak dapat diubah menjadi std :: string (dan dapat berpartisipasi dalam resolusi kelebihan beban, dll.) Maka kita tidak memerlukan prefiks yang konyol.

Jadi, klaim utama bahwa bahasa Hongaria adalah untuk hal-hal yang bukan tipe adalah salah. Ini digunakan untuk informasi tipe. Informasi tipe yang lebih kaya daripada informasi tipe C tradisional, tentunya; itu jenis informasi yang menyandikan beberapa jenis detail semantik untuk menunjukkan tujuan objek. Tapi itu masih tipe informasi, dan solusi yang tepat selalu menyandikannya ke dalam sistem tipe. Mengkodekannya ke dalam sistem tipe adalah cara terbaik untuk mendapatkan validasi dan penegakan aturan yang tepat. Nama variabel tidak memotong mustard.

Dengan kata lain, tujuannya tidak boleh "membuat kode yang salah terlihat salah bagi pengembang". Ini harus "membuat kode yang salah terlihat salah untuk kompiler ".

DrPizza
sumber
30
Maksud dari variabel harus dikodekan dalam tipe variabel, tidak diserahkan pada sesuatu yang begitu rapuh seperti skema penamaan frigging.
DrPizza
3
Saya ingin menjadikannya pekerjaan kompiler / juru bahasa juga, tetapi itu akan menimbulkan biaya besar untuk bahasa dinamis (Python, Ruby, PHP atau Javascript).
terlalu banyak php
22
"Apa yang tidak dimiliki kebanyakan bahasa, bagaimanapun, adalah sistem tipe yang cukup ekspresif untuk menegakkan perbedaan semacam ini" Dan di sanalah masalahnya. AppsHungarian adalah metode pragmatis untuk menyoroti masalah saat menggunakan bahasa ini dengan cara yang jelas bagi pemrogram untuk melihat kode, daripada memeriksa laporan bug.
Neil Trodden
6
@DrPizza: Saya yakin Anda telah melewatkan salah satu poin sangat penting yang dibuat Joel saat mendukung Apps Hungarian: notasi ini hanyalah pertukaran yang sangat pragmatis . Membuat kompiler mampu melihat "kode yang salah" adalah tujuan yang bagus, tetapi apakah selalu sepadan dengan biayanya?
Yarik
4
@DrPizza: Joel is wrong, dan What most languages lack, however, is a type system that's expressive enough to enforce these kind of distinctions.Jadi, karena sebagian besar bahasa yang tidak memiliki cukup ekspresif untuk menegakkan semacam ini perbedaan, Joel adalah benar. Baik?
sampathsris
46

Saya pikir itu sangat mengacaukan kode sumber.

Itu juga tidak memberi Anda banyak manfaat dalam bahasa yang diketik dengan kuat. Jika Anda melakukan segala bentuk ketidakcocokan tipe tomfoolery, kompilator akan memberitahu Anda tentang hal itu.

nsanders
sumber
Wow. 90 repetisi dalam 15 menit. Panggilan yang bagus.
Penjaga sampah
2
Jika Anda menggunakannya untuk mengetik, maka ya, itu tidak berguna. Berguna untuk menyampaikan informasi lain.
Lou Franco
12
@ Lou, tepatnya - secara pribadi, saya menyimpan riwayat revisi dalam nama variabel saya: string firstName_wasName_wasNameID_wasSweetCupinCakes
Shog9
@nsanders: Coba gunakan compiler untuk memeriksa apakah Anda menggunakan satuan ukuran yang sama ketika kedua jenis variabel adalah integer.
Igor Levicki
1
@ Shog9: Saya pikir Anda tidak memahami Apps Hungarian Notation. Ini lebih tentang sFirstName vs unFirstName (aman vs tidak aman, tidak bersih), dengan cara ini Anda tahu lebih banyak tentangnya. Masih saya pikir dalam bahasa statis lebih baik untuk subtipe String untuk membuat UnsafeString dan SafeString dan hanya mengizinkan SafeString untuk keluar. Konvensi boleh saja, tetapi (lebih sering) penegakan kompilasi lebih baik.
kgadek
28

Notasi Hungaria hanya dapat digunakan dalam bahasa tanpa tipe yang ditentukan pengguna . Dalam fungsional modern atau bahasa OO, Anda akan menyandikan informasi tentang "jenis" nilai ke dalam tipe data atau kelas daripada ke dalam nama variabel.

Beberapa jawaban merujuk pada artikel Yoels . Namun perlu dicatat bahwa contohnya ada di VBScript, yang tidak mendukung kelas yang ditentukan pengguna (setidaknya untuk waktu yang lama). Dalam bahasa dengan tipe yang ditentukan pengguna, Anda akan memecahkan masalah yang sama dengan membuat tipe-HtmlEncodedString dan kemudian membiarkan metode Write hanya menerima itu. Dalam bahasa yang diketik secara statis, kompilator akan menangkap kesalahan pengkodean apa pun, dalam ketikan secara dinamis Anda akan mendapatkan pengecualian waktu proses - tetapi dalam hal apa pun Anda dilindungi dari penulisan string yang tidak dikodekan. Notasi Hongaria hanya mengubah pemrogram menjadi pemeriksa tipe manusia, dengan jenis pekerjaan yang biasanya lebih baik ditangani oleh perangkat lunak.

Joel membedakan antara "system hungarian" dan "apps hungarian", di mana "system hungarian" mengkodekan tipe built-in seperti int, float dan sebagainya, dan "apps hungarian" mengkodekan "kind", yang merupakan meta-info tingkat tinggi tentang variabel di sekitar jenis mesin, Dalam OO atau bahasa fungsional modern Anda dapat membuat jenis yang ditentukan pengguna, sehingga tidak ada perbedaan antara jenis dan "jenis" dalam hal ini - keduanya dapat diwakili oleh sistem jenis - dan "aplikasi" bahasa Hongaria sama mubazirnya dengan bahasa Hongaria "sistem".

Jadi untuk menjawab pertanyaan Anda: Bahasa Hongaria sistem hanya akan berguna dalam bahasa yang tidak aman dan diketik dengan lemah di mana misalnya menetapkan nilai float ke variabel int akan merusak sistem. Notasi Hongaria secara khusus ditemukan pada tahun enam puluhan untuk digunakan dalam BCPL , bahasa tingkat rendah yang tidak melakukan pengecekan tipe sama sekali. Saya tidak berpikir bahasa apa pun yang digunakan secara umum saat ini memiliki masalah ini, tetapi notasi tersebut hidup sebagai semacam pemrograman kultus kargo .

Aplikasi bahasa Hongaria akan masuk akal jika Anda bekerja dengan bahasa tanpa tipe yang ditentukan pengguna, seperti VBScript lama atau versi awal VB. Mungkin juga versi awal Perl dan PHP. Sekali lagi, menggunakannya dalam bahasa modern adalah kultus kargo murni.

Dalam bahasa lain, bahasa Hongaria jelek, berlebihan, dan rapuh. Ini mengulangi informasi yang sudah diketahui dari sistem tipe, dan Anda tidak boleh mengulanginya sendiri . Gunakan nama deskriptif untuk variabel yang mendeskripsikan maksud instance tipe tertentu ini. Gunakan sistem tipe untuk menyandikan invarian dan info meta tentang "jenis" atau "kelas" variabel - mis. jenis.

Poin umum dari artikel Joels - membuat kode yang salah terlihat salah - adalah prinsip yang sangat bagus. Namun perlindungan yang lebih baik terhadap bug adalah - jika memungkinkan - memiliki kode yang salah untuk dideteksi secara otomatis oleh kompilator.

JacquesB
sumber
Bahasa dengan jenis yang ditentukan pengguna tidak selalu praktis untuk menggunakan jenis alih-alih "jenis". Pertimbangkan awalan "c", "d", "ix" dari Joel's Apps Hungarian. Apakah Anda menggunakan tipe bilangan bulat khusus untuk itu, dalam setiap bahasa modern? Saya kira tidak. Karena bahasa modern masih belum memiliki tipe bilangan bulat kustom bawaan untuk indeks, hitungan, dan perbedaan antara dua angka. Selama kita masih menggunakan vanilla ints, Apps Hungarian akan menjadi tidak mubazir dan berguna.
Eldritch Conundrum
27

Saya selalu menggunakan notasi Hongaria untuk semua proyek saya. Saya merasa sangat membantu ketika saya berurusan dengan 100-an nama pengenal yang berbeda.

Sebagai contoh, ketika saya memanggil sebuah fungsi yang membutuhkan string, saya dapat mengetik 's' dan menekan control-space dan IDE saya akan menunjukkan dengan tepat nama variabel yang diawali dengan 's'.

Keuntungan lain, ketika saya memberi awalan u untuk unsigned dan i untuk int yang ditandatangani, saya langsung melihat di mana saya mencampur ditandatangani dan tidak ditandatangani dengan cara yang berpotensi berbahaya.

Saya tidak dapat mengingat berapa kali ketika dalam basis kode baris 75000 besar, bug disebabkan (oleh saya dan orang lain juga) karena penamaan variabel lokal sama dengan variabel anggota kelas itu. Sejak itu, saya selalu memberi awalan anggota dengan 'm_'

Ini pertanyaan tentang rasa dan pengalaman. Jangan mengetuknya sampai Anda mencobanya.

rep_movsd
sumber
1
Mengkodekan tanda masuk ke nama variabel sangat bagus ketika potongan kode benar-benar berurusan dengan tanda tangan. Menggunakan itu sebagai alasan untuk menegakkan konvensi untuk semua variabel hanyalah Domatisme IMHO.
Plumenator
Anda memiliki poin yang bagus dengan variabel anggota. Tetapi dalam bahasa seperti Python di mana Anda dipaksa untuk memenuhi syarat anggota dengan diri / objek ini diperdebatkan.
Plumenator
Itu hanya trik untuk membantu produktivitas. Sama seperti pelengkapan otomatis IDE. Tidak ada yang pada dasarnya jahat tentang itu. Saya percaya bahwa pembuat kode berpengalaman harus diizinkan menggunakan gaya mereka sendiri. Memaksa siapa pun untuk memilih gaya tertentu itu buruk. Saya bekerja sebagai pengembang tunggal sekarang, tetapi saya tidak akan menerapkan gaya pada siapa pun yang bekerja dengan saya kecuali mereka tidak memiliki gaya yang konsisten sejak awal.
rep_movsd
Jadi, Anda menggunakan konvensi penamaan untuk memfilter variabel, ya? Saya harus setuju bahwa ini agak pintar . :-) Namun, cara saya terhubung, titik jangkar (atau kriteria filter, jika Anda suka) selalu menjadi semantik bagi saya. Jarang jenisnya (kecuali itu adalah semantik). Saya harap itu masuk akal. TL; DR: Saya masih akan menamai variabel sesuai dengan apa yang mereka wakili daripada bagaimana mereka diwakili.
Plumenator
1
Saya memilih ini saat itu karena saya mendukung Hongaria. Sekarang saya menyesalinya, dan tidak akan pernah kembali ke awalan sesuatu ke variabel ..
nawfal
22

Anda lupa alasan nomor satu untuk memasukkan informasi ini. Ini tidak ada hubungannya dengan Anda, programmer. Itu ada hubungannya dengan orang yang turun jalan 2 atau 3 tahun setelah Anda meninggalkan perusahaan yang harus membaca hal itu.

Ya, IDE akan segera mengidentifikasi jenis untuk Anda. Namun, ketika Anda membaca beberapa kumpulan kode 'aturan bisnis' yang panjang, ada baiknya Anda tidak perlu berhenti sejenak pada setiap variabel untuk mengetahui jenisnya. Saat saya melihat hal-hal seperti strUserID, intProduct, atau guiProductID, waktu 'ramp up' menjadi lebih mudah.

Saya setuju bahwa MS bertindak terlalu jauh dengan beberapa konvensi penamaan mereka - Saya mengkategorikannya dalam tumpukan "terlalu banyak hal yang baik".

Konvensi penamaan adalah hal yang baik, asalkan Anda mematuhinya. Saya telah melewati cukup banyak kode lama yang membuat saya terus-menerus kembali untuk melihat definisi untuk begitu banyak variabel bernama serupa sehingga saya mendorong "casing unta" (seperti yang disebut di pekerjaan sebelumnya). Saat ini saya sedang mengerjakan pekerjaan yang memiliki ribuan baris kode ASP klasik yang benar-benar tidak dikomentari dengan VBScript dan itu adalah mimpi buruk mencoba mencari tahu.

David
sumber
Sebagai pengguna VIM (tanpa IDE, tanpa penyorotan, tanpa hover-tell-you-what-type), saya sama sekali tidak memahami argumen ini. Saya secara alami memahami bahwa variabel yang disebut name adalah string, dan variabel yang disebut i atau count adalah int. Apakah seseorang benar-benar membutuhkan sName dan iCount? Bagaimana itu benar-benar membantu? Saya berpendapat bahwa contoh id produk Anda adalah kasus khusus, dan mungkin itu akan baik-baik saja. Namun meskipun demikian, menjadi konsisten dan merepresentasikan ID produk dengan int atau string di mana-mana akan menjadi solusi yang jauh lebih baik, bukan? Keseluruhan penamaan tampaknya seperti penolakan.
MrFox
6
Ini untuk konsistensi. Ya, "nama" secara inheren menyiratkan sebuah string. Tapi apa yang Anda anggap sebagai "userid"? GUID? Tali? Bilangan bulat? Bahkan sesuatu seperti "acctno" bisa memiliki nilai 42 atau "23X". Dokumentasi cukup jarang di sebagian besar kode. Standar ini membantu programmer pemeliharaan sedikit.
David
1
@David Saya sangat setuju dengan jawaban Anda - mengetahui secara sekilas maksud dari variabel adalah alasan saya lebih memilih awalan juga, terlebih dalam bahasa dinamis seperti JS.
Daniel Sokolowski
10

Mengatasi karakter samar di awal setiap nama variabel tidak diperlukan dan menunjukkan bahwa nama variabel itu sendiri tidak cukup deskriptif. Kebanyakan bahasa memerlukan tipe variabel di deklarasi, sehingga informasi sudah tersedia.

Ada juga situasi di mana, selama pemeliharaan, tipe variabel perlu diubah. Contoh: jika variabel yang dideklarasikan sebagai "uint_16 u16foo" perlu menjadi 64-bit unsigned, salah satu dari dua hal akan terjadi:

  1. Anda akan memeriksa dan mengubah setiap nama variabel (pastikan untuk tidak memasukkan variabel yang tidak terkait dengan nama yang sama), atau
  2. Ubah saja jenisnya dan jangan ubah namanya, yang hanya akan menyebabkan kebingungan.
coledot
sumber
9

Joel Spolsky menulis postingan blog yang bagus tentang ini. http://www.joelonsoftware.com/articles/Wrong.html Pada dasarnya itu tidak membuat kode Anda lebih sulit untuk dibaca ketika IDE yang layak akan memberitahu Anda ingin ketik variabel ini jika Anda tidak dapat mengingat. Selain itu, jika Anda membuat kode Anda cukup terkotak-kotak, Anda tidak perlu mengingat variabel apa yang dideklarasikan sebagai tiga halaman ke atas.

Paul Tomblin
sumber
9

Bukankah ruang lingkup lebih penting daripada jenis hari ini, misalnya

* l for local
* a for argument
* m for member
* g for global
* etc

Dengan teknik modern refactoring kode lama, mencari dan mengganti simbol karena Anda mengubah jenisnya membosankan, kompilator akan menangkap perubahan jenis, tetapi sering tidak akan menangkap penggunaan ruang lingkup yang salah, konvensi penamaan yang masuk akal membantu di sini.

titanae
sumber
Kemudian lagi, kode mungkin seharusnya tidak terlalu bergantung pada cakupan. :-)
Plumenator
8

Tidak ada alasan mengapa Anda tidak harus membuat yang benar menggunakan notasi Hungaria. Ini tidak populer karena serangan balik yang berjalan lama terhadap penyalahgunaan notasi Hongaria, terutama di Windows API.

Di masa lalu yang buruk, sebelum sesuatu yang menyerupai IDE ada untuk DOS (kemungkinan besar Anda tidak memiliki cukup memori untuk menjalankan kompiler di bawah Windows, jadi pengembangan Anda dilakukan di DOS), Anda tidak mendapatkan bantuan dari mengarahkan mouse ke nama variabel. (Dengan asumsi Anda memiliki mouse.) Apa yang harus Anda tangani adalah fungsi callback event di mana semuanya diteruskan kepada Anda sebagai int 16-bit (WORD) atau 32-bit int (LONG WORD). Anda kemudian harus mentransmisikan parameter tersebut ke jenis yang sesuai untuk jenis peristiwa yang diberikan. Akibatnya, sebagian besar API hampir tanpa tipe.

Hasilnya, API dengan nama parameter seperti ini:

LRESULT CALLBACK WindowProc(HWND hwnd,
                            UINT uMsg,
                            WPARAM wParam,
                            LPARAM lParam);

Perhatikan bahwa nama wParam dan lParam, meskipun cukup mengerikan, sebenarnya tidak lebih buruk daripada menamakannya param1 dan param2.

Lebih buruk lagi, Window 3.0 / 3.1 memiliki dua jenis penunjuk, dekat dan jauh. Jadi, misalnya, nilai yang dikembalikan dari fungsi manajemen memori LocalLock adalah PVOID, tetapi nilai yang dikembalikan dari GlobalLock adalah LPVOID (dengan panjang 'L'). Bahwa notasi mengerikan kemudian mendapat diperpanjang sehingga l ong p ointer tali itu diawali lp , untuk membedakannya dari string yang memiliki hanya telah malloc'd.

Tidak mengherankan jika ada reaksi balik terhadap hal semacam ini.

dgvid
sumber
6

Notasi Hungaria dapat berguna dalam bahasa tanpa pemeriksaan jenis waktu kompilasi, karena akan memungkinkan pengembang untuk dengan cepat mengingatkan dirinya sendiri tentang bagaimana variabel tertentu digunakan. Itu tidak melakukan apa pun untuk kinerja atau perilaku. Ini seharusnya meningkatkan keterbacaan kode dan sebagian besar adalah masalah selera dan gaya pengkodean. Karena alasan inilah ia dikritik oleh banyak pengembang - tidak semua orang memiliki kabel yang sama di otak.

Untuk bahasa pemeriksa jenis waktu kompilasi, sebagian besar tidak berguna - menggulir ke atas beberapa baris akan mengungkapkan deklarasi dan dengan demikian mengetik. Jika variabel global atau blok kode Anda mencakup lebih dari satu layar, Anda memiliki masalah desain dan kegunaan kembali yang parah. Jadi salah satu kritiknya adalah bahwa Notasi Hongaria memungkinkan pengembang memiliki desain yang buruk dan dengan mudah lolos. Ini mungkin salah satu alasan dibenci.

Di sisi lain, ada kasus di mana bahkan bahasa pemeriksa tipe waktu kompilasi akan mendapat manfaat dari Notasi Hungaria - void pointer atau HANDLE di win32 API. Ini mengaburkan tipe data sebenarnya, dan mungkin ada gunanya menggunakan Notasi Hongaria di sana. Namun, jika seseorang dapat mengetahui tipe data pada waktu pembuatan, mengapa tidak menggunakan tipe data yang sesuai.

Secara umum, tidak ada alasan kuat untuk tidak menggunakan Notasi Hongaria. Ini masalah suka, kebijakan, dan gaya pengkodean.

Ignas Limanauskas
sumber
6

Sebagai programmer Python, Notasi Hungaria berantakan dengan cukup cepat. Dalam Python, saya tidak peduli jika sesuatu adalah string - saya peduli apakah itu dapat bertindak seperti string (yaitu jika memiliki ___str___()metode yang mengembalikan string).

Misalnya, kita memiliki foo sebagai bilangan bulat, 12

foo = 12

Notasi Hongaria memberi tahu kita bahwa kita harus memanggil iFoo atau sesuatu, untuk menunjukkan itu bilangan bulat, sehingga nanti, kita tahu apa itu. Kecuali di Python, itu tidak berhasil, atau lebih tepatnya, itu tidak masuk akal. Dengan Python, saya memutuskan jenis apa yang saya inginkan saat menggunakannya. Apakah saya ingin tali? nah jika saya melakukan sesuatu seperti ini:

print "The current value of foo is %s" % foo

Perhatikan %s- string. Foo bukanlah string, tetapi %operator akan memanggil foo.___str___()dan menggunakan hasilnya (dengan asumsi itu ada). foomasih berupa bilangan bulat, tetapi kami memperlakukannya sebagai string jika kami menginginkan string. Jika kita menginginkan pelampung, maka kita memperlakukannya sebagai pelampung. Dalam bahasa yang diketik secara dinamis seperti Python, Notasi Hongaria tidak ada gunanya, karena tidak masalah apa jenisnya sampai Anda menggunakannya, dan jika Anda membutuhkan jenis tertentu, maka pastikan untuk mentransmisikannya ke jenis itu (misalnya float(foo)) saat Anda Gunakan.

Perhatikan bahwa bahasa dinamis seperti PHP tidak memiliki manfaat ini - PHP mencoba melakukan 'hal yang benar' di latar belakang berdasarkan seperangkat aturan tidak jelas yang hampir tidak ada yang hafal, yang sering mengakibatkan kekacauan yang tidak terduga. Dalam hal ini, semacam mekanisme penamaan, seperti $files_countatau $file_name, bisa berguna.

Menurut saya, Notasi Hungaria itu seperti lintah. Mungkin dulu berguna, atau paling tidak kelihatannya berguna, tapi sekarang ini hanya banyak mengetik tambahan dan tidak banyak manfaatnya.

Dan Udey
sumber
Menarik bahwa contoh Anda dengan .str () dengan Python bukanlah hasil dari bahasanya yang dinamis. Java, jelas bukan bahasa yang dinamis, melakukan hal yang sama.
Dustman
C # juga melakukan hal yang sama, setiap kelas menerapkan bahasa .ToString()sehingga semuanya bisa dicetak
Electric Coffee
5

IDE harus memberikan informasi yang berguna itu. Bahasa Hongaria mungkin membuat beberapa pengertian (tidak banyak, tapi semacam) masuk akal ketika IDE jauh lebih maju.

Paul Batum
sumber
4
Kemudian lagi, Anda tidak harus mengandalkan IDE yang memberi tahu Anda lebih banyak. Bagaimanapun, kode dapat dilihat di luar IDE ...
TraumaPony
5

Apps Hungarian adalah bahasa Yunani bagi saya - dalam arti yang baik

Sebagai seorang insinyur, bukan seorang programmer, saya segera membaca artikel Joel tentang manfaat Apps Hungarian: "Membuat Kode yang Salah Tampak Salah" . Saya suka Apps Hungarian karena meniru cara teknik, sains, dan matematika merepresentasikan persamaan dan rumus menggunakan simbol sub- dan super-skrip (seperti huruf Yunani, operator matematika, dll.). Ambil contoh tertentu dari Hukum Newton tentang Gravitasi Universal : pertama dalam notasi matematika standar, lalu di kode semu Apps Hungaria:

Hukum gravitasi universal Newton untuk Bumi dan Mars

frcGravityEarthMars = G * massEarth * massMars / norm(posEarth - posMars)

Dalam notasi matematika, simbol yang paling menonjol adalah simbol yang mewakili jenis informasi yang disimpan dalam variabel: gaya, massa, vektor posisi, dll. Subskrip memainkan peran kedua untuk menjelaskan: posisi apa? Inilah tepatnya yang dilakukan Apps Hungarian; itu memberi tahu Anda jenis hal yang disimpan dalam variabel terlebih dahulu dan kemudian membahas secara spesifik - tentang kode terdekat dapat mencapai notasi matematika.

Pengetikan yang jelas kuat dapat menyelesaikan contoh string aman vs. tidak aman dari esai Joel, tetapi Anda tidak akan menentukan tipe terpisah untuk vektor posisi dan kecepatan; keduanya adalah array ganda dengan ukuran tiga dan apa pun yang mungkin Anda lakukan pada salah satunya mungkin berlaku untuk yang lain. Selain itu, sangat masuk akal untuk menggabungkan posisi dan kecepatan (untuk membuat vektor keadaan) atau mengambil hasil kali titiknya, tetapi mungkin tidak untuk menjumlahkannya. Bagaimana pengetikan mengizinkan dua yang pertama dan melarang yang kedua, dan bagaimana sistem seperti itu meluas ke setiap operasi yang mungkin ingin Anda lindungi? Kecuali Anda bersedia menyandikan semua matematika dan fisika dalam sistem pengetikan Anda.

Di atas semua itu, banyak rekayasa dilakukan dalam bahasa tingkat tinggi yang diketik lemah seperti Matlab, atau yang lama seperti Fortran 77 atau Ada.

Jadi, jika Anda memiliki bahasa yang bagus dan IDE serta Apps Hungarian tidak membantu Anda, lupakan saja - banyak orang tampaknya memilikinya. Tapi bagi saya, lebih buruk daripada programmer pemula yang bekerja dalam bahasa yang diketik lemah atau dinamis, saya dapat menulis kode yang lebih baik lebih cepat dengan Apps Hungarian daripada tanpa.

Adam Wuerl
sumber
4

Ini sangat berlebihan dan tidak berguna adalah sebagian besar IDE modern, di mana mereka melakukan pekerjaan yang baik untuk membuat jenisnya terlihat.

Plus - bagi saya - hanya mengganggu melihat intI, strUserName, dll. :)

Ian P
sumber
3
Seperti yang dikatakan TraumaPony kepada Paul Batum, tidak semua orang melihat kode di IDE.
Chris Charabaruk
4

Jika saya merasa bahwa informasi yang berguna sedang diberikan, mengapa saya tidak meletakkannya di tempat yang tersedia?

Lalu siapa peduli apa yang orang lain pikirkan? Jika Anda merasa berguna, gunakan notasi.

eduffy
sumber
Karena hanya ada satu dari saya dan bajillion orang lain yang mungkin mempertahankan kode saya nanti. Karena semua orang itu ada di tim (tetapi mereka belum mengetahuinya), saya ingin tahu jika mereka mengalahkan saya.
Dustman
4

Saya pengalaman saya, itu buruk karena:

1 - maka Anda memecah semua kode jika Anda perlu mengubah jenis variabel (yaitu jika Anda perlu memperluas integer 32 bit menjadi integer 64 bit);

2 - ini adalah informasi yang tidak berguna karena tipenya sudah ada dalam deklarasi atau Anda menggunakan bahasa dinamis di mana tipe sebenarnya seharusnya tidak begitu penting sejak awal.

Selain itu, dengan bahasa yang menerima pemrograman generik (yaitu fungsi di mana jenis beberapa variabel tidak ditentukan ketika Anda menulis fungsi) atau dengan sistem pengetikan dinamis (yaitu ketika jenisnya bahkan tidak ditentukan pada waktu kompilasi), bagaimana Anda memberi nama variabel? Dan sebagian besar bahasa modern mendukung salah satunya, meskipun dalam bentuk terbatas.

PierreBdR
sumber
4

Dalam Joel Spolsky, Making Wrong Code Look Wrong dia menjelaskan bahwa apa yang semua orang anggap sebagai Notasi Hungaria (yang dia sebut Sistem Hungarian) bukanlah apa yang sebenarnya dimaksudkan (apa yang dia sebut Apps Hungarian). Gulir ke bawah ke judul I'm Hungary untuk melihat diskusi ini.

Pada dasarnya, Sistem Hongaria tidak berharga. Ini hanya memberi tahu Anda hal yang sama yang akan diberitahukan oleh compiler dan / atau IDE Anda.

Apps Hungarian memberi tahu Anda apa arti variabel itu, dan sebenarnya bisa berguna.

cjm
sumber
4

Saya selalu berpikir bahwa satu atau dua awalan di tempat yang tepat tidak akan merugikan. Saya rasa jika saya dapat memberikan sesuatu yang berguna, seperti "Hai ini adalah antarmuka, jangan mengandalkan perilaku tertentu" di sana, seperti di IEnumerable, saya harus melakukannya. Komentar dapat mengacaukan banyak hal lebih dari sekadar satu atau dua simbol karakter.

Dustman
sumber
1
Saya tidak pernah mendapatkan ISomethingable. Jika itu adalah -able, itu menyiratkan antarmuka. (Setidaknya di java)
tunaranch
4

Ini adalah konvensi yang berguna untuk memberi nama kontrol pada formulir (btnOK, txtLastName, dll.), Jika daftar kontrol muncul dalam daftar pull-down menurut abjad di IDE Anda.

MusiGenesis
sumber
4

Saya cenderung menggunakan Notasi Hungaria dengan kontrol server ASP.NET saja , jika tidak saya merasa terlalu sulit untuk mengetahui kontrol apa yang ada di formulir.

Ambil cuplikan kode ini:

<asp:Label ID="lblFirstName" runat="server" Text="First Name" />
<asp:TextBox ID="txtFirstName" runat="server" />
<asp:RequiredFieldValidator ID="rfvFirstName" runat="server" ... />

Jika seseorang dapat menunjukkan cara yang lebih baik untuk memiliki kumpulan nama kontrol itu tanpa bahasa Hongaria, saya akan tergoda untuk pindah ke sana.

Aaron Powell
sumber
4

Artikel Joel memang bagus, tetapi tampaknya menghilangkan satu poin utama:

Hongaria membuat 'ide' tertentu (jenis + nama pengenal) unik, atau hampir unik, di seluruh basis kode - bahkan basis kode yang sangat besar.

Itu sangat bagus untuk pemeliharaan kode. Ini berarti Anda dapat menggunakan pencarian teks satu baris yang bagus (grep, findstr, 'find in all files') untuk menemukan SETIAP penyebutan 'ide' itu.

Mengapa itu penting ketika kita memiliki IDE yang tahu cara membaca kode? Karena mereka belum pandai dalam hal itu. Ini sulit dilihat dalam basis kode kecil, tetapi jelas dalam basis kode besar - ketika 'ide' mungkin disebutkan dalam komentar, file XML, skrip Perl, dan juga di tempat-tempat di luar kendali sumber (dokumen, wiki, basis data bug).

Anda memang harus sedikit berhati-hati bahkan di sini - misalnya, menempelkan token di makro C / C ++ dapat menyembunyikan penyebutan pengenal. Kasus seperti itu dapat ditangani dengan menggunakan konvensi pengkodean, dan bagaimanapun mereka cenderung hanya mempengaruhi sebagian kecil dari pengidentifikasi dalam basis kode.

PS Sampai pada poin tentang menggunakan sistem tipe vs. Hongaria - yang terbaik adalah menggunakan keduanya. Anda hanya perlu kode yang salah agar terlihat salah jika kompilator tidak bisa menangkapnya untuk Anda. Ada banyak kasus di mana kompilator tidak dapat menangkapnya. Tapi jika memungkinkan - ya, silakan lakukan itu!

Namun, saat mempertimbangkan kelayakan, pertimbangkan efek negatif dari tipe pemisahan. misalnya dalam C #, membungkus 'int' dengan tipe non-built-in memiliki konsekuensi yang besar. Jadi masuk akal dalam beberapa situasi, tetapi tidak di semua situasi.

McFig
sumber
4

Membongkar manfaat dari Notasi Hongaria

  • Ini memberikan cara untuk membedakan variabel.

Jika jenis adalah semua yang membedakan satu nilai dari yang lain, maka itu hanya dapat untuk konversi satu jenis ke jenis lainnya. Jika Anda memiliki nilai yang sama yang sedang dikonversi antar jenis, kemungkinan Anda harus melakukan ini di fungsi yang didedikasikan untuk konversi. (Saya telah melihat sisa-sisa VB6 hungarian menggunakan string pada semua parameter metode mereka hanya karena mereka tidak dapat mengetahui cara deserialisasi objek JSON, atau memahami dengan benar bagaimana mendeklarasikan atau menggunakan tipe nullable. ) Jika Anda memiliki dua variabel yang hanya dibedakan oleh Awalan bahasa Hongaria, dan mereka bukan konversi dari satu ke yang lain, maka Anda perlu menjelaskan maksud Anda dengan mereka.

  • Itu membuat kode lebih mudah dibaca.

Saya telah menemukan bahwa notasi Hongaria membuat orang malas dengan nama variabel mereka. Mereka memiliki sesuatu untuk membedakannya, dan mereka merasa tidak perlu menjelaskan tujuannya. Inilah yang biasanya akan Anda temukan dalam kode bernotasi Hungaria vs. modern: sSQL vs. groupSelectSql ( atau biasanya tidak ada sSQL sama sekali karena mereka seharusnya menggunakan ORM yang dimasukkan oleh pengembang sebelumnya. ), SValue vs. formCollectionValue ( atau biasanya juga tidak ada sValue, karena kebetulan berada di MVC dan seharusnya menggunakan fitur pengikatan modelnya ), sType vs. publishSource, dll.

Itu tidak bisa dibaca. Saya melihat lebih banyak sTemp1, sTemp2 ... sTempN dari sisa VB6 hungaria yang diberikan daripada gabungan semua orang.

  • Ini mencegah kesalahan.

Ini akan menjadi berdasarkan nomor 2, yang salah.

An00bus
sumber
3

Dalam kata-kata sang master:

http://www.joelonsoftware.com/articles/Wrong.html

Bacaan yang menarik, seperti biasa.

Ekstrak:

"Seseorang, di suatu tempat, membaca makalah Simonyi, di mana dia menggunakan kata" tipe, "dan mengira yang dia maksud adalah tipe, seperti kelas, seperti dalam sistem tipe, seperti tipe pemeriksaan yang dilakukan penyusun. Dia tidak melakukannya. Dia menjelaskan dengan sangat hati-hati persis seperti yang dia maksud dengan kata "tipe", tetapi itu tidak membantu. Kerusakan telah terjadi. "

"Tapi masih ada nilai yang sangat besar bagi Apps Hungarian, karena meningkatkan kolokasi dalam kode, yang membuat kode lebih mudah dibaca, ditulis, di-debug, dan dipelihara, dan, yang terpenting, kode yang salah terlihat salah."

Pastikan Anda memiliki waktu sebelum membaca Joel On Software. :)

rlerallut.dll
sumber
Tidak ada waktu sekarang karena saya memiliki Stackoverflow. Saya pikir asosiasi Spolsky belaka dengan proyek itu pasti berhasil. :)
Dustman
3

Beberapa alasan:

  • IDE modern apa pun akan memberi Anda jenis variabel hanya dengan mengarahkan mouse ke variabel.
  • Sebagian besar nama tipe terlalu panjang (pikirkan HttpClientRequestProvider ) untuk digunakan secara wajar sebagai awalan.
  • Informasi jenis tidak membawa informasi yang benar , ini hanya memparafrasekan deklarasi variabel, daripada menguraikan tujuan variabel (pikirkan myInteger vs. pageSize ).
Joannes Vermorel
sumber
2

Saya tidak berpikir semua orang dengan fanatik menentangnya. Dalam bahasa tanpa tipe statis, ini sangat berguna. Saya pasti lebih suka jika digunakan untuk memberikan informasi yang belum di ketik. Seperti di C, char * szName mengatakan bahwa variabel akan merujuk ke string yang diakhiri dengan null - itu tidak tersirat dalam char * - tentu saja, typedef juga akan membantu.

Joel memiliki artikel bagus tentang penggunaan bahasa Hongaria untuk mengetahui apakah suatu variabel dikodekan HTML atau tidak:

http://www.joelonsoftware.com/articles/Wrong.html

Bagaimanapun, saya cenderung tidak menyukai bahasa Hongaria yang digunakan untuk menyampaikan informasi yang sudah saya ketahui.

Lou Franco
sumber
Saya pikir kalimat pertama itu mungkin mempercayai jawaban di halaman ini.
Dustman
@ Debman Nah, apakah Anda sudah tahu bahwa string C adalah null dihentikan? Saya melihat bagaimana hal itu akan berguna ketika string mungkin tidak ada tetapi itu jarang dan jadi saya pikir penggunaan konvensi harus dibatasi pada kasus-kasus itu.
Plumenator
Tidak setiap karakter * adalah string c yang diakhiri dengan null. Inti dari bahasa Hongaria adalah menggunakannya untuk setiap variabel, bahkan variabel yang termasuk dalam kasus umum. Pada akhirnya, saya merasa seperti Anda - dan karena itu saya tidak menggunakannya di C.
Lou Franco
2

Saya mulai membuat kode hampir sama dengan waktu notasi Hungaria ditemukan dan pertama kali saya dipaksa untuk menggunakannya dalam sebuah proyek, saya membencinya.

Setelah beberapa saat saya menyadari bahwa ketika itu dilakukan dengan benar itu benar-benar membantu dan hari-hari ini saya menyukainya.

Tetapi seperti semua hal yang baik, itu harus dipelajari dan dipahami dan untuk melakukannya dengan benar membutuhkan waktu.

jussij
sumber
1

Notasi Hungaria disalahgunakan, terutama oleh Microsoft, yang mengarah ke awalan yang lebih panjang dari nama variabel, dan menunjukkan itu cukup kaku, terutama ketika Anda mengubah jenis (lparam / wparam yang terkenal, dari jenis / ukuran yang berbeda di Win16, identik di Win32 ).

Jadi, baik karena penyalahgunaan ini, maupun penggunaannya oleh M $, dianggap tidak berguna.

Di pekerjaan saya, kami membuat kode di Java, tetapi pendirinya berasal dari dunia MFC, jadi gunakan gaya kode yang serupa (kurung kurawal, saya suka ini !, ibu kota untuk nama metode, saya sudah terbiasa dengan itu, awalan seperti m_ untuk anggota kelas (bidang ), s_ ke anggota statis, dll.).

Dan mereka mengatakan semua variabel harus memiliki awalan yang menunjukkan tipenya (misalnya BufferedReader bernama brData). Yang ditampilkan sebagai ide yang buruk, karena jenis dapat berubah tetapi nama tidak mengikuti, atau pembuat kode tidak konsisten dalam penggunaan awalan ini (saya bahkan melihat aBuffer, theProxy, dll!).

Secara pribadi, saya memilih beberapa prefiks yang menurut saya berguna, yang paling penting adalah b untuk mengawali variabel boolean, karena mereka adalah satu-satunya tempat saya mengizinkan sintaks seperti if (bVar)(tidak menggunakan autocast dari beberapa nilai menjadi benar atau salah). Ketika saya membuat kode di C, saya menggunakan awalan untuk variabel yang dialokasikan dengan malloc, sebagai pengingat itu harus dibebaskan nanti. Dll

Jadi, pada dasarnya, saya tidak menolak notasi ini secara keseluruhan, tetapi mengambil apa yang tampaknya sesuai dengan kebutuhan saya.
Dan tentu saja, ketika berkontribusi pada beberapa proyek (pekerjaan, sumber terbuka), saya hanya menggunakan konvensi yang ada!

PhiLho
sumber