Nie możesz pisać dobrego kodu bez getterów.
Powodem tego nie jest to, że osoby pobierające nie przerywają enkapsulacji. Nie dzieje się tak dlatego, że osoby pobierające nie kuszą ludzi, aby nie zawracali sobie głowy obserwowaniem OOP, co pozwoliłoby im zastosować metody z danymi, na których działają. Oni robią. Nie, potrzebujesz getterów z powodu granic.
Pomysły enkapsulacji i utrzymywania metod wraz z danymi, na które działają, po prostu nie działają, gdy natrafisz na granicę, która powstrzymuje cię przed przeniesieniem metody i zmusza do przeniesienia danych.
To naprawdę takie proste. Jeśli użyjesz getterów, gdy nie ma granicy, w końcu nie będziesz mieć prawdziwych obiektów. Wszystko zaczyna mieć tendencję proceduralną. Który działa tak dobrze, jak kiedykolwiek.
True OOP nie jest czymś, co można rozpowszechniać wszędzie. Działa tylko w tych granicach.
Te granice nie są cienkie jak brzytwa. Mają w sobie kod. Ten kod nie może być OOP. To też nie może być funkcjonalne. Żaden kod nie pozbawił naszych ideałów, aby poradzić sobie z trudną rzeczywistością.
Michael Fetters nazwał ten kod powięź po tej białej tkance łącznej, która utrzymuje razem fragmenty pomarańczy.
To wspaniały sposób na przemyślenie tego. Wyjaśnia, dlaczego dobrze jest mieć oba rodzaje kodu w tej samej bazie kodu. Bez tej perspektywy wielu nowych programistów mocno trzyma się swoich ideałów, a następnie łamie im serca i rezygnuje z tych ideałów, gdy osiągną swoją pierwszą granicę.
Ideały działają tylko na swoim miejscu. Nie poddawaj się tylko dlatego, że nie wszędzie działają. Używaj ich tam, gdzie pracują. To miejsce jest soczystą częścią, którą chroni powięź.
Prostym przykładem granicy jest kolekcja. To coś trzyma i nie ma pojęcia, co to jest. Jak projektant kolekcji mógłby przenieść funkcjonalność behawioralną trzymanego obiektu do kolekcji, skoro nie ma pojęcia, co on będzie trzymał? Nie możesz Jesteś na granicy. Dlatego kolekcje mają gettery.
Teraz, jeśli wiesz, możesz zmienić to zachowanie i uniknąć zmiany stanu. Kiedy wiesz, powinieneś. Po prostu nie zawsze wiesz.
Niektórzy nazywają to po prostu pragmatycznym. I to jest. Ale miło wiedzieć, dlaczego musimy być pragmatyczni.
Wyraziłeś, że nie chcesz słyszeć argumentów semantycznych i wydaje się, że opowiadasz się za umieszczaniem wszędzie „rozsądnych pobudzających”. Pytasz o zakwestionowanie tego pomysłu. Myślę, że mogę pokazać, że pomysł ma problemy ze sposobem, w jaki go sformułowałeś. Ale wydaje mi się również, że wiem, skąd pochodzisz, ponieważ byłem tam.
Jeśli chcesz, aby użytkownicy pobierali wszędzie, spójrz na Python. Nie ma prywatnego słowa kluczowego. Jednak Python dobrze sobie radzi z OOP. W jaki sposób? Używają sztuczki semantycznej. Wymieniają wszystko, co ma być prywatne, z wiodącym podkreśleniem. Możesz nawet z niego czytać, pod warunkiem że bierzesz za to odpowiedzialność. „Wszyscy tu jesteśmy dorośli”, często mówią.
Jaka jest różnica między tym a umieszczaniem programów pobierających wszystko na Java lub C #? Przepraszam, ale to semantyka. Konwencja podkreślania w Pythonie wyraźnie sygnalizuje, że grzebiesz za drzwiami tylko dla pracowników. Uderz we wszystko, a stracisz ten sygnał. Dzięki refleksji mogłeś i tak usunąć prywatność i nadal nie stracić sygnału semantycznego. Po prostu nie ma tu argumentu strukturalnego.
Pozostaje nam więc zadecydować, gdzie zawiesić znak „tylko dla pracowników”. Co należy uznać za prywatne? Nazywacie to „rozsądnymi pobieraczami”. Jak powiedziałem, najlepszym uzasadnieniem dla getterów jest granica, która zmusza nas do oddalenia się od naszych ideałów. Nie powinno to skutkować uzyskaniem wszystkiego. Kiedy to spowoduje getter, powinieneś rozważyć przeniesienie zachowania dalej do soczystego kawałka, gdzie możesz je chronić.
Ten rozdział doprowadził do kilku warunków. Obiekt transferu danych lub DTO nie zachowuje się. Jedynymi metodami są pobierające, a czasem ustawiające, czasem konstruktor. Ta nazwa jest niefortunna, ponieważ wcale nie jest prawdziwym przedmiotem. Programy pobierające i ustawiające są tak naprawdę tylko kodem debugującym, który daje miejsce do ustawienia punktu przerwania. Gdyby nie ta potrzeba, byliby tylko stosem publicznych pól. W C ++ nazywaliśmy je strukturami. Jedyną różnicą, jaką mieli od klasy C ++, było to, że domyślnie nie ustawili na public.
DTO są fajne, ponieważ można je przerzucić przez ścianę graniczną i bezpiecznie przechowywać inne metody w ładnym, soczystym obiekcie zachowania. Prawdziwy przedmiot. Bez narzędzi pobudzających do naruszenia jest hermetyzacja. Moje obiekty zachowania mogą jeść DTO, używając ich jako obiektów parametrów . Czasami muszę wykonać jego obronną kopię , aby zapobiec wspólnemu, zmiennemu stanowi . Nie rozprowadzam modyfikowalnych DTO wewnątrz soczystej części w obrębie granicy. Zamykam je. Chowam je. A kiedy w końcu wpadam na nową granicę, odkrywam nowe DTO i rzucam je na ścianę, sprawiając, że jest to problem kogoś innego.
Ale chcesz zapewnić użytkownikom, którzy wyrażają tożsamość. Gratulacje, znalazłeś granicę. Podmioty mają tożsamość, która wykracza poza ich odniesienie. Oznacza to, że poza ich adresem pamięci. Więc to musi być gdzieś przechowywane. I coś musi być w stanie odnosić się do tego poprzez swoją tożsamość. Getter, który wyraża tożsamość, jest całkowicie rozsądny. Stos kodu, który używa tego modułu pobierającego do podejmowania decyzji, które jednostka mogła sama podjąć, nie jest.
W końcu to nie istnienie pobierających jest błędne. Są znacznie lepsze niż pola publiczne. Złe jest to, że są one używane do udawania, że jesteś zorientowany obiektowo, kiedy nie jesteś. Getters są dobrzy. Bycie zorientowanym obiektowo jest dobre. Gettery nie są zorientowane obiektowo. Użyj narzędzi pobierających, aby wykroić bezpieczne miejsce, w którym będzie zorientowany obiektowo.