Widzę pytania podobne do tego w odniesieniu do nazw parametrów, które pasują do właściwości w klasie, ale nie mogę znaleźć niczego dotyczącego używania nazwy parametru, która jest taka sama jak nazwa typu parametru, z wyjątkiem casing w C #. Wydaje się, że nie jest to naruszenie, które mogę znaleźć, ale czy uważa się to za złą praktykę? Na przykład mam następującą metodę
public Range PadRange(Range range) {}
Ta metoda przyjmuje zakres i zwraca nowy zakres z zastosowanym dopełnieniem. Biorąc pod uwagę ogólny kontekst, nie mogę wymyślić bardziej opisowej nazwy parametru. Przypomniała mi się jednak wskazówka, którą wybrałem podczas czytania Code Complete na temat „dystansu psychologicznego”. To mówi
Odległość psychologiczną można zdefiniować jako łatwość różnicowania dwóch elementów ... Podczas debugowania przygotuj się na problemy spowodowane niewystarczającą odległością psychologiczną między podobnymi nazwami zmiennych i między podobnymi nazwami rutynowymi. Podczas konstruowania kodu wybieraj nazwy z dużymi różnicami, aby uniknąć problemu.
Moja sygnatura metody ma wiele „zasięgu”, więc wydaje się, że może to być problem w odniesieniu do tego dystansu psychologicznego. Teraz widzę, że wielu programistów wykonuje następujące czynności
public Range PadRange(Range myRange) {}
Osobiście bardzo nie lubię tej konwencji. Dodanie przedrostka „my” do nazw zmiennych nie zapewnia dodatkowego kontekstu.
Widzę również następujące
public Range PadRange(Range rangeToPad) {}
Podoba mi się to bardziej niż „mój” prefiks, ale nadal nie dbam o to ogólnie. Po prostu wydaje mi się to zbyt szczegółowe i odczytuje niezręcznie jako nazwę zmiennej. Dla mnie zrozumiałe jest, że zakres zostanie uzupełniony z powodu nazwy metody.
Więc przy tym wszystkim, moim przeczuciu jest iść z pierwszym podpisem. Dla mnie to jest czyste. Nie ma potrzeby wymuszania kontekstu, gdy nie jest potrzebny. Ale czy robię sobie lub przyszłym programistom niezadowolenie z tej konwencji? Czy naruszam najlepszą praktykę?
źródło
Range range
jest w porządku.Range r
(przynajmniej dla krótkiej treści metody) iRange toPad
.Odpowiedzi:
Nie przemyśl tego,
Range range
jest w porządku. Używam tego rodzaju nazewnictwa od ponad 15 lat w C #, i prawdopodobnie znacznie dłużej w C ++, i nigdy nie doświadczyłem żadnych prawdziwych wad, wręcz przeciwnie.Oczywiście, jeśli masz różne zmienne lokalne w tym samym zakresie, wszystkie tego samego typu, prawdopodobnie pomoże to zainwestować trochę wysiłku umysłowego w ich prawidłowe rozróżnienie.
źródło
Wack(Bozo bozoToBeWacked)
za przykład nadmiarowości w nazwie zmiennej, która jest wyrażona w sposób obfity przez samą metodę (a zatem niepożądana w pierwotnym pytaniu).Wack(Person bozo)
jest jednak bardziej wartościowa semantycznie, ponieważ implikuje, że oczekuje się, że tylko bozo zostaną wyrzucone.initialRange
. Nadal jest bardzo ogólny, ale nie ma prawie tego samego poziomu niesmaku jakmyRange
.Punch(Bozo punchingBozo, Bozo bozoToBePunched)
. Szczegółowe nazewnictwo jest bardziej odpowiednie, gdy trzeba rozróżnić wiele rzeczy (które są semantycznie opisane za pomocą tych samych słów). Sugestia OPRange rangeToPad
nie jest konieczna w jego przykładzie metody jednoparametrowej, ale może być niezwykle konieczna dla metody, która przyjmuje kilkaRange
obiektów.Punch(Bozo source, Bozo target)
zadanieRobię to cały czas, daje mi to świetne zdanie. Jeśli jest to argument przekazany konstruktorowi, który należy przypisać do elementu członkowskiego, mój element członkowski również otrzymałby nazwę range, a przypisanie to
I zazwyczaj miałbym właściwość o nazwie Range.
Wszystkie są takie same, różnią się tylko kontekstem, więc utrzymanie jednego imienia ma sens, a będziesz musiał zapamiętać tylko jedno imię. To jedno, różnice są czysto techniczne.
Powinieneś być surowy wobec w pełni kwalifikujących się członków z „tym”. choć właśnie po to jest StyleCop.
Notatka boczna StyleCop
Kontrowersje gwarantowane!
Dla tych, którzy opowiadają się przeciwko używaniu „tego”: widziałem _, m, m_ i tylko nic. Sam język oferuje nam całkowicie jasny, jednoznaczny, powszechnie rozpoznawalny sposób wskazywania, że mamy do czynienia z członkiem klasy. Dlaczego, u licha, chciałbyś wymyślić własną drogę, która okalecza i tak już doskonałe nazwy?
Jedyny powód, dla którego mogę o tym pomyśleć, że jest to nawyk spuścizny z epoki C, kiedy to miało sens, ponieważ nie było innego wyjścia.
„To więcej postaci!” Poważnie? „Czas kompilacji gwałtownie wzrośnie!” Poważnie? „Będę musiał podnieść mój pinky podczas pisania!”. Jakby czas pisania miał jakieś znaczenie w całkowitym czasie programowania.
Zdaję sobie sprawę, że każdy styl inny niż ten, do którego jesteś przyzwyczajony, wzbudzi sprzeciw. Jednak konsekwentne korzystanie z tego jest trudne. Oto, jak to działa dla mnie: zanim wypchnę nowy plik kodu, uruchamiam StyleCop i znajdzie on liczbę członków, którzy nie mają kwalifikatorów „tego”. Umieszczam „to”. w schowku, prowadzony przez członków i wstaw. Bez żadnego wysiłku.
StyleCop robi o wiele więcej (haha). Jest tak wiele sposobów, w jakie programista może (tylko biorąc pod uwagę formatowanie kodu) udaremnić prace konserwacyjne swojego następcy. StyleCop zapobiega większości z nich. To jest nieocenione.
Jeśli jesteś nowy: zazwyczaj narzekasz przez tydzień lub dwa, a potem pokochasz.
źródło
this
chyba że jest to konieczne. W przeciwnym razie to tylko hałas. Użyj_range
dla pola ithis
nigdy nie jest potrzebne, z wyjątkiem metod rozszerzenia._
jest lepszy niż hałasthis.
? Twierdziłbym, że jedno ma znaczenie narzucone przez język (i zwykle ma podświetlanie składni), podczas gdy drugie nie.Moje wskazówki dotyczące metod nazewnictwa, parametrów i zmiennych są dość proste:
Zatem moim zdaniem optymalną sygnaturą metody byłoby:
Skrócenie nazwy metody jest oczywiste.
Nazwa parametru
toPad
natychmiast informuje czytelnika, że ten parametr prawdopodobnie zostanie zmodyfikowany w miejscu poprzez wypełnienie, a następnie zwrócenie. Przeciwnie, nie można przyjąć żadnych założeń dotyczących zmiennej o nazwierange
.Ponadto, w rzeczywistej treści metody, wszelkie inne
Range
zmienne, które są wprowadzane, powinny (powinny) być nazwane według ich zamiarów, więc możesz miećpadded
iunpadded
...toPad
jest zgodny z tymi konwencjami nazewnictwa, alerange
po prostu wystaje i nie żeluje.źródło
padded
/unpadded
brzmi dobrze dla lokalnych niezmiennych zmiennych. Ale jeśli istnieje zmiennytoPad
parametr, to po zakończeniu wypełniania nazwatoPad
już nie pasuje (chyba że wynik zostanie natychmiast zwrócony).Range range
W takich przypadkach wolałbym się trzymać .result
. Zostanie zmodyfikowany i zwrócony . To drugie wynika z nazwy, a drugie wynika z tego, że zwrócenie niemodyfikowanego argumentu nie ma sensu.Pad
metoda zwraca aRange
. To dla mnie oznacza, że ten, który przekazałem, zostanie zachowany, a nie zmodyfikowany w miejscu, a nowy, wyściełanyRange
zostanie zwrócony. .Pad(toPad)
czuje się trochę źle IMHO. Dobrze bronisz swojego punktu widzenia. Dostajesz ode mnie +0! :)Kluczowym pytaniem, które należy sobie zadać, jest nazywanie elementów kodu (typów, zmiennych, funkcji itp.)
Jeśli zrobię literówkę, czy kompilator ją dla mnie znajdzie?
Najgorszy rodzaj błędu opartego na literówkach to taki, w którym kod się kompiluje i działa, ale daje inne zachowanie niż się spodziewano z powodów, które są subtelne. A ponieważ jest to spowodowane literówką, zwykle bardzo trudno jest zobaczyć, kiedy sprawdzasz kod. Jeśli literówka zatrzyma kompilację kodu, kompilator oznaczy wiersz powodując problem, a ty możesz łatwo go znaleźć i naprawić.
W sytuacji, gdy typ i zmienna różnią się jedynie wielkością liter, zawsze tak będzie. (Lub prawie zawsze - przy wystarczającym wysiłku, jestem pewien, że mógłbyś sprawić, by działało, ale naprawdę musisz spróbować.) Myślę więc, że tam jesteś OK.
Trzeba by się martwić, gdyby w bieżącym zakresie były dwie zmienne, metody, funkcje lub właściwości o nazwie
range
iRange
. W takim przypadku kompilator prawdopodobnie będzie niech to przez, i masz zamiar uzyskać nieoczekiwane zachowanie w czasie wykonywania. Zauważ, że to dwa każdy z tych typów elementów kodu, nie tylko „dwie zmienne” lub „dwie funkcje” - wszystkie te mogą być niejawnie oddanych do siebie, co powoduje rzezi, gdy skończy. Możesz otrzymywać ostrzeżenia, ale nie możesz zagwarantować nic więcej. Podobne problemy występują, jeśli zgłoszono dwa typy nazwanerange
iRange
.Należy również pamiętać, że to samo dotyczy węgierskiego stylu notacji , w którym nazwy są poprzedzone jednym lub kilkoma znakami, aby powiedzieć coś więcej na temat tego, co to jest. Jeśli masz zmienną o nazwie
Range
i wskaźnik do niej o nazwiePRange
, łatwo na przykład przypadkowo pominąćP
. C # powinien to złapać, ale C i C ++ dają tylko ostrzeżenie. Lub, co bardziej niepokojące, załóżmy, że masz podwójną wersję o nazwieDRange
i próbkujesz ją do wersji o nazwie floatFRange
. Użyj jednego pływaka przez przypadek (co jest proste, ponieważ klucze sąsiadują na klawiaturze) i kod będzie rodzaj z pracy, ale to się przewrócić w dziwnych i nieprzewidywalny sposób, gdy proces skończy się rozdzielczością i niedomiarów.Nie jesteśmy już w czasach, w których mieliśmy ograniczenia nazewnictwa wynoszące 8 znaków lub 16 znaków lub dowolny dowolny limit. Czasami słyszałem, jak nowicjusze narzekają na dłuższe nazwy zmiennych, co powoduje, że kodowanie trwa dłużej. Jednak tylko nowicjusze narzekają na to. Poważni koderzy wiedzą, że to, co naprawdę wymaga czasu, to znajdowanie niejasnych błędów - a zły wybór nazewnictwa to klasyczny sposób, aby wpaść w tę konkretną dziurę.
źródło
Jedna anegdota, którą chciałbym dodać, chociaż
Range range
jest to syntaktycznie legalne, może utrudnić debugowanie lub refaktoryzację. Szukasz tej jednej zmiennej o nazwie „zakres” w pliku z dużą ilością zmiennych typu Range? Możesz później wykonać więcej pracy w wyniku wyboru nazwy.Jest to jednak w dużej mierze zależne od kontekstu. Jeśli jest to plik 30-liniowy, moje wypowiedzi tak naprawdę nie wchodzą w grę.
źródło
grep
jest doskonałym narzędziem, ale nie jest narzędziem refaktoryzującym. Narzędzia refaktoryzacji istnieją na każdej platformie programistycznej, z której korzystałem. (OS X, Ubuntu, Windows).Myślę, że możesz używać dni
Range range
dzisiejszych z jednego powodu: podświetlania składni. Nowoczesne IDE zwykle podkreślają nazwy typów i nazwy parametrów w różnych kolorach . Również typ i zmienna mają znaczną „logiczną odległość”, której nie można łatwo pomylić.Jeśli tak nie jest, rozważę inną nazwę lub spróbuję włączyć wtyczkę / rozszerzenie, które może to wyróżniać składnię.
źródło
Gdy funkcja jest ogólna, to znaczy, że parametry będą ogólne, a zatem powinny mieć nazwy ogólne.
Nie to, co mówisz, ale widziałem funkcje, które wykonują funkcje ogólne, które mają nazwy parametrów, które są myląco specyficzne. Lubić
Nazwa funkcji brzmi bardzo ogólnikowo, tak jakby można ją było zastosować do wielu ciągów w wielu sytuacjach. Ale nazwa parametru jest dziwnie specyficzna, co sprawia, że zastanawiam się, czy nazwa funkcji wprowadza w błąd, czy ... co?
Więc na pewno zamiast powiedzieć Range Range, możesz powiedzieć Range RangeToPad. Ale jakie informacje to dodaje? Oczywiście to zakres pad. Co jeszcze by to było?
Dodanie dowolnego przedrostka „my” lub „m_” lub cokolwiek innego, przekazuje czytelnikowi zero dodatkowych informacji. Kiedy korzystałem z języków, w których kompilator nie pozwala na to, aby nazwa zmiennej była taka sama jak nazwa typu - z rozróżnianiem wielkości liter lub bez - czasami umieszczam prefiks lub sufiks, aby kompilować go . Ale to tylko po to, by zaspokoić kompilator. Można argumentować, że nawet jeśli kompilator jest w stanie odróżnić, ułatwia to ludzkiemu czytelnikowi rozróżnienie. Ale wow, w Javie napisałem oświadczenia takie jak „Klient klient = nowy Klient ();” miliard razy i nigdy nie pomyliłem się. (Zawsze uważałem, że jest to trochę zbędne i raczej podoba mi się to w VB, możesz po prostu powiedzieć „ciemny klient jako nowy klient” i nie musisz podawać nazwy klasy dwa razy).
W przypadku, gdy DOKŁADNIE sprzeciwiam się nazwom ogólnym, to w tej samej funkcji występują dwa lub więcej wystąpień tego samego typu. SPECJALNIE parametry. Lubić:
Jaka jest różnica między zakresem 1 a zakresem 2? Jak mogę to wiedzieć? Jeśli jest to coś, gdzie naprawdę są dwie ogólne i wymienne wartości, dobrze, na przykład
Spodziewałbym się, że zwróci wartość true, jeśli zakresy będą się nakładać, a false, jeśli nie, więc są ogólne i wymienne.
Ale jeśli są różne, daj mi wskazówkę, jak się różnią! Niedawno pracowałem nad programem, który miał klasę „Place” do przechowywania danych o miejscach geograficznych i ze zmiennymi tego typu o nazwie „p”, „place”, „place2”, „myPlace” itp. Wow, te nazwy naprawdę pomagają mi ustalić, który jest który.
źródło