Wiele klas w jednym pliku .cs - dobry czy zły? [Zamknięte]

30

Czy wskazane jest utworzenie wielu klas w pliku .cs czy każdy plik .cs powinien mieć osobną klasę?

Na przykład:

public class Items
{
    public class Animal
    {
    }

    public class Person
    {
    }

    public class Object
    {
    }
}

Pomijając fakt, że jest to kiepski przykład dobrej architektury, czy więcej niż jedna klasa w pliku .cs ma zapach kodu?


źródło

Odpowiedzi:

30

Podany przez Ciebie przykład jest moim zdaniem w porządku. Deklarujesz klasy wewnętrzne , więc rozsądnie jest trzymać je w tym samym pliku . Jedynym sposobem na obejście tego byłoby uczynienie z Itemsklasy częściowej klasy i podzielenie jej na wiele plików. Rozważę tę złą praktykę. Moja ogólna zasada dotycząca klas zagnieżdżonych polega na tym, że powinny one być małe i prywatne. Istnieją dwa wyjątki od tego:

  • projektujesz klaster klas (bardziej powszechny w celu-c), dlatego rozsądne może być zastosowanie podejścia klasowego
  • potrzebujesz wyliczenia, które jest używane tylko z publicznym interfejsem API klasy nadrzędnej. W takim przypadku wolę zadeklarować publiczne wyliczenie wewnątrz klasy nadrzędnej zamiast zanieczyszczać moją przestrzeń nazw. Wyliczenie będące „wyliczeniem wewnętrznym” skutecznie skutkuje nadaniem mu ściśle określonego zakresu.

Jeśli sformułujesz pytanie nieco inaczej i zapytasz o: „Czy powinienem umieścić każdą klasę poziomu przestrzeni nazw we własnym pliku”, wtedy moja odpowiedź brzmiałaby „tak”.

Projektując klasy, przestrzegamy zasady pojedynczej odpowiedzialności. Czytanie kodu staje się o wiele łatwiejsze, jeśli jego kształt jest zgodny z semantyką, dlatego dzielenie plików według klas jest rozsądne.

Z mechanicznego punktu widzenia posiadanie pliku według klasy ma kilka zalet. Możesz otworzyć wiele klas jednocześnie w różnych oknach. Jest to szczególnie ważne, ponieważ żaden poważny programista nie pracuje z mniej niż dwoma ekranami. Będąc w stanie mieć więcej kontekstu przed moją głową, mogę zachować większy kontekst w mojej głowie. (Większość IDE pozwoli ci dwukrotnie otworzyć ten sam plik, ale wydaje mi się to niezręczne).

Kolejnym ważnym aspektem jest kontrola źródła i łączenie. Trzymając osobne klasy, unikniesz wielu kłopotów, gdy wprowadzane są zmiany w tym samym pliku, ponieważ należy zmienić osobne klasy.

Johannes Rudolph
źródło
1
Zgadzam się, ale z drugiej strony klasy wewnętrzne są bardzo rzadkie z mojego doświadczenia. Aby być uczciwym, tak naprawdę nie ma zbyt wiele, co może naprawdę uzasadnić klasy wewnętrzne, jedyny znany mi przypadek to klasy IEnumerable, w których tak naprawdę nie chodzi o klasę rzeczywistą, o ile można ją wyliczyć. We wszystkich innych przypadkach każda klasa powinna otrzymać własny plik. Jeśli nie z innego powodu z powodu problemów z kontrolą źródła.
Homde
2
Dodałbym, że klasy wewnętrzne powinny być rzadkim wyjątkiem i prawie nigdy nie powinny być publiczne.
Josh
Tak, uczy mnie, że jestem tak szybki, że klasy wewnętrzne są w porządku, jednak pytanie, czy powinieneś użyć klasy wewnętrznej, to kolejne pytanie :)
Krystan zaszczyca
11

Mówiąc brutalnie, nie dodawaj do pliku więcej niż jednej klasy root. W moim ostatnim zadaniu były pliki z nie tylko wieloma klasami, ale wieloma przestrzeniami nazw, a to rozciągało się na wiele tysięcy wierszy kodu. Bardzo trudny do naśladowania.

Jeśli istnieją klasy blisko ze sobą powiązane, nazwij ich pliki podobnie lub umieść je w podfolderze.

Fizyczna separacja plików klas pomaga (zauważ, że nie koniec), prowadzi do rozdzielenia obaw i luźniejszego łączenia.

Z drugiej strony, twój przykład nie pokazuje więcej niż jednej klasy root. Istnieje kilka klas zagnieżdżonych (uwaga: staraj się nie tworzyć żadnych klas zagnieżdżonych, ale privatejeśli możesz to zaprojektować) i doskonale jest mieć to w jednym pliku.

Jesse C. Slicer
źródło
3
Boże, to brzmi okropnie.
Dlaczego pytasz? Czy ktoś cię ocenił i chcesz zapytać dlaczego?
Chwila ... czy odnosiłeś się do małej anegdoty na temat mojej ostatniej pracy? Jeśli tak, źle zrozumiałem i przepraszam za to.
Jesse C. Slicer
Zgadzam się całkowicie. Pracuję nad projektem, w którym większość plików ma co najmniej 4 klasy na plik. Niektóre mają nawet 22 klasy + 1 interfejs na plik.
L_7337,
7

Jeśli pliki są bardzo spójne, na przykład gdy jest to alternatywa dla kilku bardzo krótkich plików o podobnych nazwach, może to być dobry pomysł.

Na przykład uważam, że przy użyciu Fluent NHibernate łatwiej gdybym zachować Entityi EntityMapw jednym pliku, mimo tego, co moje narzędzia może mieć do powiedzenia na ten temat.

W większości przypadków trudniej jest znaleźć klasy. Używaj oszczędnie i ostrożnie.

mootinator
źródło
1
Szczególnie dla Fluent NHibernate uznałem, że warto je przechowywać nie tylko w tym samym pliku, ale również w tej samej klasie. Wszystkie moje byty mają zagnieżdżoną klasę o nazwie Mapa.
James Beninger,
7

Po prostu tak, nie jest to dobra forma, aby to zrobić, a powiem ci dlaczego, nieco później, gdy twoje rozwiązanie stanie się duże, zapomnisz, gdzie są klasy, ponieważ nazwa pliku nie będzie już reprezentować zawartości, jaka jest nazwa pliku AnimalPersonObject.cs to po prostu niemożliwe.

Jasne, że możesz obejść ten problem, używając funkcji w narzędziach takich jak resharper do przeskakiwania do typów, ale 1 klasa na plik (w tym interfejsy) jest naprawdę podstawą każdego standardu kodu, jaki kiedykolwiek widziałem, nie tylko w .net, ale w Javie i c ++ i wiele innych języków, tych, które często nie mają problemów z utrzymaniem, a młodszym programistom trudno będzie zrozumieć kod.

Prawie wszystkie narzędzia do optymalizacji kodu podpowiedzą, aby przenieść klasy do osobnego pliku, więc dla mnie tak, to jest zapach kodu i trzeba go trochę zneutralizować :)

krystan honor
źródło
3

Inną kwestią jest to, że przy bardzo dużych i podobnych klasach w tym samym pliku - gdy deklaracja klasy nie jest widoczna przez cały czas - możesz w końcu umieścić punkty przerwania w niewłaściwej klasie i zastanawiać się, dlaczego nie zostały trafione ... grrr! :)

Julia Hayward
źródło
-3

Zasadniczo, jeśli potrzebujesz użyć tej klasy tylko z klasy „macierzystej” (pod względem zakresu), wówczas zwykle jest właściwe zdefiniowanie jej jako klasy zagnieżdżonej.

hjdjdg
źródło