OK, więc tytuł to trochę clickbaity, ale tak na serio, jestem na dobrej drodze , nie proś przez chwilę kick. Podoba mi się, jak zachęca metody do używania jako wiadomości w sposób zorientowany obiektowo. Ale to ma dokuczliwy problem, który grzechotał mi w głowie.
Zacząłem podejrzewać, że dobrze napisany kod może jednocześnie przestrzegać zasad OO i zasad funkcjonalnych. Staram się pogodzić te pomysły z wielkim punktem spornym, na którym wylądowałem return
.
Funkcja czysta ma dwie cechy:
Wielokrotne wywoływanie tego samego wejścia zawsze daje ten sam rezultat. Oznacza to, że jest niezmienny. Jego stan jest ustawiany tylko raz.
Nie powoduje żadnych skutków ubocznych. Jedyną zmianą wywołaną przez wywołanie tego jest wynik.
Jak więc przejść na temat bycia czysto funkcjonalnym, jeśli przysiągłeś, że używasz return
swojego sposobu komunikowania wyników?
Tell, nie pytaj prace pomysł za pomocą tego, co niektórzy uważają efekt uboczny. Kiedy mam do czynienia z przedmiotem, nie pytam go o jego stan wewnętrzny. Mówię mu, co muszę zrobić, i wykorzystuje swój stan wewnętrzny, aby dowiedzieć się, co zrobić z tym, co powiedziałem. Kiedy to powiem, nie pytam, co to zrobiło. Po prostu oczekuję, że coś to zrobiło z tym, co mu kazano.
Myślę, że Tell, Don't Ask to coś więcej niż inna nazwa enkapsulacji. Kiedy używam, return
nie mam pojęcia, co mnie wezwało. Nie mogę mówić, że to protokół, muszę go zmusić, by zajął się moim protokołem. Co w wielu przypadkach wyraża się jako stan wewnętrzny. Nawet jeśli to, co jest widoczne, nie jest dokładnie stanem, zwykle jest to tylko kilka obliczeń przeprowadzonych na argumencie stanu i wejściowym. Posiadanie interfejsu umożliwiającego reakcję daje szansę na zamaskowanie wyników w coś bardziej znaczącego niż stan wewnętrzny lub obliczenia. To jest przekazywanie wiadomości . Zobacz ten przykład .
Dawno temu, kiedy dyski faktycznie miały dyski, a napędem kciuka było to, co robiłeś w samochodzie, gdy koło było zbyt zimne, aby dotykać palcami, dowiedziałem się, jak denerwujące osoby uważają funkcje, które mają parametry. void swap(int *first, int *second)
wydawało się to bardzo przydatne, ale zachęcano nas do pisania funkcji, które zwracały wyniki. Wziąłem to sobie do serca z wiarą i zacząłem za tym podążać.
Ale teraz widzę ludzi budujących architektury, w których obiekty pozwalają, w jaki sposób zostały zbudowane, kontrolować, gdzie wysyłają swoje wyniki. Oto przykładowa implementacja . Wstrzyknięcie obiektu portu wyjściowego ponownie przypomina trochę pomysł parametru out. Ale w ten sposób obiekty „nie mów” pytają inne obiekty o tym, co zrobiły.
Kiedy po raz pierwszy dowiedziałem się o skutkach ubocznych, pomyślałem o tym jak o parametrze wyjściowym. Powiedziano nam, aby nie zaskakiwać ludzi tym, że niektóre prace odbywają się w zaskakujący sposób, to znaczy nie przestrzegając return result
konwencji. Teraz jestem pewien, że wiem, że jest stos równoległych problemów z asynchronicznym wątkiem, z którymi psują się skutki uboczne, ale powrót jest tak naprawdę tylko konwencją, w której pozostawiasz wynik wypchnięty na stos, więc niezależnie od tego, jak go nazwiesz, możesz go później usunąć. To wszystko, czym tak naprawdę jest.
O co tak naprawdę staram się zapytać:
Czy jest return
to jedyny sposób, aby uniknąć tych wszystkich niedoli związanych z efektami ubocznymi i uzyskać bezpieczeństwo nici bez zamków itp. Czy też mogę powiedzieć, nie pytać w czysto funkcjonalny sposób?