Nie , obiekt nie musi reprezentować bytu.
W rzeczywistości argumentowałbym, że kiedy przestajesz myśleć o przedmiotach jako o fizycznych bytach, to w końcu dostajesz korzyści, które obiecuje OOP.
To nie jest najlepszy przykład, ale projekt ekspresu do kawy jest prawdopodobnie miejscem, w którym zaczęło mi się świecić światło.
Obiekty dotyczą wiadomości. Chodzi o obowiązki. Nie dotyczą samochodów, użytkowników ani zamówień.
Wiem, że uczymy OO w ten sposób, ale po kilku próbach staje się oczywiste, jak frustrujące jest zastanawianie się, dokąd zmierzają rzeczy, gdy próbujesz robić MVC, MVVM lub MVW cokolwiek. Albo twoje modele staną się śmiesznie rozdęte, albo zrobią to twoje kontrolery. Jeśli chodzi o nawigację, dobrze jest wiedzieć, że wszystko, co dotyczy pojazdów, znajduje się w pliku Vehicle.ext, ale gdy twoja aplikacja dotyczy pojazdów, nieuchronnie kończy się na 3000 linii spaghetti w tym pliku.
Kiedy masz nową wiadomość do wysłania, masz co najmniej jeden nowy obiekt i być może ich parę. Więc w twoim pytaniu o pakiet metod argumentowałbym, że potencjalnie mówisz o pakiecie wiadomości. I każdy z nich może być swoim własnym przedmiotem, z własną pracą do wykonania. I to jest w porządku. Stanie się oczywiste, gdy rozdzielisz różne rzeczy, które naprawdę naprawdę muszą być razem. I złożyłeś je razem. Ale nie od razu umieszczasz każdą metodę w niejasnej szufladzie dla wygody, jeśli chcesz cieszyć się OO.
Porozmawiajmy o workach funkcji
Obiekt może być tylko zbiorem metod i nadal być OO, ale moje „reguły” są dość surowe.
Kolekcja powinna ponosić jedną odpowiedzialność, a odpowiedzialność ta nie może być tak ogólna, jak „Robi rzeczy dla silników”. Mogę zrobić coś takiego jak fasada warstwy usługowej, ale jestem świadomy, że jestem leniwy z powodów związanych z nawigacją / odkryciem, a nie dlatego, że próbuję napisać kod OO.
Wszystkie metody powinny mieć spójną warstwę abstrakcji. Jeśli jedna metoda pobiera obiekty Motorowe, a druga zwraca Moc, to prawdopodobnie jest to zbyt daleko od siebie.
Obiekt powinien działać na tym samym „rodzaju” danych. Ten obiekt robi rzeczy dla silników (start / stop), ten robi rzeczy z długością korby, ten obsługuje sekwencjonowanie zapłonu, ten ma postać HTML. Dane te mogą być polami na obiekcie i wydają się spójne.
Generalnie buduję tego typu obiekty, kiedy wykonuję transformacje, kompozycje lub po prostu nie chcę się martwić o zmienność.
Uważam, że skupienie się na odpowiedzialności za przedmiot prowadzi mnie do spójności. Aby być przedmiotem, musi istnieć pewna spójność, ale nie musi być żadnych pól ani bardzo dużego zachowania, aby mógł on być przedmiotem. Gdybym budował system, który potrzebowałby 5 metod motorycznych, zaczynałbym od 5 różnych obiektów, które robią te rzeczy. Gdy znalazłem podobieństwo, zacząłem łączyć rzeczy ze sobą lub używać wspólnych obiektów „pomocniczych”. To porusza mnie do otwartych / zamkniętych problemów - jak mogę wyodrębnić ten kawałek funkcjonalności, aby nigdy więcej nie musiałem modyfikować tego konkretnego pliku, ale nadal go używać w razie potrzeby?
Obiekty dotyczą wiadomości
Pola prawie nie mają znaczenia dla obiektu - pobieranie i ustawianie rejestrów nie zmienia świata poza programem. Współpraca z innymi obiektami kończy pracę. Jednak siłą OO jest to, że możemy tworzyć abstrakcje, abyśmy nie musieli myśleć o wszystkich pojedynczych szczegółach jednocześnie. Abstrakcje, które przeciekają lub nie mają sensu, są problematyczne, dlatego głęboko (prawdopodobnie za dużo) myślimy o tworzeniu obiektów pasujących do naszych modeli mentalnych.
Kluczowe pytanie: dlaczego te dwa obiekty muszą ze sobą rozmawiać?
Pomyśl o obiekcie jako o organie w człowieku - ma on domyślny cel i zmienia zachowanie tylko wtedy, gdy otrzyma określony komunikat, na którym mu zależy.
Wyobraź sobie scenariusz, w którym jesteś na przejściu dla pieszych i samochód jedzie szybko. Jako obiekt mózgu wykrywam stresor. Mówię podwzgórzowi, aby wysłał hormon uwalniający kortykotrofinę. Przysadka mózgowa otrzymuje tę wiadomość i uwalnia hormon kortykotroficzny nadnerczy. Nadnercza otrzymują tę wiadomość i wytwarzają adrenalinę. Kiedy obiekt mięśniowy otrzymuje ten komunikat adrenaliny, kurczy się. Kiedy serce otrzymuje tę samą wiadomość, bije szybciej. Cały łańcuch graczy jest zaangażowany w rozpoczęcie złożonego zachowania podczas sprintu po drugiej stronie ulicy i ważne są przesłania. Obiekt mózgu wie, jak doprowadzić podwzgórze do wysłania ostrzeżenia, ale nie zna łańcucha obiektów, które ostatecznie spowodują zachowanie. Podobnie serce nie ma pojęcia, skąd pochodzi adrenalina,
Zatem w tym ( uproszczonym ) przykładzie obiekt nadnerczy musi tylko wiedzieć, jak przyjmować ACTH i wytwarzać adrenalinę. Nie potrzebuje do tego żadnych pól, ale nadal wydaje mi się, że to jakiś przedmiot.
Teraz, jeśli nasza aplikacja jest przeznaczona tylko do sprintu po drugiej stronie ulicy, może nie potrzebuję przysadki mózgowej i obiektów nadnerczy. Albo potrzebuję tylko obiektu przysadki mózgowej, który wykonuje tylko niewielką część tego, co możemy koncepcyjnie postrzegać jako „model przysadki mózgowej”. Wszystkie te koncepcje istnieją jako byty koncepcyjne, ale jest to oprogramowanie i możemy zrobić AdrenalineSender lub MuscleContractor lub cokolwiek innego i nie martwić się zbytnio o „niekompletność” naszego modelu.