Przeszukałem forum, ale nie mogłem znaleźć odpowiedzi, dlaczego należy tego unikać, tylko dlaczego nie jest to srebrna kula. Więc nie sądzę, że to pytanie jest duplikatem.
Czy istnieje WAŻNY powód, dla którego powinienem oduczyć się systemów węgierskiego, do których jestem przyzwyczajony?
Jak dotąd widzę następujące zalety korzystania z niego:
- Spójne nazewnictwo zmiennych
- Widzisz pismo bez wyszukiwania (Intellisense jest martwy / indeksowanie przez połowę czasu, więc nadal jest to ważny powód)
- Semantyka może być nadal pakowana w drugą część nazwy
I następujące wady:
- Drażni niektórych ludzi (nie mam pojęcia dlaczego)
- Jeśli typ zostanie zmieniony, typ może nie pasować do nazwy zmiennej (nie sądzę, że jest to poprawny powód, typy są zmieniane rzadko, a Ty masz „zmień nazwę wszystkiego”)
Więc dlaczego:
vector<string> vecCityNames;
wstring strCity = L"abc";
//more code here
vecCityNames.push_back(strCity);
jest gorszy niż:
vector<string> cityNames;
wstring city = L"abc";
//more code here
cityNames.push_back(city);//Are we pushing back int on a queue? Float on a stack? Something else?
vectCityNames
byćvectStringCityNames
aż tak dużo dla twojego konsekwentnego argumentu, a to „pytanie” jest bardziej rażące niż cokolwiek innego, masz już swój umysł, to powinno być zamknięte.cityNames.push_back(city)
jest dość jasne. Jest to lista nazw miast, którą dodajesz.Odpowiedzi:
Korzystałem z niego (wiele lat temu) i już go nie używam. Głównym powodem jest to, że jest zbyteczny w językach OO z silnym pisaniem (C ++, Java), z których korzystałem przez większość mojej kariery. W tych językach, jeśli dobrze zdefiniuję typy, kompilator może i wymusi dla mnie bezpieczeństwo typu. Tak więc wszelkie prefiksy nazw są po prostu bałaganem, który powoduje, że nazwy są dłuższe, a zatem trudniejsze do odczytania i wyszukiwania.
W każdym dobrze napisanym programie OO większość zmiennych to (odniesienia) typy zdefiniowane przez użytkownika. Jeśli poprzedzisz je tym samym tagiem ogólnym (jak
o
dla „object”), nie uzyskasz z niego żadnych korzyści, tylko wady. Jeśli jednak poprzedzisz je tagami specyficznymi dla typu, wpadniesz w labirynt próbowania znaleźć różne skróty dla tysiąca różnych typów o często podobnych nazwach * i pamiętaj, aby zmienić je wszystkie, gdy typ lub jego nazwa się zmieni (co jest wcale nie rzadkie w dobrze utrzymanym programie).Oczywiście nie dotyczy to języków innych niż OO i może nie dotyczyć języków słabo i / lub dynamicznie typowanych (nie mam z nimi żadnego doświadczenia poza C). Ani do nieoptymalnych edytorów / IDE bez użytecznego IntelliSense (lub jego lokalnego odpowiednika). A to tylko moje 2 centy. Więc jeśli notacja węgierska działa dla twojego zespołu i twojego projektu, idź po nią. Ważne jest uzgodnienie tego (a także ogólnie spójnego stylu kodowania) przed rozpoczęciem projektu i utrzymanie go przez cały czas.
* Tylko krótka lista z naszego aktualnego projektu: mamy
Charge
,ChargeBreakdown
,ChargeCalculator
,ChargeDAO
,ChargeDTO
,ChargeLineHelper
,ChargeMaps
,ChargePair
iChargeType
, między innymi. Ponadto mamy równieżContract
s,Countrie
s,Checkout
s,Checkin
s ... a to dopiero litera C, w ramach projektu, który prawdopodobnie nawet nie można nazwać „całkiem spore” przez PO.Uwaga: Jestem Węgrem, więc wierzę, że mogę mówić w tej sprawie z autorytetem ;-)
źródło
iPos
lubfAmount
może być tolerowane, ale spróbuj pracować na bazie kodu, w której każda zmienna obiektowa ma nadmiarowy sześcioliterowy przedrostek informujący tylko, że jest to „wskaźnik do struktury”.char[]
Posiadanych przez aStringBuilder
), a odniesieniami do instancji, które nie mogą być zmutowane, ale mogą być dzielone z rzeczami, które ich nie mutują (np.char[]
wstrzymywane przezString
, które mogą być współdzielone przez wieleString
instancji). Oba pola są tego samego typuchar[]
, ale zawierają rzeczy, które są bardzo różne. Wiele błędów związanych ze zmiennością wynika z ...Dlaczego jest
std::vector<string> vecCityNames;
źle?Problem z węgierską notacją, ponieważ jest zwykle używany, że jeśli profilowanie pokazuje, że nazwy miast powinny raczej być przechowywane w
std::deque
, wszystkie nazwy zmiennych odnoszące się do obiektu tego typu będą nagle miały mylącą nazwę.Czy zamierzasz zmienić nazwy wszystkich swoich zmiennych? Czy kiedykolwiek próbowałeś to zrobić w dużym projekcie? Z pomocą Murphy'ego (a facet jest tam niesamowicie pomocny) ktoś gdzieś z pewnością użyłby zmiennych zwanych czymś podobnym
deqCityNames
, powodując, że zmiany przerwały kompilację, pozostawiając cię godzinami majstrującymi przy kodzie, którego przez pół dekady nikt nie śmiał nawet spojrzeć w obawie przed ugryzieniem przez jadowitą bestię.Z tego, co wiem, jednak sposób, w jaki Charles Simonyi wymyślił węgierski, przedrostek oznaczał użycie semantyczne zmiennych , a nie jego typ składniowy . Oznacza to, że prawidłowy prefiks dla listy nazw miast, bez względu na typ, w jakim jest zaimplementowany, prawdopodobnie byłby
listCityNames
(lublstCityNames
, jeślilist
nie jest wystarczająco tajemniczy).Ale uważam ten przedrostek za zbyteczny, ponieważ liczba mnoga („nazwy”) już wskazuje, że jest to kilka miast. Konkluzja: Gdy ostrożnie wybierasz identyfikatory, notacja węgierska jest rzadko potrzebna. OTOH, sposób, w jaki jest powszechnie używany, w dłuższej perspektywie faktycznie powoduje uszkodzenie kodu.
źródło
typedef
jest to bardzo niedoceniane narzędzievecCityNames
nadeqCityNames
kilkaset plików i zrobisz to samo.Z jakiegokolwiek powodu istniejące tutaj odpowiedzi wydają się tańczyć wokół uzasadnienia węgierskiej notacji, nie stwierdzając tego wprost. Notacja węgierska jest przydatna do dodawania informacji o typie (w sensie teoretycznym ), gdy byłoby to trudne w samym języku . Tak się składa, że zwykle nie jest tak trudno używać C ++ lub systemu czcionek Java w taki sposób, że notacja węgierska (jak zwykle opisywana) jest całkowicie zbędna, i to prawdopodobnie spowodowało luz w stosunku do niej - dodaje pracy programisty aby zachować te adnotacje we wszystkich naszych zmiennych zmiennych, ale zapewnia niewielką lub żadną dodatkową wartość (a nawet może powodować szkody, ponieważ kod wygląda na bardziej zagracony).
Z drugiej strony, jeśli ograniczy się użycie notacji węgierskiej do wpisywania informacji (ponownie w sensie teoretycznym ), które nie sąnaturalnie otoczone przez język, to może być bardzo przydatne. Na przykład C i C ++ przekazują odwołania do tablic jako typy wskaźników, ale odwołania do tablic i wskaźniki mają różne operacje, które należy wykonać na nich: tablice mogą być indeksowane poza pierwszym elementem, podczas gdy wskaźniki nie. Jest to użyteczna informacja, która zostaje utracona w systemie typów, gdy tylko tablica zostanie przekazana do funkcji jako argument. Jako takie, w naszej grupie przyjęliśmy adnotacje nazw zmiennych w kodach C i C ++, aby rozróżnić, czy zmienna wskaźnikowa jest rzeczywiście wskaźnikiem do pojedynczego elementu, czy wskaźnikiem do tablicy. Przyjęcie tej konwencji było częściowo odpowiedzialne za znaczne ograniczenie występowania problemów z uszkodzeniem pamięci w naszej bazie kodu.
źródło
dw
kontracb
.) Nie jest tak, że jego oryginalna forma byłaby mniej pomocna w językach OO: Indeks jest nadal indeksem, nawet jeśli jest przechowywany w typie klasy, a nie we wbudowanym.Powoduje to, że denerwuje mnie to, że jest to niewielki wzrost prędkości na każdym identyfikatorze, który spowalnia moje wizualne skanowanie kodu. Jest to mAs, jeśli masz ZADA q Czytać iAngielski tekst jak to.
źródło
Nienawiść to zbyt mocne słowo, IMO. Możesz napisać kod w dowolny sposób; Po prostu wolę nie używać notacji węgierskiej w swoim własnym kodzie, a biorąc pod uwagę wybór, wolałbym również nie czytać go ani nie pracować z nim w kodzie innych osób.
Pytałeś, dlaczego niektórzy uważają denerwujący zapis węgierski. Nie mogę mówić w imieniu innych, ale to mnie denerwuje:
Jest brzydki.Węgierski przyjmuje całkowicie rozsądne nazwy i poprzedza kod. Po zinternalizowaniu tego kodu jestem pewien, że ma to sens, ale dla niewtajemniczonych wygląda to tak, jakby ktoś uwolnił manglera nazw C ++ w moim kodzie źródłowym.
Jest zbędny. Deklaracja zmiennej określa jej typ; Nie czuję potrzeby powtarzania tych informacji w nazwie zmiennej. Nie jest to prawdą w każdym języku: na przykład w Perlu sigile, takie jak @ lub $ poprzedzone nazwą zmiennej, zasadniczo określają typ zmiennej, więc nie masz innego wyboru, jak z nich korzystać.
Rozwiązuje problem, którego nie mam.Metody i funkcje nie powinny być tak długie, abyś musiał ciężko szukać deklaracji zmiennej lokalnej lub parametru, i nie powinny one obejmować tak wielu zmiennych, abyś miał problem ze śledzeniem, co jest. Deklarowanie lokalnych zmiennych blisko kodu, który ich używa, również pomaga w tym względzie. Kompilatory C z przeszłości wymagały zadeklarowania wszystkich zmiennych lokalnych na początku funkcji, ale to ograniczenie zostało usunięte dawno temu.
To jest niekompletne. Notacja węgierska została wynaleziona dla języka (BCPL), który nie miał systemu typów, a następnie została szeroko zastosowana w języku (C), który miał dość ograniczoną liczbę typów rodzimych. IMO nie działa dobrze z takimi językami jak C ++ lub Java, które mają rozbudowane systemy typów. Dlaczego miałbym używać prefiksu, aby wskazać typ zmiennej, która jest rodzimym typem, takim jak char [], ale nie taka, która jest klasą? Alternatywnie, jeśli zacznę wymyślać prefiksy jak
vec
dla klas, skończę z dużą hierarchią prefiksów równolegle do mojej hierarchii klas. Jeśli to ci się podoba, możesz to zrobić; samo myślenie o tym sprawia mi ból głowy.To niejednoznaczne , przynajmniej tak rozumiem. Jaka jest różnica między
szFoo
ipszFoo
? Pierwszy to ciąg zakończony zerem, a drugi to wskaźnik do łańcucha zakończonego zerem. Ale w C lub C ++, o ile wiem, każda zmienna łańcuchowa jest faktycznie wskaźnikiem, więc czy są takie same, czy nie? Z którego powinienem korzystać? Rzeczywista odpowiedź naprawdę nie ma znaczenia - chodzi o to, że nie mogę rozpoznać odpowiedzi za pomocą samego zapisu, który powinien pomóc mi uniknąć tego rodzaju pytań. Z drugiej strony deklaracja zmiennej musi być jednoznaczna, ponieważ używa jej kompilator.To właśnie denerwuje mnie w węgierskiej notacji. Jednak nawet jako grupa nie sądzę, żeby w pełni wyjaśniali, dlaczego Węgier został w dużej mierze porzucony. Oto trzy największe powody, dla których większość programistów nie używa węgierskiego:
Nie ma ważnego powodu, aby z niego korzystać. Patrz punkty 3 i 4 powyżej. Prawdopodobnie mógłbym żyć z irytacją, gdyby Węgier oferował jakąś dużą przewagę nad niestosowaniem węgierskiego, ale nie widzę żadnego, i najwyraźniej większość innych ludzi też nie. Być może najlepszą rzeczą w języku węgierskim było to, że była to powszechnie stosowana konwencja, a jeśli trzymasz się standardowego zastosowania, możesz rozsądnie oczekiwać, że inni programiści o podobnych umiejętnościach będą w stanie zrozumieć zapis.
Zwiększony wpływ firm, które nie są Microsoftem. Prawdopodobnie słusznie jest powiedzieć, że większość programistów, którzy przyjęli notację węgierską, zrobiło to, ponieważ w ten sposób Microsoft pisał kod i często łatwiej jest z tym płynąć. Firmy takie jak Google i Apple mają teraz znacznie większy zakres wpływów niż kiedyś, a więcej programistów niż kiedykolwiek wcześniej przyjmuje style tych firm i innych, które w większości unikają węgierskiego. (Trzeba tylko zaznaczyć, że nadal widać niektóre resztki, np. Zarówno Google, jak i Apple często używają przedrostka „k” dla stałych nazw).
Microsoft sam zrezygnował z węgierskiego. Jeśli sprawdzisz sekcję Ogólne konwencje nazewnictwa Microsoft w jej wytycznych dotyczących kodowania, przekonasz się, że napisano pogrubioną czcionką: Nie używaj notacji węgierskiej.
W związku z tym jednym ważnym powodem do zaprzestania używania notacji węgierskiej jest:
Popularność notacji węgierskiej spadła do tego stopnia, że konwencja nie jest już pomocna. O wiele mniej programistów używa lub nawet rozumie język węgierski, a zatem konwencja jest znacznie mniej skuteczna w przekazywaniu informacji, które powinna. Jeśli uznasz, że jest to przydatny sposób pisania kodu we własnych projektach, to nie ma powodu, aby się kończyć. Jeśli jednak piszesz kod jako część zespołu, który nie używa węgierskiego, może stać się ścianą między tobą a resztą zespołu zamiast udanej strategii komunikacji.
źródło
szFoo
ipszFoo
”? Jednachar*
z nichchar**
zajęła mi 0,25 sekundy, żeby powiedzieć różnicę. Spróbuj pokonać to dzięki Intellisense.pnFoo
prawdopodobnieint*
nie byłbyint**
, więc musisz wiedzieć, żesz
oznacza to również wskaźnik. Jestem pewien, że nie jest to duży problem dla ograniczonej liczby typów, które ustanowiły węgierskie prefiksy, ale w każdym dużym projekcie liczba typów zdefiniowanych w tysiącach. Nie wiem o Intellisense, ale IDE ulegały stałej poprawie w ciągu ostatnich 25 lat i oczekuję, że trend ten będzie się utrzymywał.Jeśli wymienię wszystkie moje zmienne po znakach z The Simpsons, to też będzie spójne, ale czy to jest korzyść?
To jedyny uzasadniony powód, oparty na słabości jednego konkretnego narzędzia ...
To nie jest korzyść; po prostu twierdzisz, że nie ma ( ogromnego ) minusu.
źródło
IDE w trywialny sposób powie mi, jaki jest typ zmiennej, kiedy na nią kliknę. Więc po co zawracać sobie głowę powielaniem tych informacji? Zasadniczo notacja węgierska systemów stanowi naruszenie zasady DRY, z wszystkimi powiązanymi z nią pułapkami. Kiedy te informacje są łatwo dostępne w nowoczesnym środowisku, nie ma powodu, aby płacić tę cenę.
Spójność sama w sobie nie jest zaletą. Nie nazywanie ich typem jest również spójne. Gdyby tylko niektóre zmienne miały swoje nazwy w nazwie, miałbyś niespójność. A pakowanie semantyki do drugiej części to po prostu „Cóż, nie jest tak źle.”, Wszyscy inni mogą używać całej nazwy dla semantyki. Nie wymieniono żadnych rzeczywistych zalet.
źródło
Inną kwestią związaną z tradycyjnymi formami węgierskiej notacji jest to, że zwykle są to przedrostki. są tutaj 2 problemy imho:
1) Ludzki czytelnik na ogół chciałby najpierw najważniejszej informacji, w większości węgierskich zakodowane informacje mają prawdopodobnie mniejsze znaczenie niż sama nazwa.
2) Prefiksy mają wpływ na sortowanie leksykalne, więc jeśli na przykład zamierzasz użyć prefiksu do oznaczenia interfejsów lub klas, a IDE zapewnia posortowaną listę tych, powiązane klasy / interfejsy zostaną rozdzielone na tej liście.
źródło
Oczywiście sprowadza się to do opinii, więc trudno będzie tu pracować z faktami. Osobiście uważam, że argument dla notacji węgierskiej przebiega nieco cienki w silnie wpisane, obiektowych języków. Z mojego doświadczenia wynika, że aplikacje OO mają tendencję do radzenia sobie ze złożonością, utrzymując spójność i zwięzłość klas, i to samo można powiedzieć o funkcjach. Oznacza to, że wszystkie inne rzeczy są równe, w wyniku czego:
Teraz, jeśli chcesz używać notacji węgierskiej, musisz zdecydować, czy zastosować ją ogólnie, czy po prostu użyć jej do niektórych uprzywilejowanych typów i klas (takich jak podstawowe biblioteki klas). To drugie nie ma dla mnie sensu, a drugie prowadzi do „labiryntu próbowania znalezienia różnych skrótów do tysiąca różnych typów”, o których mówił Péter Török. Oznacza to, że utrzymywanie list skrótów wiąże się z dużym nakładem pracy i zwykle „spójne nazewnictwo zmiennych” wychodzi z okna.
Drugi punkt dotyczący krótszych metod oznacza, że w większości przypadków nie będziesz musiał przechodzić przez setki linii kodu, aby sprawdzić, jaki jest typ zmiennej. Nieco ostrożniejsze nazywanie zmiennych wyeliminowałoby niektóre z pozostałych pytań - np.
cityName
Vs. sprawiedliwecity
. Mam nadzieję, żecityName
to nie jest pływak :)Jeśli chodzi o to, dlaczego denerwuje ludzi - znowu, prawdopodobnie jest to spowodowane przyzwyczajeniem się do tego lub nie. Ale jako ktoś, kto nie jest do tego przyzwyczajony, mogę powiedzieć, że użycie węgierskiej notacji przerywa przepływ kodu w moich oczach, co utrudnia szybkie czytanie. Podsumowując, nie mówię, że nie ma on żadnych zalet (chociaż nie omawiałem niektórych jego wad, jeśli chodzi o refaktoryzację itp.), Mówię, że wysiłek nie jest opłacalny, dla silnie typowanych języków OO.
źródło
Nie wiem w kontekście C ++, ale w świecie Java / C # wolałbym mieć sensowne nazwy, które przekazują język domeny lub kontekst, niż mówienie mi, że
strFirstName
jest to String; powinno być oczywiste, że jest to ciąg znaków, w przeciwnym razie należy zmienić nazwę, aby przekazać lepsze zamiary. Jeśli potrzebujesz prefiksu, aby poznać rodzaj tego, z czym pracujesz, argumentowałbym, że twoje nazewnictwo jest niespójne, niewystarczająco opisowe lub wręcz błędne. We współczesnych językach zawsze wolę dłuższe nazwy, które nie pozostawiają dwuznaczności niż nazwy niejasne lub dwuznaczne.Jedynym razem, gdy używam węgierskiego, są formanty ASP.NET, a tym bardziej IA) nie muszę wpisywać czegoś naprawdę długiego
CustomerFirstNameTextBox
porównaniutxtCustomerFirstName
do B, a więc B) Intellisense posortuje wszystkie typy kontroli. Mimo to czuję się „brudny”, ale muszę dopiero znaleźć lepszy sposób.źródło
Meh - tak naprawdę chodzi o osobiste preferencje, bez względu na to, jak bardzo staramy się zracjonalizować swoje wybory. Ja osobiście trzymam się zasady „When in Rome ...” i używam węgierskiego w kodzie, który często wywołuje Windows API. W przypadku kodu niezależnego od platformy zwykle używam standardowego stylu biblioteki C ++.
źródło
Odpowiedź leży w tym pytaniu: Powiedz mi, jak nazwać następujące zmienne:
Dodaj do tych stałych ciągów, wskaźnik do nich i stałe wskaźniki do nich.
źródło
szFoo
,wczFoo
,strFoo
,(w)strFoo
,strFoo
,bstrFoo
,bstrFoo
Bardzo nie podoba mi się opisana przez ciebie notacja węgierska. Powód? Nie służy to żadnemu punktowi w 90% przypadków.
Na przykład trochę kodu (równoważnego C ++. Faktycznie napisanego w Delphi) ze starszego projektu, który muszę znieść:
... pRecord jest zmienną, jest typu TRecordList.
TRecordList *pRecords[10];
Jest to klasa składająca się z orioerty o nazwie FooMember, która wskazuje na fFooMember ... lub mFooMember, w zależności od tego, czy jest to „pole” czy „członek” (wskazówka: to to samo)
Problemy?
fFooMember
może być coś w rodzaju FooMember_, ponieważ zawsze będziemy uzyskiwać do niego dostęp za pośrednictwem własności publicznej FooMember. pRecords? To dość oczywiste, że jest wskaźnikiem tego, że odczuwasz to wszędzie. TRecordList? Kiedy możesz pomylić nazwę typu i obiekt tego typu? Kompilator będzie na ciebie krzyczał, a typy są używane prawie w żadnym miejscu, w którym znajdują się obiekty (z wyjątkiem właściwości / metod statycznych)Teraz jest jedno miejsce, w którym używam węgierskiej notacji. Dzieje się tak, gdy mamy do czynienia z wieloma zmiennymi interfejsu użytkownika, które miałyby taką samą nazwę jak inne zmienne interfejsu użytkownika lub zmienne zwykłe.
Na przykład, gdybym miał na nim formularz Twojego imienia.
Miałbym klasę o nazwie FirstNameForm. W nim lblFirstName i txtFirstName odpowiednio dla etykiety i pola tekstowego. I publiczna właściwość FirstName do uzyskiwania i ustawiania nazwy w polu tekstowym.
Można to również rozwiązać za pomocą FirstNameLabel i FirstNameTextBox, ale okazuje się, że pisanie długo trwa. Zwłaszcza z czymś takim jak GenderDropDownList i tym podobne.
Tak więc w gruncie rzeczy notacja węgierska jest co najmniej denerwująca na poziomie systematycznym, a najgorszy przypadek szkodliwy (ponieważ inne odpowiedzi wskazują na problemy z refaktoryzacją i spójnością).
źródło