Często widziałem, że programowanie obiektowe opiera się na modelowaniu świata rzeczywistego, ale czy tak?
Wydaje mi się, że nie dotyczy to niczego poza warstwą biznesową. Moje klasy GUI / klasy dostępu do danych nie modelują niczego w prawdziwym świecie. Nawet w mojej warstwie biznesowej mam klasy takie jak obserwatorzy, menedżerowie, fabryki itp., Które nie są obiektami z prawdziwego świata. Staram się zaprojektować moje klasy, aby wykorzystywały takie rzeczy jak enkapsulacja, ale czy realny świat jest enkapsulowany?
Podczas gdy niektóre obiekty, które tworzę, modelują obiekty świata rzeczywistego, czy kod sprzed OOP nie zrobiłby tego samego? Wątpię, aby OO jako pierwsi umieścił w swoich bazach kodu takie jak Klient. Ale OO naprawdę polega na modelowaniu rzeczy, a ta metoda modelowania nie wydaje mi się inspirowana prawdziwym światem.
Więc: czy programowanie obiektowe naprawdę modeluje rzeczywisty świat?
źródło
modeling the real world
może nie być tym, co naprawdę wyróżnia OO. Może. Ale zdecydowanie nie wierzę, że nie uda ci się to zrobić w OO. Jak myślisz, który paradygmat lub technika jest lepsza niż OO?Odpowiedzi:
Nie, wcale nie.
Jest to jednak metodologia, która pozwala stworzyć ładną abstrakcję do przechowywania złożonych struktur danych wraz z niektórymi metodami, które działają na struktury danych.
źródło
Modele jakiegokolwiek rodzaju nie modelują realnego świata, nie do końca.
Modelują wybrane części, które są odpowiednie dla danej aplikacji.
To, o czym mówisz (obserwatorzy, menedżerowie, fabryki itp.), To infrastruktura, która pomaga w uzyskaniu prawidłowej abstrakcji i wspiera wymagane funkcje, takie jak wytrwałość.
źródło
Czym w każdym razie jest model:
Model jest uproszczoną reprezentacją służącą do wyjaśnienia działania systemu lub zdarzenia w świecie rzeczywistym
Zdecydowanie tak
Jest prawie niemożliwe, aby modelować system dokładnie dopasowany do rzeczywistego świata.
NIE
Powiedzenie, że możesz modelować wszystko, nie oznacza, że musisz modelować wszystko. W rzeczywistości istotą użytecznego modelowania jest przedstawienie uproszczonej reprezentacji. O ile uproszczenie jest wystarczające, aby wyrazić obecną potrzebę biznesową, a co należy pominąć, to dobra równowaga między udanym użyciem techniki a zagubieniem się lub jej całkowitym brakiem.
Istnieją oczywiście byty, które tak naprawdę nie istnieją, ale tylko dzięki modelowaniu możemy właściwie dobrze konceptualizować.
źródło
Myślę, że nauczanie, że istnieje związek między rzeczownikami a klasami, powoduje irytujące złe nawyki, które muszą zostać zmiażdżone przez niecierpliwego architekta lub starszego inżyniera.
Należy uczyć, że klasy modelują obiekty abstrakcyjne, tak jak robi to mózg. Masz w głowie abstrakcyjną koncepcję „samochodu”, która nie odwzorowuje żadnego konkretnego samochodu fizycznego, jest wielokrotnego użytku, konkretne implementacje samochodu mogą z niego odziedziczyć. Twój mózg nawet dla ciebie meta-modeli. Masz mentalny model tego, czym jest myśl, czym jest pojęcie.
Gdybyśmy nauczyli ludzi rozpoznawać modele, które już generują w twojej głowie, byliby znacznie lepiej przygotowani do tworzenia prawdziwego oprogramowania.
źródło
źródło cytatu: Victoria Livschitz, The Next Move in Programming
źródło
this.MoveTo(Environment.Find<Bathroom>().OrderBy(b=>b.Distance(this)).First()); this.SitOn(Environment.Find<Toilet>().Where(t=>!t.IsOccupied).OrderBy(t=>t.Distance(this)).First().Component<Seat>()); this.DiscardWaste(HumanWasteType.All);
Tak, OO może być często używane do modelowania rzeczywistych bytów.
Nie należy mylić rozwoju obiektowego z wzorami projektowymi. Analiza i projektowanie OO jest sposobem na podejście do programowania kodu, który można utrzymać. W połączeniu z językiem OO programiści mają możliwość tworzenia kodu wielokrotnego użytku poprzez filary OO: enkapsulacji, polimorfizmu i dziedziczenia.
Aby obudować byt, możemy modelować go na podstawie jego odpowiednika w świecie rzeczywistym. Na przykład, jeśli mamy gitarę, wtedy klasa gitary podsumowuje zachowania i właściwości gitary z prawdziwego świata. Możemy dalej wyodrębnić gitarę, powiedzmy,
IInventoryItem
aby wykorzystać potencjał ponownego wykorzystania kodu poprzez polimorfizm i dziedziczenie.Z drugiej strony może się okazać, że fabryka gitar może nam pomóc w utrzymaniu zestawu różnych rodzajów gitar. To nie jest spowodowane OO. Zamiast tego fabryka jest wzorcem projektowym, który przetrwał próbę czasu jako sprawdzony sposób skutecznego tworzenia łatwego do utrzymania kodu do takiego celu. Innymi słowy, my programiści często rozwiązujemy podobne problemy. Więc wymyśliliśmy wspólne rozwiązanie ich rozwiązywania (nie wymyślaj ponownie koła).
Nie oznacza to, że OO musi modelować rzeczywisty świat, ani że zawsze jest to najbardziej optymalne rozwiązanie. Po prostu, że zasada „OO modeluje świat rzeczywisty” ma sens.
źródło
To zależy od tego, o którym prawdziwym świecie mówisz.
Jorge Luis Borges napisał historię „Tlön, Uqbar, Orbis Tertius”, w której jeden z mieszkańców wydaje się postrzegać swój rzeczywisty świat zupełnie inaczej:
Dla mnie nie chodzi o to, że świat może być postrzegany inaczej niż my, co jest raczej stereotypem, ale to postrzeganie struktury samej rzeczywistości zależy od języka, którym mówimy, czy to języka naturalnego, czy programowania. Tlönese może być bardzo zadowolony z Lisp i może postrzegać Javę (AKA The Kingdom Of Nouns ) jako bardzo nienaturalną, podczas gdy większość programistów terrańskich woli faworyzować obiekty zorientowane na języki funkcjonalne. Lubię oba style, ponieważ myślę, że to głównie kwestia perspektywy. Niektóre problemy najlepiej atakować za pomocą funkcjonalnego, inne za pomocą technik programowania obiektowego. Dobry programista zawsze patrzy na trudny problem z różnych punktów widzenia, zanim spróbuje rozwiązania. Lub, jak ujął to Alan Kay: punkt widzenia jest wart 80 punktów IQ .
Więc moja odpowiedź na twoje pytanie brzmi: o jakim prawdziwym świecie mówisz? I jak?
źródło
Powiedziałbym, że nie. OOP wiąże relację między rzeczami (właściwościami / obiektami) a tym, co mogą zrobić / może być im zrobione (metody), podczas gdy programowanie proceduralne tego nie robi (poza, w niewielkim stopniu, przy użyciu ścisłego pisania). Model nie polega tylko na definiowaniu dyskretnych części i procesów, ale także na określaniu, jak pasują do siebie, a OOP jest w tym szczególnie dobry.
źródło
Tak. Nacisk tutaj opiera się na . OOP nie modeluje prawdziwego świata (jeśli tak, to nawiasem mówiąc) i nie powinno. To, co robi OOP, pozwala nam modelować problemy programistyczne w sposób, w jaki modelujemy świat rzeczywisty: jako system bytów, które są zdefiniowane poprzez naszą abstrakcję ich zachowania.
źródło
Kod OO zwykle nie modeluje świata rzeczywistego - przynajmniej nie jest to celem, pozwala po prostu myśleć o kodzie w sposób bardziej naturalny, bardziej podobny do sposobu myślenia o rzeczach w świecie rzeczywistym - oto, co próbuje powiedzieć cytat.
źródło
Nie modeluje naszego świata, ale modeluje ludzką interpretację naszego świata. Ludzie naturalnie oddzielają rzeczy jako przedmioty. OO jest skuteczne, ponieważ pozwala ludziom zaprogramować sposób, w jaki myślą.
źródło
OOP może nie być idealnym modelem realnego świata i zawartych w nim obiektów, ale jest to metodologia, która pomaga radzić sobie z rosnącą złożonością prawdziwego oprogramowania. Pomaga także lepiej pisać kod, dzieląc go na logicznie powiązane części.
Podczas gdy starsze metody zorientowane na procedury również z pewnością przyniosą rezultaty, OOP pomaga dotrzeć tam szybciej i ze względną łatwością, nawet w przypadku dużych i złożonych projektów.
Abstrakcja i enkapsulacja pomagają skoncentrować się na rdzeniu problemu, ukrywając całą instalację wodociągową, która faktycznie sprawia, że coś się dzieje. Dziedziczenie i pozwala ustanowić znaczącą i logiczną relację między różnymi aspektami kodu. Polimorfizm promuje ponowne wykorzystanie kodu i pozwala łatwo obsługiwać wariacje (te „ prawie sam zachowanie jako istniejącego obiektu” kategorii problemów, które zdarza się tak często) i rozszerzenie kodu poprzez rozszerzenie semantyki związane z obiektem.
Uważam, że OOP jest bardziej jak sprawdzona pomoc, która pozwala skutecznie radzić sobie ze wszystkimi złożonościami prawdziwego systemu życia. Tak więc, chociaż może nie być to bardzo dokładny model realnego świata, jest wystarczająco blisko i pomaga ci załatwić sprawy, co w końcu liczy się przede wszystkim IMHO.
źródło
Nie. Jak zauważyłeś, wiele rzeczy „modelowanych” w języku OOP to abstrakcyjne pojęcia, takie jak kolejki komunikatów, kontrolery i stosy.
Nawet w warstwie biznesowej nadal nie modelujesz „prawdziwego świata”. Załóżmy, że masz klasę pracowników. Pracownicy to także Ludzie, którzy są również Ssakami, którzy są również Zwierzętami, którzy także… (ziewają) Pracownicy mają ulubione kolory, noszą określone ubrania i wierzą w pewne rzeczy. Krótko mówiąc, w świecie rzeczywistym istnieje ogromna złożoność, której nawet nie próbujemy uchwycić w większości programów.
W modelowaniu skupiamy się tylko na tych aspektach modelu, które mają znaczenie dla danego zadania. Jeśli projektujemy system wprowadzania czasu, prawdopodobnie chcemy jakiejś klasy Pracownika, ale ta klasa nie potrzebuje właściwości do wyrażenia ulubionego koloru pracownika.
Dlatego modele nie powinny próbować (ani udawać) pełnego przedstawienia „świata rzeczywistego”.
Masz rację. Jeśli spojrzysz na duże programy, które nie są OOP, często są one nadal zorganizowane wokół struktur danych. Struktura danych i wszystkie manipulowane funkcje są zdefiniowane blisko siebie, ze względu na przejrzystość. (Projekt subversion jest tego dobrym przykładem. Struktury danych i funkcje są poprzedzone nazwami modułów, aby było jasne, które struktury i funkcje są ze sobą przeznaczone.)
Nie jestem ekspertem od historii języków programowania, ale wyobrażam sobie, że OOP wyrósł z przypadkowej obserwacji, że kod był bardziej przejrzysty i łatwiejszy do zrozumienia, gdy był zorganizowany w ten sposób, więc projektanci języków zaczęli projektować języki, w których ten typ organizacji był bardziej rygorystycznie egzekwowane.
Największą różnicą między OOP a innymi niż OOP jest to, że OOP wiąże kod z danymi. Zamiast wywoływać kod w ten sposób:
robimy to zamiast tego:
Chociaż może się to wydawać różnicą gramatyczną, różnica jest w rzeczywistości nastawiona. Mówimy obiektom, co mają robić, i zazwyczaj nie dbamy o stan wewnętrzny lub działanie obiektu. Opisując obiekt, musimy tylko opisać jego publiczny interfejs, aby z nim pracować.
źródło
Nie całkiem.
W prawdziwym świecie mamy do czynienia z prawdziwymi problemami. Chcemy rozwiązać ten problem za pomocą paradygmatu, który replikuje system, który chcemy zbudować, który staje się modelem.
Na przykład, jeśli problemem jest aplikacja Koszyk, mamy różne podmioty, takie jak
Produkt będący abstrakcyjnym terminem, który może mieć wielu członków, takich jak Książki, Gadżety, Samochody, które można ponownie podzielić.
Kryteria podatkowe, takie jak (podatek od sprzedaży), zależą od lokalizacji, w której oprogramowanie jest wdrażane, ponieważ podlega zmianom zgodnie z polityką rządu.
Podatek jest rozpatrywany na podstawie tego, czy produkt został przywieziony wraz z kryteriami podatkowymi.
Użytkownik może mieć koszyk z listą produktów itp.
Jak widać, istnieją prawdziwe problemy, które próbujemy rozwiązać, ale są one zmodularyzowane zgodnie z paradygmatem OOP, aby zbliżyć się do prawdziwego systemu, jak to możliwe.
źródło
Myślę, że za dużo czytasz w tym, co ma być bardzo prozaicznym, historycznym stwierdzeniem. Wiele pomysłów dotyczących programowania OO, klas, polimorfizmu, funkcji wirtualnych itp. Zostało wprowadzonych w języku Simula w latach 60. XX wieku (http://en.wikipedia.org/wiki/Simula). Jak sama nazwa wskazuje, Simula została zaprojektowana jako język do pisania symulacji. Tak więc historycznie tak, pomysły OO zostały wprowadzone w celu modelowania „prawdziwego świata”. To, czy odniosą większy sukces niż inne style, jest kwestią dyskusyjną.
źródło
Największa różnica między kodem OOP a kodem sprzed OOP polega na tym, że ten pierwszy modeluje sytuację w świecie rzeczywistym jako grupa odrębnych jednostek oddziałujących ze sobą, każda z ograniczoną „mocą” w zakresie tego, co może zrobić, a także zdolna do „reagowania” na zdarzenia zewnętrzne z własnymi działaniami. Ten ostatni modeluje wszystko jako duży fragment danych, który sam nic nie robi, podczas gdy obliczenia reprezentują „rzeczy, które się zdarzają” i mogą wpływać na niektóre lub wszystkie z nich.
To, czy lepiej modeluje rzeczywisty świat, czy nie, to naprawdę zależy od tego, które aspekty świata modelujesz. Na przykład symulacja fizyki, w której chcesz opisać skutki, które, powiedzmy, zapalony ogień miałby w otaczających obiektach, lepiej reprezentowałaby „tradycyjna” metoda, ponieważ zarówno światło, jak i ciepło są dobrze… zdefiniowane procesy, które wpływają zarówno na stan zewnętrzny, jak i wewnętrzny innych obiektów i nie różnią się w zależności od zachowania poszczególnych obiektów, na które wpływ mają tylko ich właściwości.
Z drugiej strony, jeśli modelujesz różne komponenty, które oddziałują na siebie, aby uzyskać pożądane zachowanie, traktowanie ich jako agentów zamiast rzeczy pasywnych może ułatwić wykonanie tego poprawnie bez niczego. Jeśli chcę włączyć telewizor, wystarczy nacisnąć przycisk, jeśli przewód zasilający jest odłączony
TV.turnOn
, sprawdzi to dla mnie. Tak więc nie ma ryzyka, że zmienisz trybik i zapomnisz obrócić tego, który go dotyka, ponieważ sam tryb (jeśli jest odpowiednio zaprogramowany) zajmie się drugorzędnymi interakcjami wynikającymi z pierwotnego.Uważam, że ma to więcej wspólnego ze sposobem, w jaki postrzegamy świat, niż z tym, jak on naprawdę jest. Można argumentować, że wszystko to tylko wiązka atomów (lub energii lub fal, cokolwiek innego), ale to nie pomaga nam poradzić sobie z zadaniem radzenia sobie z problemami, przed którymi stoimy, ze zrozumieniem otaczającego nas środowiska i przewidywaniem przyszłych wydarzeń ( lub opisując poprzednie). Tworzymy więc „modele mentalne” świata i często te modele mentalne znajdują lepszą zgodność z OO niż model danych + procesów - co prawdopodobnie modeluje „lepiej” rzeczywisty świat.
Warto również zauważyć, że większość ludzi uważa OOP za synonim „klasycznego OOP”, w którym taksonomicznie tworzymy zbiory i podzbiory rzeczy, i jednoznacznie umieszczamy obiekty w bardzo specyficznym zestawie. Jest to bardzo przydatne do tworzenia nowych typów wielokrotnego użytku , ale nie tak świetne, gdy modelowany element jest dość samowystarczalny i chociaż inicjuje interakcje z innymi obiektami, rzadko, jeśli w ogóle, jest celem interakcji. Lub gorzej, gdy istnieje kilka (może tylko jeden) przypadek tego podmiotu lub przypadki różnią się znacznie pod względem składu, zachowania lub obu.
Istnieje jednak również „prototypowy OOP”, w którym obiekt jest opisywany przez wybranie podobnego i wyliczenie aspektów, w których się różnią. Proponuję ten esej, aby uzyskać dobre i niezbyt techniczne wyjaśnienie procesu myślowego (cały post jest zbyt duży, nawet jak na standardy Steve'a Yegge, więc wskazuję odpowiednią sekcję: P). Ponownie, jest to dobre dopasowanie do naszych modeli mentalnych, gdy wyobrażamy sobie nieznane przypadki w porównaniu do znanego, ale niekoniecznie ze względu na to, jak działa prawdziwy świat ... (dwie krowy są w rzeczywistości całkowicie odrębnymi bytami, nawet jeśli je postrzegamy pod wieloma względami „podobne”)
źródło
Myślę, że „robi” jest ważną częścią tego pytania. Myślę, że programowanie obiektowe z pewnością może modelować rzeczywiste „obiekty”, ale to jest programowanie . Nie ma metodologii, która nie mogłaby być nadużywana, więc nie sądzę, że można powiedzieć „OOP nie modeluje prawdziwego świata” tylko dlatego, że możesz robić głupie rzeczy z Przedmiotami. Nie jest to bardziej sprawiedliwe niż stwierdzenie, że wskaźniki nie są bezpieczne, ponieważ można robić głupie rzeczy za pomocą wskaźników.
Artykuł Wikipedii na ten temat dobrze podsumowuje:
Chodzi o to, że jeśli twój program nie jest symulacją wszechświata, dbasz tylko o części świata rzeczywistego - stąd „model”. Do tego służą modele, które zapewniają strukturę i funkcjonalność, które musisz wyświetlić.
W prawdziwym świecie mamy rzeczy (obiekty) i rzeczy mogą wykonywać działania (metody). Możemy kwantyfikować aspekty rzeczy (właściwości). OOP ma wszelkie możliwości modelowania rzeczy z prawdziwego świata, gdy jest stosowany w sposób redukcjonistyczny; każda złożona rzecz ma mniejsze lub bardziej szczegółowe podklasy i wszystkie te rzeczy mają naturalne interakcje metodami.
OOP jest metodą abstrakcji, więc praktyczną rzeczą jest to, czy OOP naprawdę logicznie modeluje obiekty w Realnym Świecie, mniej ważne jest, aby nie modelować każdej możliwej rzeczy, którą wszystko może zrobić . Jeśli musisz zrobić każdą możliwą rzecz, tak naprawdę nie modelujesz .
źródło
Aby myśleć o orientacji obiektowej we właściwym kontekście, przejdźmy o jeden poziom abstrakcji i porozmawiajmy o programowaniu w ogóle, dobrze?
Niezależnie od tego, czy przyjmujesz podejście OO, czy funkcjonalne, twój program musi coś zrobić , prawda? Celem całego programu jest pokazanie określonych zachowań przy określonym zestawie bodźców. Dlatego w ogóle istnieją programy, ponieważ coś robią . Kluczowym słowem jest tutaj zachowanie .
Oprócz rozważenia, jakie zachowania musi wdrożyć program, twój program na ogół musi wykazywać pewne cechy. Na przykład, nie wystarczy, aby program monitorujący serce miał wymagane od niego zachowania - zwykle musi także działać wystarczająco szybko, aby działać w czasie zbliżonym do rzeczywistego. Inne „cechy”, które program może potrzebować, to: bezpieczeństwo, elastyczność, modułowość, rozszerzalność, czytelność i tak dalej. Nazywamy te Architektoniczne Atrybuty Jakości . Możemy więc powiedzieć, że nasz program musi spełniać określone cele behawioralne (funkcjonalne), a także wykazywać pewne cechy (niefunkcjonalne).
Jak dotąd nic z tego nie mówiło o OO, prawda? Zróbmy to teraz.
Gdy inżynier zrozumie wymagania (behawioralne, AQA, ograniczenia itp.), Powstaje pytanie: jak mam uporządkować mój kod, aby spełniał wszystkie swoje potrzeby, a jednocześnie wykazywał cechy niezbędne do bycia użytecznym programem? Programowanie obiektowe to strategia organizowania funkcjonalności programu w spójne moduły współpracujących obiektów. Programowanie funkcjonalne to kolejna strategia organizowania funkcjonalności programu i robi to w inny sposób. Obie strategie mają swoje mocne i słabe strony.
Jesteśmy świadkami niedawnego odrodzenia się koncepcji funkcjonalnych, ponieważ ma mocne strony, które są bardzo atrakcyjne dla ogromnie rozproszonego przetwarzania, między innymi.
Ale wracając do OO, widać teraz, że niekoniecznie modeluje „rzeczywisty świat”; jego zadaniem jest uporządkowanie zachowania Twojego programu, tak aby Twój program mógł wykazywać cechy niezbędne do osiągnięcia dowolnej liczby celów biznesowych. Techniki takie jak TDD, DDD i BDD to sposoby, w jakie odkrywamy, jak najlepiej zorganizować nasze obiekty. Książki takie jak zasady, wzorce i praktyki , rozwijanie oprogramowania zorientowanego obiektowo kierowanego testami , specyfikacja według przykładów i projektowanie oparte na domenie przedstawiają teorię i praktykę orientacji obiektowej, koncentrując się na projektowaniu opartym na zachowaniu.
Kiedy czytasz o takich rzeczach jak „obserwatorzy, kierownicy, fabryki itp.”, Stosujesz wzorce OO, które pomagają Twojemu programowi wykazywać pewne cechy, które mogą być konieczne, aby był użyteczny. Są to „sprawdzone przepisy”, które „mają tendencję do działania”, biorąc pod uwagę, że Twoje potrzeby odpowiadają problemowi rozwiązanemu przez wzór.
Mam nadzieję, że to pomoże ci zrozumieć, o czym jest OO, bez wydawania się zbyt tendencyjnego między OO a paradygmatami funkcjonalnymi.
źródło
OOP tworzy ładny model z punktu widzenia programowania, nie odzwierciedla rzeczywistego świata.
Istnieją jednak znacznie lepsze przybliżenia świata rzeczywistego, znane pod nazwą języków specyficznych dla domeny ( DSL ). Na przykład Boo umożliwia pisanie czytelnego dla człowieka kodu w prawie zwykłym angielskim (przykład z artykułu ).
Innym przykładem mogą być zautomatyzowane ramy testowania akceptacji użytkowników oparte na języku korniszon .
źródło
W końcu to zależy od ciebie. Ale OOP to dokładny sposób niż inne metodologie, takie jak programowanie strukturalne lub programowe. Taktyka proceduralna może rozwiązać twoje problemy, ale przestrzeganie OOP może ułatwić ci życie.
źródło