Kilka miesięcy temu przeczytałem Czysty kod wuja Boba , który miał ogromny wpływ na sposób, w jaki piszę kod. Nawet jeśli wydawało się, że powtarza rzeczy, które każdy programista powinien wiedzieć, zebranie ich wszystkich razem i wdrożenie ich w praktyce skutkuje znacznie czystszym kodem. W szczególności odkryłem, że dzielenie dużych funkcji na wiele drobnych funkcji i dzielenie dużych klas na wiele małych klas jest niezwykle przydatne.
Teraz pytanie. Wszystkie przykłady tej książki są w Javie, podczas gdy ja pracuję w C ++ od kilku lat. W jaki sposób pomysły w Czystym Kodzie obejmowałyby stosowanie przestrzeni nazw, które nie istnieją w Javie? (Tak, wiem o pakietach Java, ale tak naprawdę to nie to samo.)
Czy ma sens zastosowanie idei tworzenia wielu małych bytów, z których każdy ma jasno określoną odpowiedzialność, do przestrzeni nazw? Czy mała grupa pokrewnych klas powinna być zawsze zawinięta w przestrzeń nazw? Czy jest to sposób na zarządzanie złożonością posiadania wielu małych klas, czy też koszt zarządzania wieloma przestrzeniami nazw byłby zbyt wysoki?
Edycja: Odpowiedzi na moje pytanie w tym wpisie w Wikipedii na temat zasad pakietów .
Odpowiedzi:
(Nie przeczytałem Czystego Kodu i nie znam dużo Javy).
Tak, podobnie jak w przypadku refaktoryzacji na wiele klas i wiele funkcji.
Bez odpowiedzi: tak, powinieneś użyć przynajmniej jednej przestrzeni nazw najwyższego poziomu. Może to być oparte na projekcie, organizacji lub czymkolwiek innym, ale użycie kilku nazw globalnych ograniczy konflikty nazw. Pojedyncza przestrzeń nazw do grupowania wszystkich pozostałych elementów wprowadza tylko jedną nazwę globalną. (Z wyjątkiem zewnętrznych funkcji „C”, ale wynika to z interoperacyjności C i wpływa tylko na inne zewnętrzne funkcje „C”.)
Czy mała grupa powiązanych klas powinna być zapakowana w dedykowaną im przestrzeń nazw ? Prawdopodobnie. Zwłaszcza jeśli używasz wspólnego przedrostka w tych klasach - FrobberThing, FrobberThang, FrobberDoohickey - powinieneś rozważyć przestrzeń nazw - frobber :: Thing i tak dalej. To nadal znajdowałoby się w głównej przestrzeni nazw lub w innej przestrzeni nazw, jeśli są one częścią większego projektu.
Biorąc powyższy przykład prefiksowanych nazw, zarządzanie frobber :: Thing nie jest trudniejsze niż FrobberThing. Może być nawet łatwiej z niektórymi narzędziami, takimi jak dokumentacja i uzupełnianie kodu. Istnieje różnica w ADL, ale może to działać na twoją korzyść: mniej nazw w powiązanych przestrzeniach nazw ułatwia ADL, aby łatwiej je rozgryźć, i możesz użyć deklaracji, aby wstrzyknąć określone nazwy do jednej lub innej przestrzeni nazw.
Aliasy przestrzeni nazw pozwalają na użycie krótszej nazwy dla dłuższej przestrzeni nazw w określonym kontekście, co ponownie pozwala na łatwiejsze użycie:
Rozważ Boost, który ma jedną główną przestrzeń nazw, boost, a następnie wiele podprzestrzeni - boost :: asio, boost :: io, boost :: system plików, boost :: krotki itp. - dla różnych bibliotek. Niektóre nazwy są „promowane” do głównej przestrzeni nazw:
Największą różnicą w stosunku do języków z „prawdziwymi” modułami jest to, jak często stosuje się bardziej płaską strukturę, co dzieje się głównie dlatego, że tak to działa, chyba że podejmiesz dodatkowy, konkretny wysiłek, aby zdefiniować zagnieżdżone nazwy.
źródło
Powinieneś mieć jedną główną przestrzeń nazw dla całego swojego kodu. To odróżnia go od kodu zewnętrznego w odniesieniu do przestrzeni nazw.
W obrębie głównej przestrzeni nazw, w zależności od wielkości i złożoności, można otwierać podprzestrzenie nazw. To tutaj nazwy wyraźnie oznaczają coś w kontekście, a te same nazwy mogą być użyte w innym kontekście.
W szczególności, jeśli masz ogólną nazwę brzmiącą jak FileInfo, która oznacza coś konkretnego w kontekście, umieść ją w przestrzeni nazw.
Możesz także użyć do tego klasy, chociaż nie można jej rozszerzyć, więc nie możesz dodawać do niej nowych deklaracji bez modyfikacji jej nagłówka.
źródło
Przestrzenie nazw nie są koncepcją modułu, więc używałbym ich tylko tam, gdzie mogłyby wystąpić konflikty nazw.
źródło
Java ma przestrzenie nazw, tak naprawdę tak się nie nazywają. In
javax.swing.*
javax
jest przestrzenią nazw iswing
jest podprzestrzenią nazw. Nie czytałem książki, aby wiedzieć, co mówi o pakietach Java, ale te same zasady miałyby zastosowanie prawie bezpośrednio do przestrzeni nazw w dowolnym języku.Dobra heurystyka polega na tym, że używasz przestrzeni nazw, gdy chcesz ciągle powtarzać ten sam prefiks dla klas. Na przykład ostatnio napisałem kilka klas o nazwach OmciAttribute, OmciAlarm, OmciMe itp. I zdałem sobie sprawę, że muszę rozbić Omci na własną przestrzeń nazw.
źródło
Lubię głębokie przestrzenie nazw (co zwykle oznacza trzy poziomy).
W zależności od sytuacji mogę mieć jeszcze jeden poziom
źródło