Przykładowy kod wyjaśniający problem Banana Monkey Jungle autorstwa Joe Armstronga [zamknięty]

14

W książce Coders at work Joe Armstrong stwierdził, że:

Myślę, że brak możliwości ponownego użycia występuje w językach obiektowych, a nie w językach funkcjonalnych. Ponieważ problem z językami obiektowymi polega na tym, że mają one całe to ukryte środowisko, które ze sobą niosą. Chciałeś banana, ale dostałeś goryla trzymającego banana i całą dżunglę

Nie do końca to rozumiem. Jeśli problemem jest zdobycie banana, możemy zawrzeć całą logikę funkcji „getBanana”. Jak zaangażowane są małpy i dżungla w tym kontekście. Czy ktoś mógłby napisać fragment kodu wyjaśniający problem w łatwiejszy do zrozumienia sposób, powiedzmy, wykazujący fakt, że Bananaobiekt wymaga zainicjowania obiektów Monkeyi Jungle?

Kha Nguyễn
źródło
zobacz Omów to $ {blog}
gnat
Szkoda, że ​​to zostało zamknięte - przyniosło dobre rozmowy. Spójrz na funkcje pierwszej klasy jako starter.
Robbie Dee,
1
@Euforyczne pytania typu dyskusyjnego są w rzeczywistości dozwolone, ale które pytania są subiektywne, mogą być ... subiektywne.
Robbie Dee,
2
Wierzę, że wywiad ten odbył się, zanim Joe Armstrong napisał swoją pracę doktorską. Pisząc pracę doktorską, Armstrong dowiedział się o prawdziwej definicji OO, i zrozumiał, że Erlang jest rzeczywiście dokładnie zorientowany obiektowo, w rzeczywistości wszystkich obecnych językach nurtu, Erlang jest prawdopodobnie najbardziej obiektowy język! Nie wypowiedziałby tego w ten sposób, gdyby wiedział, że Erlang to w rzeczywistości język OO. Mówi o autorytecie otoczenia , który absolutnie nie ma nic wspólnego z OO.
Jörg W Mittag
1
Cześć, moje pytanie dotyczy podania przykładowego kodu, który pomoże mi (i innym) lepiej zrozumieć problem. Każdy fragment kodu wskazujący na problem jest akceptowalny, nie tylko opinia.
Kha Nguyễn

Odpowiedzi:

16

Wskazuje na fakt, że większość prawdziwych programów OOP nie szanuje podziału problemów. Na przykład możesz mieć klasy:

public class Banana
{
    public Monkey Owner {get;}
}

public class Monkey
{
    public Jungle Habitat {get;}
}

public class Jungle
{
}

Jeśli używasz Banana, tranzytowo konieczne jest również poleganie na Monkeyi Jungle.

Ale zdecydowanie nie zgadzam się, że jest to problem z OOP i że styl funkcjonalny jakoś go nie ma. Można to łatwo naprawić w OOP dzięki wprowadzeniu odpowiedniej abstrakcji.

Problem polega bardziej na tym, że programiści nie dbają o rozdzielenie problemów. I nie bałbym się stwierdzić, że większość programistów OOP to nowicjusze, podczas gdy programiści funkcjonalni mają pewne doświadczenie, które motywuje ich do właściwego rozdzielenia kodu.

Możliwą abstrakcją może być:

public class Banana
{
    public IBananaOwner Owner {get;}
}

public interface IBananaOwner
{
}

public class Monkey : IBananaOwner
{
    public Jungle Habitat {get;}
}

public class Jungle
{
}

W ten sposób wiesz, że Bananama właściciela, ale nie musi tak być Monkey. To może być wszystko. I ogranicza to, co może Bananazrobić z właścicielem, tylko do operacji zdefiniowanych przez IBananaOwner, co upraszcza rozumowanie.

Euforyk
źródło
I odwrotnie, podczas gdy języki funkcjonalne obsługują funkcje pierwszej klasy po wyjęciu z pudełka - to nie znaczy, że funkcja X może być bezpiecznie wykorzystana przez funkcję Y bez skutków ubocznych.
Robbie Dee,
Chociaż robisz świetny punkt, myślę, że możesz nieco schodzić z trasy. Cytat wyraźnie wspomina środowisko, a nie sposób zaprojektowania kodu.
Robbie Dee,
@RobbieDee The Monkeyi Junglesą środowiskiem dla Banana. Dzięki wprowadzeniu abstrakcji IBananaOwnerśrodowisko staje się wyraźne. I w jaki sposób zaprojektowano to środowisko, na tym polega jego problem.
Euforyczny
Być może masz rację, ale nie mogę przestać myśleć, że po przeczytaniu tego między innymi, że słoń w pokoju (aby dodać kolejne zwierzę), ma problem z prawidłowym zestawieniem funkcji, które programowanie funkcjonalne, historycznie, ma użyczył się więcej.
Robbie Dee,
@RobbieDee Nie możesz zastąpić tego, co napisałem prostą kompozycją funkcji. Przynajmniej nie przykładowe problemy z zabawkami. W praktyce, aby w pełni zastąpić projekt OOP, konieczne są rzeczy takie jak złożone generyczne, klasy typów, monady i inne. A to tylko zmienia jeden rodzaj złożoności na inny.
Euforyczny
13

Goryle to nie małpy!

Pozostawiając to na boku, odpowiadasz na swoje własne pytanie „ możemy zawrzeć całą logikę stojącą za funkcją„ getBanana ” ”. Wszystko czego chcę to banan, ale aby go zdobyć, muszę wywołać getBananajakiś obiekt, np. Instancję Gorillaklasy. Ten obiekt bananowy prawdopodobnie zawiera odniesienie do goryla, do którego należy, a ten obiekt goryla będzie z kolei miał odniesienie do lasu, do którego należy. Proszę więc o banana, ale za tym kryje się cała dżungla.

To ekstremalny przykład i nie zawsze będzie taki zły. Ale nierzadko kończy się na takim systemie OO. Aby przetestować tę getBananametodę, muszę utworzyć instancję lub wyśmiewać cały las.

David Arno
źródło
1
To nie odpowiada na pytanie, ponieważ nie ma przykładowego kodu ...
Robbie Dee