W ostatnich latach języki, których lubię używać, stają się coraz bardziej „funkcjonalne”. Teraz używam języków, które są rodzajem „hybrydowym”: C #, F #, Scala. Lubię projektować swoją aplikację przy użyciu klas, które odpowiadają obiektom domeny, i używam funkcji funkcjonalnych, dzięki którym kodowanie jest łatwiejsze, bardziej spójne i bezpieczniejsze (szczególnie podczas pracy na kolekcjach lub podczas przekazywania funkcji).
Jednak dwa światy „zderzają się”, jeśli chodzi o projektowanie wzorów. Konkretnym przykładem, z którym się ostatnio spotkałem, jest wzorzec Observer. Chcę, aby producent powiadomił inny kod („konsumenci / obserwatorzy”, powiedzmy pamięć DB, rejestrator itd.) O utworzeniu lub zmianie elementu.
Początkowo robiłem to „funkcjonalnie” w ten sposób:
producer.foo(item => { updateItemInDb(item); insertLog(item) })
// calls the function passed as argument as an item is processed
Ale teraz zastanawiam się, czy powinienem zastosować bardziej „OO”:
interface IItemObserver {
onNotify(Item)
}
class DBObserver : IItemObserver ...
class LogObserver: IItemObserver ...
producer.addObserver(new DBObserver)
producer.addObserver(new LogObserver)
producer.foo() //calls observer in a loop
Jakie są zalety i wady obu podejść? Kiedyś usłyszałem, jak guru FP powiedział, że wzorce projektowe istnieją tylko z powodu ograniczeń języka i dlatego tak mało jest języków funkcjonalnych. Może to może być tego przykład?
EDYCJA: W moim konkretnym scenariuszu nie jest mi potrzebny, ale ... jak wprowadziłbyś usuwanie i dodawanie „obserwatorów” w sposób funkcjonalny? (Tj. Jak zaimplementowałbyś wszystkie funkcje we wzorcu?) Na przykład przekazując nową funkcję?