Konwencje nazewnictwa dla klas abstrakcyjnych

102

Wyraźnie pamiętam, że kiedyś wytyczną forsowaną przez Microsoft było dodanie sufiksu „Base” do klasy abstrakcyjnej, aby uniknąć faktu, że jest abstrakcyjna. Stąd mamy zajęcia jak System.Web.Hosting.VirtualFileBase, System.Configuration.ConfigurationValidatorBase, System.Windows.Forms.ButtonBase, i, oczywiście System.Collections.CollectionBase.

Ale ostatnio zauważyłem, że wiele klas abstrakcyjnych we frameworku wydaje się nie przestrzegać tej konwencji. Na przykład wszystkie poniższe klasy są abstrakcyjne, ale nie przestrzegają tej konwencji:

  • System.DirectoryServices.ActiveDirectory.DirectoryServer

  • System.Configuration.ConfigurationElement

  • System.Drawing.Brush

  • System.Windows.Forms.CommonDialog

I właśnie to mogłem zdobyć w kilka sekund. Poszedłem więc sprawdzić, co ma do powiedzenia oficjalna dokumentacja, aby upewnić się, że nie jestem szalony. Znalazłem nazwy klas, struktur i interfejsów w witrynie MSDN na stronie Wytyczne projektowe dotyczące tworzenia bibliotek klas . Co dziwne, nie mogę znaleźć żadnej wzmianki o wytycznej dodawania „Base” na końcu nazwy klasy abstrakcyjnej. Wytyczne nie są już dostępne dla wersji 1.1 platformy.

Więc czy ja to tracę? Czy te wytyczne kiedykolwiek istniały? Czy po prostu został porzucony bez słowa? Czy przez ostatnie dwa lata samodzielnie tworzyłem długie nazwy klas?

Ktoś rzucił mi tu kość.

Aktualizacja Nie jestem szalony. Wytyczne istniały. Krzysztof Cwalina narzekał na to w 2005 roku.

Mike Hofer
źródło
Jeśli czytasz ten artykuł, Krzysztof tylko narzeka na otrzymanie „zestawu rekomendacji” - niekoniecznie, że były to oficjalne rekomendacje Microsoftu. Przypominam sobie, że przeczytałem wytyczne dotyczące SM i widziałem, jak odradzają to.
John Rudy
1
Przeczytałem go, chociaż po raz pierwszy pamiętam, że widziałem ten artykuł. Właściwie to ulga. To zalecenie nigdy mi się nie podobało. Zaoszczędzi mi to dużo warczenia od tej chwili. :)
Mike Hofer

Odpowiedzi:

19

Ponadto, jeśli klasa abstrakcyjna ma kilka statycznych elementów członkowskich, które będą używane, „Base” może stać się brzydki.

Joel Coehoorn
źródło
14

Nie pamiętam takiej wskazówki. Uważam, że powinieneś użyć nazewnictwa, które ma sens. Czasami klasa abstrakcyjna jest zaprojektowana tylko po to, aby zapewnić wspólną funkcjonalność niektórym klasom (jako narzędzie), które moim zdaniem powinny mieć przyrostek. Jednak w niektórych przypadkach chcesz użyć go jako podstawy hierarchii polimorfizmu, która sama nie jest kompletna. W takich przypadkach sugeruję nazwanie jak normalna klasa.

Jak widać, prawdopodobnie nie zadeklarujesz metody, która akceptuje ButtonBase jako parametr. Został zaprojektowany, aby zapewnić minimalną funkcjonalność dla podklas. Możesz jednak traktować a ConfigurationElementjako byt, który ma różne formy, ale nie jest sam w sobie kompletny (i dlatego jest abstrakcyjny)

Mehrdad Afshari
źródło
11

Czasami Base jest nadal potrzebny, zwłaszcza gdy podajesz zarówno klasę konkretną, jak i klasę abstrakcyjną, aby ktoś mógł rozszerzyć w celu utworzenia konkretnej implementacji.
np. Controller i ControllerBase (w rzeczywistości kontroler jest również abstrakcyjny, ale zapewnia znacznie większą funkcjonalność niż ControllerBase)

Sufiks podstawy jest brzydki, gdy programuje się na interfejsie, więc myślę, że wytyczne firmy Microsoft, aby go nie używać, mają zastosowanie, gdy klasa abstrakcyjna jest używana głównie jako interfejs. Prawdopodobnie to, co mają na myśli przez publiczne API.

Chodzi o to, że są przypadki, w których nie ma lepszej alternatywy dla używania przyrostka Base.

James
źródło
4
Zgadzam się. Pracuję w systemie kanałów, który analizuje zawartość z różnych źródeł. Używamy w publicznym API interfejsu o nazwie IFeedParser , a wewnętrznie używamy podstawowej klasy abstrakcyjnej zawierającej typową funkcjonalność o nazwie BaseFeedParser
Rui Jarimba 14.12
1

Rozumiem, że skłonność do unikania bazę przyrostek, ale także zrozumieć potrzebę jakiegoś przyrostka. Komentarz do tego artykułu sugeruje użycie „Typu” jako przyrostka jako drugiego wyboru, aby nie używać żadnego. Uważam, że to zagmatwane, ale pomysł, że „takie niezobowiązujące słowo wskazywałoby na to, że to niezaangażowana klasa” utkwił we mnie.

Jako alternatywa: wolałbym użyć „Rodzaj” jako sufiksu, aby określić obiekt jako „należący do określonej rasy lub rodziny” ( Wikisłownik: -kind ).

Przykład: DataProvideri ReflectiveDataProvideroba sąDataProviderKind

Zainspirowany Biologią, gdzie np. "Canis lupus" należy do rodziny "Canoidea", co bardzo z grubsza tłumaczy się jako "psie".

Kooooons
źródło
1

Microsoft stwierdza pod adresem:

https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces

✓ NALEŻY ROZWAŻYĆ zakończenie nazwy klas pochodnych nazwą klasy bazowej. Jest to bardzo czytelne i jasno wyjaśnia związek. Oto kilka przykładów tego w kodzie: ArgumentOutOfRangeException, który jest rodzajem wyjątku, oraz SerializableAttribute, który jest rodzaj atrybutu. Należy jednak kierować się rozsądną oceną przy stosowaniu tej wskazówki; na przykład klasa Button jest rodzajem zdarzenia Control, chociaż Control nie pojawia się w jej nazwie. "

Ogólnie rzecz biorąc, to pośrednio wyklucza użycie „Base” w nazwie.

Sam Jazz
źródło