Użycie tej samej nazwy dla przestrzeni nazw i klasy w niej jest problematyczne.
Jeśli przestrzeń nazw zawiera więcej niż jedną klasę, dlaczego umieszczane są tam inne klasy? to nie wydaje się właściwe, ponieważ celem nazwy przestrzeni nazw jest opisanie wszystkich klas w niej zawartych , a nie tylko jednej. Na przykład, jeśli masz JsonSerialization
,BinarySerialization
i XmlSerialization
klas w przestrzeni nazw, warto byłoby, aby wymienić swoje nazw XmlSerialization
?
Zwykle dzieje się tak, że z powodu wyodrębnienia klasy z istniejącej przestrzeni nazw lub połączenia wielu klas lub innej reorganizacji, znajdujesz się w przestrzeni nazw zawierającej główną klasę; stopniowo wprowadzane są tam mniejsze klasy, ponieważ są one nieco związane z klasą pierwotną. Na przykład przestrzeń nazw LogParser
może zawierać jedną klasę LogParser
, a następnie ktoś ją umieszcza LogConverter
, ponieważ jest to dość związane z analizatorem składni LogSearcher
, itd. Problem polega na tym, że nazwa przestrzeni nazw nie została zmieniona: jak tylko LogConverter
została dodana, właściwość nazwa powinna zostać zmieniona na LogsProcessing
lub po prostu Logs
.
Jeśli przestrzeń nazw zawiera tylko jedną klasę, może to oznaczać problem w organizacji kodu.
Chociaż kilkakrotnie widziałem sytuacje, w których jedna klasa z właściwymi zasadami SOLID bardzo różniła się od wszystkiego innego w bazie kodu i dlatego została umieszczona w dedykowanej przestrzeni nazw, takie przypadki są rzadkie. Częściej oznacza to problem. Podobnie nic nie stoi na przeszkodzie, aby klasa zawierała jedną metodę, ale najczęściej klasy takie wskazywałyby na problem.
Nawet jeśli twoja przestrzeń nazw zawiera tylko jedną klasę, zwykle istnieje sposób, aby być bardziej szczegółowym przy nazywaniu klasy i bardziej ogólnym przy nazywaniu przestrzeni nazw. Wyobraź sobie aplikację, która między innymi powinna w danym momencie konwertować pliki zapisane w formacie ABC do formatu DEF. Konwersja nie wymaga żadnej deserializacji / serializacji do / z obiektów biznesowych i odbywa się poprzez zastosowanie zestawu wyrażeń regularnych, które są wystarczająco krótkie, aby można je było umieścić w samej klasie konwersji o nazwieAbcToDefConverter
. Cała logika konwersji zajmuje około 80 LLOC w około dziesięciu współzależnych metodach - wydaje się być sytuacją, w której absolutnie nie ma potrzeby dzielenia istniejącej klasy ani tworzenia dodatkowych klas. Ponieważ pozostała część aplikacji nie ma nic wspólnego z konwersjami, klasy nie można grupować z innymi klasami w istniejących przestrzeniach nazw. Więc tworzy się przestrzeń nazwaną AbcToDefConverter
. Chociaż nie ma w tym nic złego, można również użyć bardziej ogólnej nazwy, takiej jak Converters
. W językach takich jak Python, w których preferowane są krótsze nazwy i narzucane jest powtarzanie, może się nawet zdarzyć converters.Abc_To_Def
.
Dlatego używaj innych nazw dla przestrzeni nazw niż dla klas, które zawierają. Nazwa klasy powinna wskazywać, co robi klasa, a nazwa przestrzeni nazw powinna podkreślać to, co wspólne dla wszystkich klas w niej zawartych.
Nawiasem mówiąc, klasy użytkowe są z natury złe: zamiast zawierać coś konkretnego, na przykład arytmetykę dowolnej precyzji, raczej zawierają wszystko, co nie znalazło się w innych klasach . To po prostu złe nazewnictwo, podobnie jak Miscellaneous
katalog na pulpicie - coś, co wskazuje na brak organizacji.
Nazywanie istnieje z jakiegoś powodu: aby ułatwić Ci życie, gdy będziesz musiał później znaleźć rzeczy. Wiesz, że jeśli musisz narysować wykres, możesz spróbować wyszukać „wykres” lub „wykres”. Gdy musisz zmienić sposób generowania faktur przez aplikację, wyszukaj „faktura [e / ing]” lub „rachunek”. Podobnie, spróbuj wyobrazić sobie przypadek, w którym powiesz sobie: „hm, ta funkcja prawdopodobnie powinna być znaleziona w misc”. Nie mogę
Spójrz na .NET Framework. Czy większość z tych klas nie jest klasami użytkowymi? Mam na myśli, że mają niewiele wspólnego z domeną biznesu. Jeśli pracuję nad aplikacją finansową, witryną e-commerce lub platformą edukacyjną nowej generacji, serializowanie XML, czytanie plików lub wykonywanie zapytań SQL lub wykonywanie transakcji to wszystko, co jest użytecznością. Jednak nie są one wywoływane UtilitySerialization
lub UtilityTransaction
nie są w Utility
przestrzeni nazw. Mają odpowiednie nazwy, które umożliwiają (i ułatwiają, dzięki deweloperom .NET!) Znajdowanie ich, kiedy ich potrzebuję.
To samo przychodzi do swoich klas ty powszechnie ponownego użycia w swoich aplikacjach. Nie są to klasy użytkowe. Są to klasy, które robią pewne rzeczy, a rzeczy, które robią, powinny być nazwami klas.
Wyobraź sobie, że stworzyłeś kod, który zajmuje się jednostkami i konwersją jednostek. Możesz nazwać to Utility
i być znienawidzonym przez swoich kolegów; lub możesz to nazwać Units
i UnitsConversion
.