Czy posiadanie wielu klas w tym samym pliku jest złą praktyką?

82

Kiedyś miałem jedną klasę na jeden plik. Na przykład car.cs ma klasę car . Ale ponieważ programuję więcej klas, chciałbym dodać je do tego samego pliku. Na przykład car.cs ma klasę samochód i klasę drzwi itp.

Moje pytanie jest dobre dla Java, C #, PHP lub dowolnego innego języka programowania. Powinienem spróbować nie mieć wielu klas w tym samym pliku, czy jest to w porządku?

Pokus
źródło

Odpowiedzi:

94

Myślę, że powinieneś spróbować zachować swój kod do 1 klasy na plik.

Proponuję to, ponieważ później łatwiej będzie znaleźć swoją klasę. Ponadto będzie działać lepiej z systemem kontroli źródła (jeśli plik ulegnie zmianie, wiesz, że zmieniła się określona klasa).

Jedynym przypadkiem, w którym wydaje mi się, że poprawne jest użycie więcej niż jednej klasy na plik, jest użycie klas wewnętrznych ... ale klasy wewnętrzne znajdują się wewnątrz innej klasy i dlatego można je pozostawić w tym samym pliku. Role klas wewnętrznych są silnie powiązane z klasami zewnętrznymi, więc umieszczenie ich w tym samym pliku jest w porządku.

Patrick Desjardins
źródło
1
Po zobaczeniu, co kotlin może zrobić w jednym pliku, zacząłem wierzyć, że niektóre rzeczy, takie jak DTO, mogą znajdować się w jednym pliku.
John Tribe
1
Co więcej, klasy, które miałbyś w tym samym pliku, są zazwyczaj ściśle powiązane, co może utrudniać edycję, ponieważ nie jest tak łatwo przeglądać wiele klas jednocześnie. Musisz dużo przewijać. Podzielony widok pomaga, ale nie jest to tak łatwe, jak po prostu posiadanie oddzielnego okna dla każdego pliku / klasy.
Chad Hedgcock
A co z automatycznym ładowaniem? Podczas definiowania wielu klas w jednym pliku źródłowym funkcja automatycznego ładowania stanie się bardziej złożona. patrz stackoverflow.com/questions/37982012/…
Alexander Behling,
26

W Javie, jedna klasa publiczna na plik jest sposobem działania języka. W pakiecie można zebrać grupę plików Java.

Jednak w Pythonie pliki są „modułami” i zazwyczaj mają kilka ściśle powiązanych klas. Pakiet Pythona to katalog, tak jak pakiet Java.

Daje to Pythonowi dodatkowy poziom grupowania między klasą a pakietem.

Nie ma jednej właściwej odpowiedzi, która byłaby niezależna od języka. To zależy od języka.

S.Lott
źródło
23

Jedna klasa na plik to dobra zasada, ale należy zrobić kilka wyjątków. Na przykład, jeśli pracuję w projekcie, w którym większość klas ma powiązane typy kolekcji, często trzymam klasę i jej kolekcję w tym samym pliku, np .:

public class Customer { /* whatever */ }

public class CustomerCollection : List<Customer> { /* whatever */ }

Najlepszą zasadą jest zachowanie jednej klasy na plik, z wyjątkiem sytuacji, gdy zaczyna to utrudniać, a nie ułatwiać. Ponieważ funkcja Find in Files w programie Visual Studio jest tak skuteczna, prawdopodobnie i tak nie będziesz musiał spędzać dużo czasu na przeglądaniu struktury plików.

Ryan Lundy
źródło
3
Nie. To zła rada. Skorzystaj z porady dotyczącej zaakceptowanej odpowiedzi. Powinieneś oddzielić repozytorium obiektów od zapisywanej klasy. Po prostu tworzy niepotrzebne zamieszanie.
Hudson,
4
@Hudson Nie widzę powyżej żadnego kodu „repozytorium obiektów”.
Ryan Lundy
18

Nie, nie sądzę, że to całkowicie zła praktyka. Mam na myśli to, że ogólnie najlepiej jest mieć osobny plik na klasę, ale są zdecydowanie dobre przypadki wyjątków, w których lepiej jest mieć kilka klas w jednym pliku. Dobrym przykładem jest grupa klas wyjątków, jeśli masz ich kilkadziesiąt dla danej grupy, czy naprawdę ma sens posiadanie osobnego pliku dla każdej z dwóch klas liniowych? Twierdzę, że nie. W tym przypadku posiadanie grupy wyjątków w jednej klasie jest znacznie mniej kłopotliwe i proste IMHO.

James
źródło
10

Odkryłem, że za każdym razem, gdy próbuję połączyć wiele typów w jeden plik, zawsze wracam do nich i rozdzielam je po prostu dlatego, że ułatwia to ich znalezienie. Ilekroć łączę, zawsze jest moment, w którym próbuję dowiedzieć się, jak zdefiniowałem typ x.

Więc teraz moja osobista zasada jest taka, że ​​każdy indywidualny typ (może z wyjątkiem klas podrzędnych, przez które oznacza klasę wewnątrz klasy, a nie klasę dziedziczoną) otrzymuje swój własny plik.

Daniel Schaffer
źródło
9

Ponieważ Twoje IDE zapewnia funkcjonalność „ Przejdź do ” i masz pewną kontrolę nad przestrzenią nazw w swoich klasach, poniższe korzyści z posiadania wielu klas w tym samym pliku są dla mnie tego warte.

Klasy rodziców i dzieci

W wielu przypadkach bardzo pomocne jest posiadanie dziedziczonych klas w ich pliku klasy podstawowej .

Dość łatwo jest wtedy zobaczyć, które właściwości i metody dziedziczy Twoja klasa podrzędna, a plik zapewnia szybszy przegląd ogólnej funkcjonalności.

Publiczne: Małe - Pomocnicze - Klasy DTO

Kiedy potrzebujesz kilku zwykłych i małych klas dla określonej funkcjonalności, uważam, że zbyteczne jest posiadanie pliku ze wszystkimi odniesieniami i zawiera tylko klasę 4-8 Liner .....

Nawigacja po kodzie jest również łatwiejsza, wystarczy przewinąć jeden plik zamiast przełączać się między 10 plikami ... Jest również łatwiejsza do refaktoryzacji, gdy trzeba edytować tylko jedną referencję zamiast 10 ...

Ogólnie rzecz biorąc, złamanie żelaznej zasady 1 klasy na plik zapewnia dodatkową swobodę w organizowaniu kodu.

To, co się wtedy stanie, naprawdę zależy od Twojego IDE, języka, komunikacji w zespole i umiejętności organizacyjnych.

Ale jeśli chcesz tej wolności, po co poświęcać ją dla żelaznej zasady?

Anestis Kivranoglou
źródło
7

Jeśli pracujesz w zespole, przechowywanie klas w oddzielnych plikach ułatwia kontrolowanie źródła i zmniejsza ryzyko konfliktów (wielu programistów zmienia ten sam plik w tym samym czasie). Myślę, że ułatwia to również znalezienie kodu, którego szukasz.

Jim Anderson
źródło
7

Zasada, którą zawsze kieruję się, to mieć jedną główną klasę w pliku o tej samej nazwie. Mogę dołączać klasy pomocnicze do tego pliku, w zależności od tego, jak mocno są one połączone z główną klasą pliku. Czy klasy wsparcia są samodzielne, czy są przydatne same w sobie? Na przykład, jeśli metoda w klasie wymaga specjalnego porównania do sortowania niektórych obiektów, nie przeszkadza mi umieszczanie klasy funktora porównawczego w tym samym pliku, co metoda, która jej używa. Nie spodziewałbym się, że użyję go gdzie indziej i nie ma sensu, aby był sam.

Boojum
źródło
6

Może to być złe z punktu widzenia przyszłego rozwoju i łatwości utrzymania. Dużo łatwiej jest zapamiętać, gdzie jest klasa Car, jeśli masz klasę Car.cs. Gdzie szukałbyś klasy Widget, gdyby nie było Widget.cs? Czy to widget samochodowy? Czy to widget silnika? Och, może to widget bajgla.

Steven Behnke
źródło
2
Jak wspomniano na stackoverflow.com/questions/360643/… , z typowymi narzędziami nawigacyjnymi i tak nie musisz nawigować według plików. Zamiast tego nawigujesz według klas / członków.
Suma,
6

Tylko czas uważam lokalizacje plików jest, gdy trzeba utworzyć nowe klasy. W przeciwnym razie nigdy nawiguję według struktury plików. Używam „przejdź do klasy” lub „przejdź do definicji”.

Wiem, że jest to trochę kwestia szkolenia; uwolnienie się od fizycznej struktury plików projektów wymaga praktyki. Jest to jednak bardzo satysfakcjonujące;)

Jeśli dobrze będzie umieścić je w tym samym pliku, bądź moim gościem. Nie mogę tego zrobić z publicznymi klasami w javie;)

krosenvold
źródło
2

Z reguły jedna klasa / jeden plik to droga do zrobienia. Jednak często trzymam kilka definicji interfejsów w jednym pliku. Kilka klas w jednym pliku? Tylko jeśli są w jakiś sposób bardzo blisko spokrewnione i bardzo małe (<5 metod i elementów)

Treb
źródło
2

Jak jest prawdą przez większość czasu w programowaniu, zależy to w dużej mierze od sytuacji.

Na przykład, jaka jest spójność omawianych klas? Czy są ściśle powiązane? Czy są całkowicie ortogonalne? Czy są powiązane funkcjonalnością?

Dostarczanie widgetów ogólnego przeznaczenia przez platformę sieciową nie byłoby poza kolejnością. Niezależnie od pliku zawierającego BaseWidget, TextWidget, CharWidget itp.

Użytkownik frameworku nie wypadłby z drogi w definiowaniu pliku more_widgets zawierającego dodatkowe widgety, które pochodzą z widgetów struktury dla określonej przestrzeni domeny.

Gdy klasy są ortogonalne i nie mają ze sobą nic wspólnego, grupowanie w jeden plik byłoby rzeczywiście sztuczne. Załóżmy, że aplikacja zarządza fabryką robotów, która buduje samochody. Plik zwany częściami zawierający CarParts i RobotParts byłby bezsensowny… nie ma prawdopodobnie związku między zamawianiem części zamiennych do konserwacji a częściami produkowanymi przez fabrykę. Takie połączenie nie dodałoby żadnych informacji ani wiedzy o projektowanym systemie.

Być może najlepszą praktyczną zasadą jest nie ograniczać swoich wyborów regułą praktyczną. Praktyczne zasady są tworzone dla pierwszej analizy lub w celu ograniczenia wyborów tych, którzy nie są w stanie dokonywać dobrych wyborów. Myślę, że większość programistów chciałaby wierzyć, że są w stanie podejmować dobre decyzje.

Wayne Werner
źródło
2

Powinieneś powstrzymać się od tego, chyba że masz dobry powód.

Jeden plik z kilkoma małymi pokrewnymi klasami może być bardziej czytelny niż kilka plików. Na przykład podczas używania „klas przypadków” do symulacji typów związków istnieje silny związek między każdą klasą. Użycie tego samego pliku dla wielu klas ma tę zaletę, że czytelnik może wizualnie je zgrupować.

W twoim przypadku samochód i drzwi nie wydają się w ogóle powiązane, a znalezienie klasy drzwi w pliku car.cs byłoby nieoczekiwane, więc nie rób tego.

Eldritch Conundrum
źródło
1

Jedna klasa na plik jest prostsza w utrzymaniu i znacznie bardziej przejrzysta dla każdego, kto patrzy na Twój kod. W niektórych językach jest to również obowiązkowe lub bardzo ograniczone.

Na przykład w Javie nie można utworzyć wielu klas najwyższego poziomu w jednym pliku, muszą one znajdować się w oddzielnych plikach, w których nazwa klasy i nazwa pliku są takie same.

Rudzik
źródło
1

Odpowiedź Smalltalk brzmi: nie powinieneś mieć plików (do programowania). Sprawiają, że wersjonowanie i nawigacja są bolesne.

Stephan Eggermont
źródło