Czy istnieją dobre techniki lub testy dla nazewnictwa typów?

23

Niezręczne, otwarte pytanie, ale to problem, z którym zawsze się spotykam:

Oprogramowanie, które jest łatwe w utrzymaniu i obsłudze, jest dobrze zaprojektowane. Próba uczynienia projektu intuicyjnym oznacza nazywanie komponentów w taki sposób, aby następny programista mógł móc wywnioskować ich działanie. Dlatego nie nazywamy naszych klas „Type1”, „Type2” itp.

Podczas modelowania koncepcji rzeczywistej (np. Klienta) jest to na ogół tak proste, jak nazywanie swojego typu po modelowaniu koncepcji rzeczywistej. Ale kiedy budujesz abstrakcyjne rzeczy, które są bardziej zorientowane na system, bardzo łatwo zabraknie imion, które są zarówno łatwe do odczytania, jak i łatwe do strawienia.

Gorzej (dla mnie), gdy próbuję nazwać rodziny typów, z typem bazowym lub interfejsem, który opisuje, co muszą zrobić komponenty, ale nie sposób ich działania. To naturalnie prowadzi do każdego typu pochodzącego próbuje opisać smak realizacji (np IDataConnectionoraz SqlConnectionw .NET Framework), lecz jak można wyrazić coś skomplikowane jak „działa przez odbicie i szuka konkretnego zestawu atrybutów”?

Potem, kiedy już w końcu wybrał nazwę typu uważasz opisuje to, co próbuje zrobić, twój kolega pyta „WTF czy to DomainSecurityMetadataProviderfaktycznie zrobić?

Czy są jakieś dobre techniki wyboru dobrej nazwy dla komponentu lub jak zbudować rodzinę komponentów bez uzyskiwania mętnych nazw?

Czy są jakieś proste testy, które mogę zastosować do nazwy, aby lepiej wyczuć, czy nazwa jest „dobra” i czy powinna być bardziej intuicyjna dla innych?

Paul Turner
źródło
20
istnieje sześć technik , które okazały się skuteczne dla mnie: 1) spędzają dużo czasu na wymyślaniu imiona 2) Recenzje użyć kodu 3) nie wahaj się przemianować 4) spędzają dużo czasu na wymyślaniu imiona 5) Recenzje użycie kodu 6) nie wahaj się zmienić nazwy
komnata
5
@gnat: Prześlij swoją odpowiedź jako odpowiedź, abyśmy mogli ją zagłosować.
S.Lott
3
Często używam tezaurusa, kiedy robię nowy rozwój, aby pomóc mi wymyślić dobre nazwiska.
Dr Wily's Apprentice,
3
Staram się unikać nazywania czegokolwiek „Menedżerem”. Alan Green i Jeff Atwood twierdzą, że termin ten jest nadużywany i jest zbyt niejasny, aby przekazać sens. Muszę się zgodzić.
Dr Wily's Apprentice,

Odpowiedzi:

41

Jeśli chodzi o nazewnictwo, sprawdzono dla mnie sześć technik :

  1. spędzać dużo czasu na wymyślaniu nazwisk
  2. użyj recenzji kodu
  3. nie wahaj się zmienić nazwy
  4. spędzać dużo czasu na wymyślaniu nazwisk
  5. użyj recenzji kodu
  6. nie wahaj się zmienić nazwy

PS. W przypadku, gdy Twój interfejs API będzie publiczny, powyższe ma zastosowanie wcześniej - ponieważ wiesz,

„Publiczne interfejsy API, takie jak diamenty, są wieczne. Masz jedną szansę, aby zrobić to dobrze, więc daj z siebie wszystko ...” (Joshua Bloch, Jak zaprojektować dobry interfejs API i dlaczego to ma znaczenie )

komar
źródło
1
Jeśli jest to publiczny interfejs API, możesz skorzystać z trzech dodatkowych technik ...
UncleZeiv,
1
@UncleZeiv: takie jak ....?
FrustratedWithFormsDesigner
3
@FrustratedWithFormsDesigner: 1. spędzaj dużo czasu na wymyślaniu nazw 2. używaj recenzji kodu i 3. nie wahaj się zmienić nazwy
S.Lott
3
Ta odpowiedź przekonała mnie, że ogólnie: nie, nie ma łatwego sposobu na poprawne nazewnictwo. Próbuję tylko naprawdę ciężkiej pracy.
Paul Turner
4
7. Nie wahaj się przeprojektować typy lub funkcje, jeśli okaże się, że nie można opracować dla nich odpowiedniej nazwy. Dobrze zaprojektowany kod zawsze można poprawnie nazwać.
Joren
8

Mój test podstawowy polega na tym, czy możesz opisać funkcję zmiennej, używając tylko słów ze zmiennej:

np. jeśli DomainSecurityMetadataProvider „Dostarcza metadane bezpieczeństwa domeny” lub „Dostarcza metadane związane z bezpieczeństwem domeny”, to dobrze.

Istnieją jednak niuanse, które różnią się w zależności od osoby:

np. dla mnie original_team_code jest kodem dla oryginalnego zespołu, podczas gdy dla kogoś innego może być oryginalnym kodem dla zespołu. Moim osobistym ulubionym z nich był „UnsafeLegacyMutex”, którego nie mogłem powstrzymać przed przeczytaniem jako „To jest Legacy Mutex, który jest niebezpieczny”, a nie „To jest Mutex dla ThreadUnsafe Legacy Code”.

Więc moim rozszerzonym testem jest zapisanie zmiennej na tablicy / wiki / chat i niech ludzie zgadną, co to znaczy.

deworde
źródło
7

Czy są jakieś dobre techniki wyboru dobrej nazwy dla komponentu lub jak zbudować rodzinę komponentów bez uzyskiwania mętnych nazw?

Nie całkiem.

Jedną wskazówką jest jednak unikanie „głosu pasywnego”.

„DomainSecurityMetadataProvider” jest pasywny. Nie ma czasownika, wszystkie rzeczowniki i rzeczowniki są używane jako przymiotniki.

„ProvideMetadataForDomainSecurity” jest bardziej aktywne. Jest czasownik.

Programowanie obiektowe to wszystko (naprawdę) czasownik. Rzeczownik == obiekt. Czasownik == metoda. Tak więc nazwa klasy jest na ogół bardzo „rzeczownikowa”. Przełamanie tego nawyku i rozpoczęcie wstawiania czasowników jest trudne.

Czy są jakieś proste testy, które mogę zastosować do nazwy, aby lepiej wyczuć, czy nazwa jest „dobra” i czy powinna być bardziej intuicyjna dla innych?

Tak. Zdefiniowałeś doskonały test w swoim pytaniu. Zapytaj innych ludzi.

W dawnych czasach nazywaliśmy to „poradnikiem projektowym”. To była wielka, spocona transakcja w metodyce wodospadu. W dzisiejszych czasach, dzięki metodom zwinnym, powinna być zwykła współpraca między autorem a użytkownikami klasy. To nie zajmuje (i nie powinno) długo. Omówienie projektu (i nazw) przed napisaniem testów (i kodu) zmniejszy czynnik zdziwienia i może zapobiec WTF.

S.Lott
źródło
12
Nie jestem pewien, czy zgadzam się z ideą głosu pasywnego. Dla mnie Klasy mają większy sens niż Rzeczowniki.
deworde
7
Mówiąc ogólnie, staram się zachować moje nazwy typowe w pasywnym głosie, ponieważ pasuje to do stylu rzeczownikowo-czasownikowego OOP. Uważam, że ProvideMetadataForDomainSecurityto kiepska nazwa. Nazwy metod są zazwyczaj o wiele łatwiejsze do nazwania dokładnie, ponieważ mogę swobodnie używać czasowników. Istotą problemu jest ograniczenie języka.
Paul Turner
O ile lubię „pytać ludzi” jako prawdziwy test, muszę zapytać moich kolegów o wymienienie przynajmniej dwa razy dziennie. Mam nadzieję na coś, co nie wymaga czasu innych ludzi.
Paul Turner
2
Klasy zrobić sensu, ponieważ rzeczowników. Problemem są te złożone klasy z długimi rzeczownikami-przymiotnikami. Przyimki też mogą pomóc.
S.Lott
2
Współpraca jest tajemnicą dobrego oprogramowania. Współpraca wymaga czasu. Nie ma królewskiej drogi do dobrego pisania.
S.Lott
6

Korzystanie z tezaurusa

Bardzo często będę odnosił się do tezaurusa, kiedy robię nowy rozwój, aby znaleźć odpowiednie słowa do opisania moich klas i metod.

Klasy, które przede wszystkim zawierają logikę operacji

Zazwyczaj nazywam klasy, które przede wszystkim zapewniają metody działania w strukturze czasownikowej, np. „EntityProvider”, „EntityLocator” itp.

Te klasy na ogół nie zawierają dużo stanu.

Klasy zawierające stan

Ekrany interfejsu użytkownika i jednostki danych są na ogół stanowe, więc po prostu nazywam te klasy wzorcem rzeczownikowym lub przymiotnikowo-rzeczownikowym.

Przykłady: osoba, pracownik, obecny pracownik, były pracownik

Klasy użyteczności

Klasy, które zawierają tylko metody statyczne, są ogólnie uważane za klasy „użytkowe”, więc konsekwentnie nazywam je sufiksem „Użyteczność”.

Przykłady: NetworkUtilities, FileUtilities

Testy

Nie mam dobrych testów pozwalających stwierdzić, czy coś jest źle nazwane, ale sugerowałbym, aby spróbować użyć pojedynczego rzeczownika i / lub pojedynczego czasownika w nazwie, a następnie zastanowić się, czy rzeczownik / czasownik dokładnie opisuje to, co „ zmiana nazwy.

Jeśli uważasz, że w klasie / metodzie jest coś więcej, co nie jest przechwytywane przez nazwę, wówczas może być konieczne ponowne przetworzenie tej klasy / metody.

Alan Green i Jeff Attwood pisali o złu nazywania klas za pomocą sufiksu „Manager”. Twierdzą, że termin „menedżer” jest nadużywany i jest zbyt niejasny, aby przekazać coś sensownego. Muszę się zgodzić.

Artykuł Jeffa zawiera także listę sugerowanych wskazówek z Kodeksu ukończonego przez Steve'a McConnella.

zmienne

Ostatnio eksperymentowałem z dłuższymi opisowymi nazwami zmiennych / parametrów, które zawierają przyimki, takie jak „Of”, „By”, „For” itp. Niektóre przykłady pokazano poniżej:

string firstNameOfEmployee;

string lastNameOfEmployee;

// here I nimbly avoid worrying about whether to call it "Id" or "ID" :)
int idOfEmployee;

decimal amountForDeposit;

Account accountForDeposit;

Uważam, że działa to dobrze z funkcją inteligencji Visual Studio, która ułatwia wpisywanie tych długich nazw. Zauważyłem również, że mniej powielania prefiksów nazw zmiennych (np. PersonID, personFirstName, personLastName vs. idOfPerson, firstNameOfPerson, lastNameOfPerson), zapewniając lepsze „hash”, dzięki czemu intellisense jest jeszcze bardziej użyteczny.

Dr Wily's Apprentice
źródło
1
Popieram kwestię długich nazw zmiennych, ponownie, Visual Studio (jeśli go używasz) sprawia, że ​​nie ma to nic przeciwko. Długie nazwy zmiennych, które są wyraźne, są o wiele mniej szkodliwe niż krótkie nazwy zmiennych, w których trzeba „pomyśleć” lub zbadać, co właściwie oznacza ta nazwa. Pomyśl także o kontekście. Wolę widzieć „peopleToDelete” niż „listOfPeople”. Ponownie Visual Studio informuje o typie zmiennej, nie trzeba jej uwzględniać.
John Bubriski,
Nie podoba mi się także skomplikowany zapis węgierski, który dodałeś do nazw zmiennych. Nie powinienem się przejmować, czy zbiór identyfikatorów osób to a List, tablica IEnumerablelub ConcurrentQueue. To kilka identyfikatorów, które muszę wymienić, a szczegóły dotyczące sposobu ich przechowywania są niepotrzebnym bagażem psychicznym. Chociaż ogólnie zgadzam się, że jeśli dłuższa nazwa jest znacznie bardziej opisowa, należy ją faworyzować w stosunku do krótszej, mniej wyraźnej nazwy.
Allon Guralnek
@Allon - Zabawne, miałem zamiar zrewidować moją odpowiedź na podstawie komentarza SkippyFire. Ja się z tobą zgadzam; mój przykład trzepie węgierską notację. Moją jedyną obroną jest to, że łatwo jest odczytać kod i zrozumieć typy danych zaangażowane bez dostępnego IDE, na przykład gdybym czytał przez różnicę kontroli źródła. Ale to nie jest wymówka. :) Zamierzam zrewidować mój przykład, aby był podobny do firstNameOfEmployee, lastNameOfEmployee itp.
Apprentice Dr Wily's
2

Następnie, kiedy w końcu wybrałeś nazwę typu, który Twoim zdaniem opisuje, co próbuje zrobić, twój kolega pyta: „WTF naprawdę robi to DomainSecurityMetadataProvider?”

Jakiej nazwy oczekujesz dla klasy złożonej i specyficznej dla domeny? Jest to tak dobre, jak to będzie możliwe, bez nadawania nazwy klasie zdania (co sprawi, że wszyscy będą myśleć, że zbyt wiele odpowiedzialności spoczywa na jednej klasie)

Rozważę usunięcie dostawcy z nazwy. Jeśli konkretnie wspomina o metadanych, wszyscy już wiedzą, że używasz refleksji. Możesz sprawić, by jedno słowo było bardziej zwięzłe (lub ewentualnie zmienić na inne słowo - jest bardziej konsumentem niż dostawcą z tego, co napisałeś)

Brian
źródło
Metadane, o których mowa, nie pochodzą z refleksji (ale opisują sposób traktowania typów). Typ implementuje ISecurityMetadataProviderinterfejs, który istnieje punkt iniekcyjny w infrastrukturze bezpieczeństwa, w celu dostarczania informacji do podsystemu. Nazewnictwo jest trudne.
Paul Turner
Uważam się za DomainSecurityMetadataProviderdostawcę DomainSecurityMetadataobiektu, w którym DomainSecurityMetadatasame metadane. Jasna i zrozumiała nazwa. Nie muszę nawet wiedzieć, co DomainSecurityMetadatato jest! To tylko jakiś obiekt, który zapewnia ten dostawca. Samo usunięcie Providersufiksu nie poprawia czytelności, ale wręcz przeciwnie - zmniejsza go. Bez tego przyrostka pomyślałbym, że to tylko niektóre metadane (obiekt kontenera dla niektórych metadanych), ale nie obiekt, z którego można uzyskać metadane (dostawca).
Ruslan Stelmachenko
0

Użyj metafor do opisania części systemu. Nie tylko pozwoli ci odkryć nowe analogie, ale także ułatwi nazewnictwo.

(Wiem, że to nie jest mocny przykład, ale mimo to) Na przykład możesz wywołać zmienną lub typ as mailbox, który służy jako kolejka dla odebranych wiadomości dla klasy.

nimcap
źródło
-1

Jedną rzeczą, na której jestem bardzo stanowczy, jest to, że NIGDY nie powinno się dopuszczać do niepoprawności. Najlepszy przykład, podczas niektórych przefakturowań wiele się zmieniło, a kilka zmiennych zaczęło odnosić się do czegoś innego niż sugerowały ich nazwy.

Wkrótce jeden programista spędził wiele lat i korzystał z bardzo drogich wywołań bazy danych, próbując zdobyć pewne dane, które zostały już wyodrębnione i zapisane. Zmieniłem nazwę wszystkiego i nagle mogliśmy usunąć tonę skomplikowanej i błędnej logiki.

deworde
źródło
1
powinieneś usunąć tę odpowiedź i zmienić ją w oryginalną odpowiedź
Ryathal,
Myślę, że to inna odpowiedź niż moja inna odpowiedź.
deworde
-1

Mam nadzieję, że przypadki, w których trzeba tak mocno myśleć o nazwiskach, są rzadkie. Gdy pojawią się takie przypadki, po prostu napisz akapit wyjaśniający, co robi klasa. W przeciwieństwie do komentarzy w funkcji lub komentarza na poziomie funkcji, główny cel klasy rzadko się zmienia, więc ryzyko przedawnienia komentarzy jest stosunkowo niewielkie. Masz więc luksus pisania kilku akapitów lub nawet rysowania ASCII, aby wyjaśnić, co robi klasa.

kizzx2
źródło