2009-05-18 12 views
41

Dlaczego OO oparte na klasach jest tak popularne, a nie oparte na prototypach OO? Czy uczą tych drugich w szkołach? Chociaż JavaScript jest oparty na prototypach, większość ludzi używa go głównie funkcjonalnie lub za pomocą frameworków, które próbują emulować system oparty na klasach.Jakie są zalety tego OO opartego na prototypach, które ma ponadnormatywne OO?

Wiem, że firma Sun przeprowadziła pewne badania na temat Self - czy istnieje inne źródło wiedzy na temat opartej na prototypach oo? najlepiej coś, co jest dostępne dla samouczenia się.

znalazłem książkę, która zawiera publikowane dokumenty: Prototype-Based Programming: Concepts, Languages and Applications

ktoś ją przeczytać?

-

Więc dałem nagrodę za odpowiedź, która dała mi najbardziej. Mimo to nie jestem usatysfakcjonowany. Chciałbym usłyszeć znacznie bardziej techniczne odpowiedzi. Może nie wyjaśniłem się dobrze.

+0

https://developer.mozilla.org/en/JavaScript/Guide/Details_of_the_Object_Model – pramodc84

+0

Debata robi nie kończysz tutaj? Podsumowuję interesujący artykuł. W skrócie, światopogląd oparty na klasach jest bardziej wadliwy niż ten z prototypów. Musimy więc być ostrożni.Oto podsumowanie: http://carnotaurus.tumblr.com/post/3248631891/class-based-javascript-or-not – CarneyCode

+0

Oparty na klasach OO historycznie pojawił się przed OO opartym na prototypach, a w rezultacie jest teraz używany w znakomita większość kodów na świecie. Zastąpienie koncepcji okazało się niepraktyczne, aż do pojawienia się Javascript. Oczekiwać, że szkoły będą uczyć oparte na prototypach OO proporcjonalnie do ilości kodu napisanego w stylu, na świecie. Niektóre z poniższych odpowiedzi łączą prototypowe OO z dynamicznym dziedziczeniem. – blueberryfields

Odpowiedz

23

Zaletą prototypowego dziedziczenia jest to, że potencjalnie pozwala na fantazyjne metaprogramowanie w prosty sposób, ponieważ łańcuch prototypów można łatwo manipulować. Jest to raczej korzyść naukowa, ponieważ metaprogramowanie jest błędną odpowiedzią w 99% przypadków. Przykładowo, możesz mieć warstwę manipulacji danymi w stylu JavaScript Observer-Style ze specjalnym DSL, który przeźroczyście przełączał między lokalnym podkładem SQLite podczas pracy w trybie offline, a magazynem opartym na REST, gdy jest on dostępny online poprzez prototypową zamianę. Nie jestem pewien, czy to najlepszy sposób na zrobienie tego, ale jest to najlepsze, co mogę wymyślić tak późno. Nie jest to coś, co zazwyczaj chcesz zrobić w kodzie projektu, ponieważ tego typu pośredniczenie jest piekielne do debugowania, gdy zaczynasz je uruchamiać na wielu warstwach, ale nie jest źle, gdy przechowujesz je w bibliotece.

Inną mniej przydatną zaletą jest to, że pozwala zaprojektować własny system klasy. Mówię mniej pomocny, ponieważ mniej więcej wszystkie biblioteki javascript mają swoje nieco niekompatybilne podejście do tego, jak "klasy" są zestawiane.

Wiele osób odpowiada, którzy mieszają model dziedziczenia z językami zaimplementowanymi w tym modelu. Fakt, że javascript jest dynamiczny i słabo napisany, a przez to trudny w użyciu, nie ma nic wspólnego z tym, że jest językiem prototypowym.

+0

Przy implementacji JavaScriptu nie można zmienić obiektu prototypu. Czy byłaby to tylko zmiana samego obiektu prototypowego z SQLite na REST? –

+0

Tak. Jeśli robiłeś wszystkie sztuczki za pomocą funkcji save(), zamień zapis SQLite() na REST save(): >>> rest_save = function() {return "REST"} >>> sql_save = function() {return "SQL"} >>> Storage = function() {/ * initialization etc * /} >>> Storage.prototype.save = rest_save >>> my_obj = new Storage() >>> my_obj.save() "spoczynku" >>> Storage.prototype.save = sql_save funkcja () >>> my_obj.save() "SQL" Można to łatwo zrobić za cały obiekt za pomocą funkcji update/merge dostępnej we wszystkich głównych bibliotekach js. Nie "prawda" zamiana, ale może być przydatna. –

+10

Nienawidzę braku nowych linii w tych komentarzach. –

12

Nie znam dokładnych przyczyn tego, ale tutaj są moje powody

myślę, że to argumentować jest taka sama jak Dynamiczny vs statyczna, klasa jest statyczna definicja obiektu, który może być używany Łatwo dowiedzieć się, czego się spodziewać po obiekcie, pomaga także narzędziom językowym mieć odpowiednie wsparcie i dokumentację dla intellisense, ponieważ można łatwo poznać, jakie są różne elementy i metody w obiekcie, innym jest inny paradygmat posiadania zdolności do zadeklaruj prywatnych członków w klasie, które nie pokazują się na obiekcie, nie można tego zrobić w prototypowym paradygmacie.

Prototypowy paradygmat jest fajny, jednak brakuje mu możliwości dostarczania informacji o metodach i elementach w obiekcie, co sprawia, że ​​oprzyrządowanie jest trudniejsze, a także ma więcej sensu w pisaniu dynamicznego pisania.

+2

zaraz. języki statyczne potrzebują klas, aby kompilatorzy wiedzieli, czego się spodziewać/zabronić. języki dynamiczne nie potrzebują ich, więc wygodniej jest używać prototypów. – Javier

+0

Uzgodnione. Należy jednak zauważyć, że chociaż JavaScript obsługuje dziedziczenie oparte na prototypach, nie jest trudno wdrożyć niektóre funkcje OO przy użyciu zamknięć. Na przykład można uzyskać realną ochronę prywatnych metod i zmiennych. Książka Dustin Diaz na ten temat jest na najwyższym poziomie: "Pro Javascript Design Patterns" (http://jsdesignpatterns.com/) Punkt ten oznacza, że ​​oprzyrządowanie dla takich dynamicznych języków jest trudne. Dzięki tak elastycznemu językowi jak Javascript trudno jest w środowisku programistycznym wiedzieć, jakich wzorów dziedziczenia używasz. –

+4

Nie zgadzam się z tym, że "oparty na prototypach brak możliwości dostarczania informacji o metodach i członkach obiektu". W przeciwieństwie do klasy, jest łatwo wyliczyć w czasie wykonywania. – Thevs

18

Jeśli szukasz kogoś, kto wskaże zalety i wady każdego z nich jako wyjaśnienie ich popularności, myślę, że popadłeś w błąd, który jest z jakiegoś powodu bardzo powszechny w technologii - ta popularność ma coś zrobić z pewną bezwzględną miarą jakości.

Prawda jest o wiele bardziej łagodna - oparta na klasach OO jest popularna, ponieważ Java używa klasycznego OO, a Sun wydał miliony dolarów i bardzo długo budował popularność Java - upewniając ludzi, że jest z powodzeniem stosowany w korporacjach, szeroko nauczane na uniwersytetach oraz w szkolnych testach AP.

Prototypowe/klasyczne OO to tylko różne sposoby organizacji pomysłów. Można go wdrożyć w językach, które nie obsługują go natywnie (przychodzą na myśl Python i Java, a po drugiej stronie - JavaScript).

W klasycznym OO, definiujesz abstrakcyjną hierarchię klas dla swoich obiektów, a następnie pracujesz z instancjami tych klas. W dziedziczeniu prototypowym tworzysz hierarchię instancji obiektów. Chociaż wyobrażam sobie, że może to być trochę heretyckie w obu obozach, nie widzę powodu, dla którego nie mógłbyś mieszać dwóch ...

+1

Jestem tylko ciekawy, czy istnieje coś, co sprawia, że ​​OO oparte na prototypach jest trudniejsze dla programistów. A przede wszystkim chciałbym się dowiedzieć, jakie problemy pojawią się w tworzeniu złożonego oprogramowania. Nie twierdzę, że popularność jest oparta na jakości paradygmatów, ale * może * wynikać z przyczyn. – egaga

+0

Zastanawiam się, co to jest klasyczny OO? Czy jest jak Smalltalk & CLOS (który jest podobny do protoptype), czy jest to Simula (która jest podobna do opartej na obiektach Java)? Który model jest klasyczny? – Thevs

+0

Przykro mi, klasycznie, miałem na myśli klasę. –

3

Myślę, że różnica tkwi w dynamicznym (prototypowym) języku . JavaScript, podobnie jak LISP, daje prawie nieograniczoną moc programistom. Ta moc jest ograniczona tylko przez odpowiedzialność programisty i poziom jego pewności siebie. Dyskusja jest tak stara, jak jest - tak samo jak pisanie statyczne vs.Jeśli uważasz, że twoja moc programowania i samodyscyplina są wystarczająco silne - wybierz prototypowy styl.

Parafrazując jedno słynne powiedzenie:

Talent robi to, co potrafi (czytaj: class-based), geniusz robi co chce (czytaj: prototyp na bazie).

+1

Ale czym jest ta moc, o której mówisz? Właśnie tego szukam. – egaga

+4

Moc strzelania do siebie w stopach. Pisanie statyczne (i podobne zajęcia) to próba ratowania programisty przed nim samym. Jest to język celowo utrudniający niebezpieczne rzeczy. Możesz robić niesamowite rzeczy po prostu za pomocą niestatycznego pisania i opartych na prototypach systemów obiektowych, ale możesz też robić naprawdę okropne rzeczy. – Orclev

+2

Jest to moc tworzenia wszelkich możliwych konstrukcji w swoich programach. Ograniczają go tylko twoje fantazje. Czasami fantazje mogą być dość chore :) – Thevs

10

To pytanie mnie zaintrygowało, więc wróciłem i przeczytałem kilka oryginalnych artykułów na ten temat. Wygląda na to, że zaczęło się w połowie lat 80. w świecie Smalltalk, ale ostatecznie stało się jednym z głównych założycieli Self. Dużo późniejszy JavaScript też to zaadaptował.

Argument przedstawiony w gazetach jest taki, że łatwiej się uczyć. Naprawdę nie ma żadnej korzyści technicznej proponowanej poza nauką. Wszystkie artykuły wyjaśniają, że jest tak samo ekspresyjny jak język oparty na klasach, ale o wiele łatwiejszy do nauczenia. Ludzie naturalnie myślą o rzeczach w sposób konkretny, a nie abstrakcyjny. Myślimy o słoniu, który widzieliśmy w zoo, a nie o generycznym "słoniu". Kiedy widzimy inne słonie, klasyfikujemy je jako różnice od pierwszego. Język oparty na prototypach ułatwia takie myślenie. Pomyśl o tym jako o programowaniu różnicowym.

Czy to wystarczający powód, aby używać go w języku? Być może. W ciągu 25 lat od pierwszego pomysłu perkolacji twierdzę, że abstrakcyjne pojęcia, takie jak OO oparte na klasach, nie były zbyt trudne dla większości ludzi. Z drugiej strony być może potrzebny jest język programowania (np. Javascript), który jest łatwiejszy i może to być sposób na osiągnięcie tego.

Jeśli jesteś zainteresowany, możesz zacząć od this paper o sobie.

+0

Miło zobaczyć to pytanie, ale zainteresowałem się! Dzięki :) – egaga