Co to jest abstrakcja? [Zamknięte]


38

Czy istnieje ogólnie uzgodniona definicja tego, czym jest abstrakcja programowania , stosowana przez programistów? [Uwaga: abstrakcji programowej nie należy mylić z definicjami słownika dla słowa „abstrakcja”.] Czy istnieje jednoznaczna, a nawet matematyczna definicja? Jakie są jasne przykłady abstrakcji?


.. i bycie zmuszonym do udowodnienia, że ​​nie jestem robotem, kiedy to publikuję, sugeruje, że naprawdę proszę o zbyt wiele :)
mlvljr

8
Co rozumiesz przez „matematycznie”? Tak naprawdę nie uważałbym abstrakcji za pojęcie matematyczne.
Fishtoaster,

2
@mlvljr: Przepraszam, wciąż nie jestem pewien, czy śledzę. Abstrakcja to tylko praktyka zapewniania prostszego sposobu radzenia sobie z czymś. Nie rozumiem, jak formalne narzędzia / metody mają z tym coś wspólnego.
Fishtoaster,

1
@mlvljr, Czy chcesz przykład matematyczny, czy matematyka obejmująca wszystkie fragmenty programowania. Nie sądzę, że to drugie istnieje.
C. Ross

8
Perhpas cstheory.stackexchange.com jest właściwym miejscem na to pytanie
Conrad Frix

Odpowiedzi:


46

Odpowiedź na „Czy potrafisz zdefiniować, czym jest abstrakcja programowa mniej więcej matematycznie?” nie jest." Abstrakcja nie jest pojęciem matematycznym. To tak, jakby poprosić kogoś, aby wyjaśnił matematycznie kolor cytryny.

Jeśli chcesz mieć dobrą definicję: abstrakcja jest procesem przejścia od konkretnego pomysłu do bardziej ogólnego. Na przykład spójrz na swoją mysz. Czy to jest bezprzewodowe? Jaki to ma czujnik? Ile przycisków? Czy to jest ergonomiczne? Jak duże to jest? Odpowiedzi na wszystkie te pytania mogą precyzyjnie opisać twoją mysz, ale niezależnie od odpowiedzi, nadal jest to mysz, ponieważ jest to urządzenie wskazujące z przyciskami. To wystarczy, aby zostać myszą. „Silver Logitech MX518” to konkretny, konkretny przedmiot, a „mysz” to jego abstrakcja. Ważną rzeczą do przemyślenia jest to, że nie ma takiego konkretnego obiektu jak „mysz”, to tylko pomysł. Mysz na biurku jest zawsze czymś bardziej szczegółowym - to „

Abstrakcja może być warstwowa i tak drobnoziarnista, jak i gruboziarnista, jak chcesz (MX518 to mysz, która jest obiektem wskazującym, który jest peryferyjnym komputerem, który jest obiektem zasilanym elektrycznie), może iść tak daleko, jak chcesz i praktycznie w dowolnym kierunku (moja mysz ma drut, co oznacza, że ​​mógłbym go zaklasyfikować jako przedmiot z drutem. Jest również płaski na dole, więc mogę zaklasyfikować go jako rodzaj przedmiotów, które nie będą się toczyć, gdy umieszczone pionowo na pochyłej płaszczyźnie).

Programowanie obiektowe opiera się na pojęciu abstrakcji i ich rodzin lub grup. Dobry OOP oznacza wybranie dobrych abstrakcji na odpowiednim poziomie szczegółowości, które mają sens w dziedzinie twojego programu i nie „wyciekają”. To pierwsze oznacza, że ​​klasyfikowanie myszy jako obiektu, który nie będzie się toczył po pochyłej płaszczyźnie, nie ma sensu w przypadku aplikacji, która inwentaryzuje sprzęt komputerowy, ale może mieć sens w przypadku symulatora fizyki. To ostatnie oznacza, że ​​powinieneś starać się unikać „bycia w boksie” w hierarchii, która nie ma sensu dla niektórych rodzajów obiektów. Na przykład w mojej hierarchii powyżej jesteśmy pewni, że wszyscyperyferia komputerowe są zasilane energią elektryczną? Co z rysikiem? Gdybyśmy chcieli pogrupować rysik w kategorię „urządzenia peryferyjne”, mielibyśmy problem, ponieważ nie wykorzystuje on prądu, i zdefiniowaliśmy urządzenia peryferyjne jako obiekty wykorzystujące prąd. Problemem koło-elipsa jest najbardziej znanym przykładem tej zagadki.


2
Myślę, że widzę; mówisz konkretnie o odwołaniu się do metody lub funkcji w sposób abstrakcyjny, tj. przez jej umowę w przeciwieństwie do jej implementacji. Twoje oświadczenia są prawidłowe i jest to całkowicie poprawne użycie tego terminu; wywołanie metody jest abstrakcją pewnego rodzaju konkretnego zachowania.
nlawalker

4
@nlawalker: Mieszasz abstrakcję z uogólnieniem. To nie to samo. Opisujesz to drugie („przejście od konkretnego pomysłu do bardziej ogólnego ”). Abstrakcja przechodzi od konkretnych rzeczy do rzeczy abstrakcyjnych, np. Mając 7 niebieskich i 7 czerwonych marmurów i mówiąc: „Mam dwa zestawy o tej samej liczbie marmurków tego samego koloru”: tutaj przechodzę od rzeczy betonowych (marmurów) do rzeczy abstrakcyjnych (klasy i zestawy równoważne). BTW, liczba naturalna n jest klasą wszystkich równoważnych zestawów liczności n, nieokrągłych, zdefiniowanych przez odwzorowania jeden na jeden między tymi zbiorami.
pillmuncher

33
Matematyczne jest zabarwienie cytryny o długości fali około 570 nm.
Erik,

1
@Erik Chciałem to napisać. Bah!
Gary Rowe,

1
@Erik To fizyka, nie matematyka :) Matematyka nie wie nic o pojęciach takich jak „światło”. Światło jest empiryczne; Matematyka nie jest.
Andres F.,

25

Kategorycznie nie zgadzam się z większością odpowiedzi.

Oto moja odpowiedź:

Biorąc pod uwagę dwa zestawy G i H, można zdefiniować między nimi połączenie Galois (alfa, beta) , a jeden z nich może być konkretyzacją drugiego; odwróć połączenie, a jedno jest abstrakcją drugiego. Funkcje są funkcją konkretyzacji i funkcją abstrakcji.

Wynika to z teorii abstrakcyjnej interpretacji programów komputerowych, która do tej pory jest zazwyczaj metodą analizy statycznej.


8
OK, otrzymujesz złotą gwiazdę za profesorstwo :)
Mike Dunlavey

@Mike: Tak? :-)
Paul Nathan

Ach, czy może być jakiś przykład?
mlvljr

2
@mlvljr: di.ens.fr/~cousot/AI astree.ens.fr dostarczają szkic danych.
Paul Nathan

1
Amir: to techniczna definicja abstrakcji ze świata analizy statycznej.
Paul Nathan

13

Abstrakcja jest bardziej skoncentrowana, Whata mniej na How. Możesz też powiedzieć, znać tylko to, czego potrzebujesz, i zaufać dostawcy wszystkich innych usług. Czasami nawet ukrywa tożsamość usługodawcy.

Na przykład ta strona zapewnia system zadawania pytań i udzielania odpowiedzi. Prawie wszyscy tutaj wiedzą, jakie są procedury dotyczące pytania, odpowiadania, głosowania i innych rzeczy na tej stronie. Ale niewielu wie, jakie są podstawowe technologie. Na przykład, czy witryna została opracowana przy użyciu ASP.net mvc lub Python, czy działa ona na serwerze z systemem Windows lub Linux itp. Ponieważ to nie jest nasza sprawa. Tak więc ta strona utrzymuje warstwę abstrakcji nad mechanizmem leżącym u jej podstaw, zapewniając nam świadczenie usługi.

Kilka innych przykładów:

  • Samochód ukrywa wszystkie swoje mechanizmy, ale zapewnia sposób prowadzenia pojazdu, tankowania i utrzymania go właścicielowi.

  • Każdy interfejs API ukrywa wszystkie szczegóły implementacji, udostępniając usługę innym programistom.

  • Klasa w OOP ukrywa swoich prywatnych członków i implementację publicznych członków zapewniających usługę dzwonienia do publicznych członków.

  • Podczas używania obiektu typu an Interfacelub an abstract classw Javie lub C ++ prawdziwa implementacja jest ukryta. I nie tylko ukryte, implementacje metod zadeklarowanych w parametrach Interfacemogą również różnić się w różnych zaimplementowanych / dziedziczonych klasach. Ale ponieważ otrzymujesz tę samą usługę, po prostu nie przejmuj się, Howże została ona wdrożona i dokładnie Who/ Whatświadczy usługę.

  • Ukrywanie tożsamości : dla zdania „Wiem, że Sam potrafi pisać programy komputerowe”. abstrakcja może brzmieć: „Sam jest programistą. Programiści potrafią pisać programy komputerowe”. W drugim stwierdzeniu osoba nie jest ważna. Ale jego umiejętność programowania jest ważna.


Dlaczego więc nie nazwać tego „dokładną specyfikacją czego”?
mlvljr

+1 za bit satori, również
mlvljr

@mlvljr Trochę Howjest zawsze pomocne, aby zrozumieć Whats. Można go więc połączyć z abstrakcją.
Gulshan,

7

Abstrakcja programowania jest uproszczonym modelem problemu.

Na przykład połączenie TCP / IP jest abstrakcją nad wysyłaniem danych. Wystarczy podać adres IP i numer portu i wysłać go do interfejsu API. Nie przejmujesz się wszystkimi szczegółami przewodów, sygnałów, formatów wiadomości i awarii.


Aha! Co to jest uproszczony model tutaj? Pamiętasz nieszczelną łamigłówkę? :)
mlvljr

7

Abstrakcja jest tylko programową wersją twierdzenia.

Masz system formalny, proponujesz przemyślenie na temat tego systemu. Robisz na to dowód, a jeśli to się uda, masz twierdzenie. Wiedząc, że twoje twierdzenie się utrzymuje, możesz je wykorzystać w dalszych dowodach dotyczących systemu. Prymitywy dostarczone przez system (takie jak instrukcje if i typy wartości int) zwykle byłyby postrzegane jako aksjomaty, chociaż nie jest to do końca prawdą, ponieważ wszystko, co nie jest instrukcją CPU zapisaną w kodzie maszynowym, jest rodzajem abstrakcji.

W programowaniu funkcjonalnym idea programu jako wyrażenia matematycznego jest bardzo silna i często system typów (w silnym, statycznie typowanym języku, takim jak Haskell, F # lub OCAML) może być wykorzystywany do testowania twierdzeń za pomocą dowodów.

Na przykład: powiedzmy, że mamy sprawdzanie dodawania i równości jako operacje pierwotne, a liczby całkowite i logiczne jako prymitywne typy danych. To są nasze aksjomaty. Możemy więc powiedzieć, że 1 + 3 == 2 + 2jest to twierdzenie, a następnie użyj reguł dodawania, liczb całkowitych i równości, aby sprawdzić, czy to prawdziwe stwierdzenie.

Załóżmy teraz, że chcemy pomnożenia, a nasze prymitywy (dla zwięzłości) zawierają konstrukcję zapętlającą i sposób przypisywania odniesień symbolicznych. Możemy to zasugerować

ref x (*) y := loop y times {x +}) 0

Udam, że to udowodniłem, pokazując, że mnożenie się utrzymuje. Teraz mogę używać mnożenia, aby robić więcej rzeczy z moim systemem (językiem programowania).

Mogę również sprawdzić mój system typów. (*) ma typ int -> int -> int. Zajmuje 2 inty i wyprowadza int. Dodawanie ma typ int -> int -> int, więc 0 + (reszta) zachowuje tak długo, jak (reszta) powoduje int. Moja pętla może robić różne rzeczy, ale mówię, że generuje łańcuch curry funkcji takich, że (x + (x + (x ... + 0))) jest wynikiem. Forma tego łańcucha dodawania jest po prostu (int -> (int -> (int ... -> int))), więc wiem, że moją ostateczną odpowiedzią będzie int. Więc mój system typów przechował wyniki mojego innego dowodu!

Złóż ten pomysł przez wiele lat, wielu programistów i wiele linii kodu, a masz nowoczesne języki programowania: bogaty zestaw prymitywów i ogromne biblioteki „sprawdzonych” abstrakcji kodu.


4

Czy odpowiedź Wikipedii byłaby wystarczająca? http://en.wikipedia.org/wiki/Abstraction_%28programming%29

W informatyce mechanizm i praktyka abstrakcji zmniejsza i rozróżnia szczegóły, dzięki czemu można skupić się na kilku koncepcjach naraz.


A jaki byłby wówczas przykład rzeczy abstrakcyjnej?
mlvljr

3
@mlvljr: Jeśli przeczytasz artykuł na Wikipedii, zobaczysz kilka.
John Fisher

Niestety jestem prawie pewien, że będą zbyt abstrakcyjni ...
mlvljr,

4

Matematycznie „liczba całkowita” jest abstrakcją. A kiedy robisz formalne dowody takie jak x + y = y + x dla wszystkich liczb całkowitych, pracujesz z abstrakcyjną „liczbą całkowitą”, a nie z konkretnymi liczbami, takimi jak 3 lub 4. To samo dzieje się w rozwoju oprogramowania, gdy wchodzisz w interakcję z maszyna na poziomie powyżej rejestrów i lokalizacji pamięci. W większości przypadków możesz myśleć silniejszymi myślami na bardziej abstrakcyjnym poziomie.


Nie używania i IInt add(IInt a, IInt b);podprogramów w programie, w którym wcześniej wiedzieć , że ai bbędzie, powiedzmy Int128: IIntbardziej lub mniej dobrego przykładu? - czy masz swój kod do robienia tego, co powinien, wiedząc (będąc w stanie udowodnić) zrobi to, czego potrzebujesz, a jednocześnie (i z drugiej strony) sprawisz, że zrobi dokładnie to, co chcesz potrzebujesz tego bez wiedzy (ze zdolnością do używania tej rzeczy również w innych kontekstach)?
mlvljr

1
Przepraszam, ale nie rozumiem twojego pytania.
Kate Gregory

Załóżmy, że piszesz program, który musi dodać 2 do 3. Robisz to, wywołując add(int, int)podprogram / funkcję. Wystarczy mieć go właśnie return 2 + 3;w tym przypadku. I dlaczego miałbyś stosować bardziej „uniwersalną” procedurę ( return a + b;tj. Operowanie dowolnymi rzeczywistymi a i podanymi bparametrami, a tym samym naprawdę abstrakcyjnym od ich wartości) - to było moje (retoryczne) pytanie powyżej. Mam nadzieję, że stało się to teraz bardziej jasne.
mlvljr

Mój pierwszy komentarz jest dość „zaciemniony”, zgadzam się :)
mlvljr

4

Dostajesz tutaj dobre odpowiedzi. Chciałbym tylko przestrzec - ludzie myślą, że abstrakcja jest w jakiś sposób cudowną rzeczą, którą należy postawić na piedestale i na którą nie można się nacieszyć. Nie jest. To tylko zdrowy rozsądek. Po prostu rozpoznaje podobieństwa między rzeczami, dzięki czemu można zastosować rozwiązanie problemu dla szeregu problemów.

Pozwól mi się wkurzyć ...

Wysoko na mojej liście irytacji jest, gdy ludzie mówią o „warstwach abstrakcji”, jakby to była dobra rzecz. Robią „owijarki” wokół klas lub procedur, które im się nie podobają, i nazywają je „bardziej abstrakcyjnymi”, jakby to ich poprawiło. Pamiętasz bajkę o „księżniczce i grochu”? Księżniczka była tak delikatna, że ​​jeśli pod jej materacem znajdował się groszek, nie byłaby w stanie spać, a dodanie kolejnych warstw materacy nie pomogłoby. Pomysł, że dodanie większej liczby warstw „abstrakcji” pomoże, jest właśnie taki - zwykle tak nie jest. Oznacza to po prostu, że każda zmiana w jednostce bazowej musi być pomarszczona przez wiele warstw kodu.


Myślenie o abstrakcji jako o czymś „zbyt pięknym, aby być wyraźnie postrzeganym (lub nawet bardziej opisanym suchymi (matematycznymi) terminami”), nie pomaga (po pierwsze i przynajmniej) zrozumieć, co to jest, i (po drugie) rozwinąć techniki jego ocena zastosowania i (horroru!) [tego, w jaki sposób i w jaki sposób dany kod jest abstrakcyjny]
mlvljr

3
Jeśli zmiana w jednym miejscu powoduje, że musisz dokonać wielu zmian w innym miejscu, twoje abstrakcje są złe. Zasadniczo nie powiem, że ja lub ktokolwiek inny nigdy nie popełniłem błędu po stronie zbyt dużej abstrakcji, ale istnieje metoda na to szaleństwo. Dobre abstrakty są podstawą luźno powiązanego kodu. Biorąc pod uwagę właściwą abstrakcję, zmiany stają się absurdalnie proste. Tak, tak, umieszczam abstrakcje na piedestale i spędzam nadmiernie dużo czasu na znajdowaniu odpowiednich.
Jason Baker

@Jason Baker Niech nasze techniki abstrakcji będą wystarczająco konkretne, aby skutecznie je wykorzystać ...
mlvljr

1
@Jason: „Jeśli zmiana w jednym miejscu powoduje, że musisz dokonać wielu zmian w innym miejscu, to twoje abstrakcje są złe”. Jestem tam z tobą. Wydaje mi się, że otaczają mnie złe.
Mike Dunlavey,

1
Wygląda na to, że pracowałeś w miejscu, w którym twórcy mieli wielkie wizje, i że nie było silnego szefa, który utrzymywałby skupienie zespołu. Kiedy znajduję się w takim środowisku, zaczynam szukać innej pracy (budżety projektów zawsze się kończą lub wystarczająco mała firma => bankrutuje). Ostatnio widziałem tweeta: „kod spaghetti” vs. „kod lasagna”, ten ostatni ma miejsce, gdy jest zbyt wiele warstw.
yzorg,

4

Myślę, że może się przydać mój post na blogu o nieszczelnych abstrakcjach. Oto odpowiednie tło:

Abstrakcja jest mechanizmem, który pomaga wziąć to, co wspólne dla zestawu powiązanych fragmentów programu, usunąć ich różnice i umożliwić programistom bezpośrednią pracę z konstrukcją reprezentującą tę abstrakcyjną koncepcję. Ten nowy konstrukt (praktycznie) zawsze ma parametryzację : sposób na dostosowanie sposobu używania konstruktora do konkretnych potrzeb.

Na przykład Listklasa może wyodrębnić szczegóły implementacji listy połączonej - gdzie zamiast myśleć o kategoriach manipulacji nexti previouswskaźników, możesz myśleć na poziomie dodawania lub usuwania wartości do sekwencji. Abstrakcja jest niezbędnym narzędziem do tworzenia użytecznych, bogatych, a czasem złożonych funkcji na podstawie znacznie mniejszego zestawu bardziej prymitywnych koncepcji.

Abstrakcja wiąże się z enkapsulacją i modułowością, a te pojęcia są często źle rozumiane.

W tym Listprzykładzie można zastosować enkapsulację, aby ukryć szczegóły implementacji listy połączonej; na przykład w języku zorientowanym obiektowo można ustawić prywatne wskaźniki nexti previouswskaźniki, w których tylko implementacja listy ma dostęp do tych pól.

Kapsułkowanie nie wystarcza do abstrakcji, ponieważ niekoniecznie oznacza, że ​​masz nową lub inną koncepcję konstruktów. Gdyby wszystko, co Listzrobiła klasa, dawało ci metody dostępu do stylu getNext„/” setNext, zawierałoby od ciebie szczegóły implementacji (np. Czy nazwałeś pole prev„czy previous”? Jaki był jego typ statyczny?), Ale to miałby bardzo niski stopień abstrakcji.

Modułowość dotyczy ukrywania informacji : stabilne właściwości są określone w interfejsie, a moduł implementuje ten interfejs, zachowując wszystkie szczegóły implementacji w module. Modułowość pomaga programistom radzić sobie ze zmianami, ponieważ inne moduły zależą tylko od stabilnego interfejsu.

Ukrywanie informacji jest wspomagane przez enkapsulację (dzięki czemu kod nie zależy od niestabilnych szczegółów implementacji), ale enkapsulacja nie jest konieczna dla modułowości. Na przykład, można wdrożyć Liststruktury w C, odsłaniając „ next” i „ prevwskaźniki” na świecie, ale także interfejs, zawierający initList(), addToList()orazremoveFromList()Funkcje. Pod warunkiem, że przestrzegane są reguły interfejsu, można zagwarantować, że pewne właściwości będą zawsze obowiązywać, na przykład upewnić się, że struktura danych jest zawsze w poprawnym stanie. [Klasyczny artykuł Parnasa na temat modułowości, na przykład, został napisany z przykładem w asemblerze. Interfejs jest umową i formą komunikacji na temat projektu, niekoniecznie musi być sprawdzany mechanicznie, chociaż na tym dziś polegamy.]

Chociaż terminy takie jak abstrakcyjne, modułowe i enkapsulowane są używane jako pozytywne opisy projektu, ważne jest, aby zdawać sobie sprawę, że obecność którejkolwiek z tych cech nie zapewnia automatycznie dobrego projektu:

  • Jeśli algorytm n ^ 3 jest „ładnie zamknięty”, nadal będzie działał gorzej niż ulepszony algorytm n log n.

  • Jeśli interfejs zostanie przypisany do konkretnego systemu operacyjnego, żadna z korzyści modułowej konstrukcji nie zostanie zrealizowana, gdy powiedzmy, że gra wideo musi zostać przeniesiona z systemu Windows na iPada.

  • Jeśli utworzona abstrakcja ujawni zbyt wiele nieistotnych szczegółów, nie uda jej się stworzyć nowego konstruktu z własnymi operacjami: Będzie to po prostu inna nazwa tego samego.


Cóż, wydaje się, że chodzi o to, czego naprawdę chciałem (niektóre „ranty” odporne na typowe / przykładowe „na” modułowe == streszczenie == dobre == widok, którego nigdy nie można oszacować, po prostu walczyć)) , dzięki (wciąż czytam)
mlvljr

A oto prowokujące motto mojej nadchodzącej odpowiedzi (na moje własne pytanie) „Abstrakcje przeciekają, gdy umysły
słabną

2

Ok, chyba wymyśliłem, o co pytasz: „Co to jest matematycznie rygorystyczna definicja„ Analizy ”.

Jeśli tak jest, myślę, że nie masz szczęścia - „abstrakcja” jest terminem architektury / projektowania oprogramowania i nie ma żadnego matematycznego poparcia, o ile mi wiadomo (może ktoś lepiej zorientowany w teoretycznej CS poprawi mnie tutaj), bardziej niż „sprzężenie” lub „ukrywanie informacji” mają definicje matematyczne.


2

Abstrakcja polega na ignorowaniu szczegółów uznanych za nieistotne na rzecz tych uznanych za istotne.

Abstrakcja obejmuje enkapsulację, ukrywanie informacji i generalizację. Nie obejmuje analogii, metafor ani heurystyki.

Każdy formalizm matematyczny dla pojęcia abstrakcji sam byłby abstrakcją, ponieważ koniecznie wymagałby abstrakcji podstawowej rzeczy w zbiór właściwości matematycznych! Pojęcie morfizmu według teorii kategorii jest prawdopodobnie najbliższe temu, czego szukasz.

Abstrakcja nie jest czymś, co deklarujesz, ale czymś, co robisz .


+1, „Robię abstrakcję!” będzie fajny dla koszulki;) Dziękuję również za link na temat morfizmu (ów) (choć nie wspomina on bezpośrednio o poli - jednym z kilkunastu innych wymienionych;)) również.
mlvljr,

2

Aby wyjaśnić to innej osobie, chciałbym przejść na drugą stronę, od wyników:

Abstrakcja w programowaniu komputerowym polega na uogólnieniu czegoś do tego stopnia, że ​​więcej niż jedna podobna rzecz może być ogólnie traktowana tak samo i traktowana tak samo.

Jeśli chcesz rozwinąć, możesz dodać:

Czasami robi się to, aby osiągnąć zachowanie polimorficzne (interfejsy i dziedziczenie) w celu ograniczenia powtarzalnego kodu z góry, innym razem robi się tak, aby wewnętrzne funkcjonowanie czegoś mogło zostać w przyszłości zastąpione podobnym rozwiązaniem bez konieczności zmiany kod po drugiej stronie abstrakcyjnego pojemnika lub opakowania, miejmy nadzieję, że w przyszłości zmniejszy to liczbę przeróbek.

Poza tym myślę, że musisz zacząć od przykładów ...


1

Możesz sprawdzić niektóre dane Boba Martina

http://en.wikipedia.org/wiki/Software_package_metrics

To powiedziawszy, nie sądzę, że jego „Abstrakcyjność” jest taka sama jak twoja. Jest bardziej miarą „braku implementacji na klasie”, co oznacza użycie interfejsów / klas abstrakcyjnych. Niestabilność i odległość od głównej sekwencji prawdopodobnie grają więcej w to, czego szukasz.


Tak, pamiętaj ten papier. Wujek Bob jest genialny w ożywianiu tłumu i zainteresowaniu ludzi mechaniką OO.
mlvljr

O dziwo, zapomniałem głosować (od razu) :)
mlvljr

1

Merriam-webster definiuje abstrakcję jako przymiotnik: nie jest powiązany z żadnym konkretnym wystąpieniem.

Abstrakcja jest modelem jakiegoś systemu. Często wymieniają grupę założeń, które muszą zostać spełnione, aby prawdziwy system mógł być modelowany za pomocą abstrakcji, i często są używane, aby umożliwić nam konceptualizację coraz bardziej skomplikowanych systemów. Przejście od prawdziwego systemu do abstrakcji nie ma do tego żadnej formalnej metody matematycznej. To zależy od osądu, kto definiuje abstrakcję i jaki jest jej cel.

Często jednak abstrakcje są definiowane w kategoriach konstrukcji matematycznych. Prawdopodobnie dlatego, że są tak często używane w nauce i inżynierii.

Przykładem jest mechanika Newtona. Zakłada, że ​​wszystko jest nieskończenie małe, a cała energia jest zachowana. Interakcje między obiektami są jasno określone za pomocą wzorów matematycznych. Teraz, jak wiemy, wszechświat nie działa w ten sposób i w wielu sytuacjach abstrakcja przecieka. Ale w wielu sytuacjach działa bardzo dobrze.

Innym modelem abstrakcyjnym są typowe elementy obwodu liniowego, rezystory, kondensatory i cewki indukcyjne. Ponownie interakcje są jasno określone za pomocą wzorów matematycznych. W przypadku obwodów niskiej częstotliwości lub prostych sterowników przekaźników i innych rzeczy analiza RLC działa dobrze i zapewnia bardzo dobre wyniki. Ale inne sytuacje, takie jak obwody radia mikrofalowego, elementy są zbyt duże, a interakcje są subtelniejsze, a proste abstrakcje RLC nie wytrzymują. Co należy zrobić w tym momencie, zależy od inżyniera. Niektórzy inżynierowie stworzyli kolejną abstrakcję nad innymi, niektórzy zastępują idealne wzmacniacze operacyjne nowymi formułami matematycznymi dotyczącymi ich działania, inni zastępują idealne wzmacniacze operacyjne symulowanymi prawdziwymi wzmacniaczami operacyjnymi, które z kolei są symulowane złożoną siecią mniejszych idealne elementy.

Jak powiedzieli inni, jest to model uproszczony. Jest to narzędzie służące do lepszego zrozumienia złożonych systemów.


Powinienem chyba podkreślić to lepiej, ale nie interesują mnie takie abstrakcje, w których brakuje niepotrzebnych szczegółów dotyczących ich prototypów w prawdziwym świecie, ale w ten sposób dostarczają przydatnych wskazówek na temat projektowania systemów, które powinny radzić sobie z wyżej wymienionymi obiektami ze świata rzeczywistego (przykładem jest budowa klasy Employee z pewnymi rzeczywistymi właściwościami pracownika, które mogą być przydatne w aplikacji biznesowej). Interesuje mnie rodzaj abstrakcji, która „izoluje” byt programowy od innych takich podmiotów, które sobie z tym poradzą (przykładem będą Employerzałożenia Employee).
mlvljr

1
Nie masz żadnego sensu. Podawanie wskazówek dotyczących projektowania prawdziwego systemu nie jest celem abstrakcji. Jeśli nie wiesz nic o tym, co jest modelowane, nie jest to problem do rozwiązania dla abstrakcji.
whatsisname

Mówiłem o usunięciu szczegółów rzeczywistych obiektów, z którymi oprogramowanie będzie sobie radzić - w trakcie tworzenia tego oprogramowania. Wykorzystanie (oprogramowania) abstrakcji realnego świata do (przeprojektowania), że rzecz w świecie rzeczywistym nie miała na myśli (chodzi o „systemy oprogramowania” jako „systemy” w ”, ale w ten sposób dostarczają kilku pomocnych wskazówek na temat projektowania systemów” w mój komentarz powyżej).
mlvljr

1

Abstrakcja reprezentuje coś (np. Pojęcie, strukturę danych, funkcję) w kategoriach czegoś innego. Na przykład używamy słów do komunikacji. Słowo to abstrakcyjny byt, który można przedstawić w kategoriach dźwięków (mowy) lub symboli graficznych (pisania). Kluczową ideą abstrakcji jest to, że dana istota różni się od reprezentacji leżącej u jej podstaw, podobnie jak słowo nie jest dźwiękiem używanym do jego wypowiedzenia ani literami używanymi do jego napisania.

Zatem przynajmniej teoretycznie podstawową reprezentację abstrakcji można zastąpić inną reprezentacją. W praktyce jednak abstrakcja rzadko różni się całkowicie od reprezentacji leżącej u podstaw, a czasami reprezentacja „ przecieka ”. Na przykład mowa ma podtekst emocjonalny, który bardzo trudno jest przekazać na piśmie. Z tego powodu nagranie audio i transkrypcja tych samych słów mogą mieć bardzo różny wpływ na odbiorców. Innymi słowy, abstrakcja słów często przecieka.

Abstrakcje zazwyczaj występują w warstwach. Słowa to abstrakcje, które mogą być reprezentowane przez litery, które z kolei same w sobie są abstrakcjami dźwięków, które z kolei są abstrakcjami wzoru ruchu cząstek powietrza, które są tworzone przez akordy głosowe i które są wykrywane przez bębny uszne .

W informatyce bity są zazwyczaj najniższym poziomem reprezentacji. Bajty, lokalizacje pamięci, instrukcje montażu i rejestry procesora to kolejny poziom abstrakcji. Następnie mamy prymitywne typy danych i instrukcje języka wyższego poziomu, które są implementowane w kategoriach bajtów, lokalizacji pamięci i instrukcji asemblacji. Następnie funkcje i klasy (przy założeniu języka OO), które są implementowane w kategoriach prymitywnych typów danych i wbudowanych instrukcji językowych. Następnie bardziej złożone funkcje i klasy są implementowane w kategoriach prostszych. Niektóre z tych funkcji i klas implementują struktury danych, takie jak listy, stosy, kolejki itp. Te z kolei służą do reprezentowania bardziej specyficznych jednostek, takich jak kolejka procesów lub lista pracowników lub tablica skrótów tytułów książek .


1
Jeśli jest nieszczelny, to oczywiście nie jest to abstrakcja ... wystarczy, bądźmy szczerzy.
mlvljr

2
@mlvljr Komputery nie są problemami matematycznymi, niestety, więc musisz pozwolić na pewien poziom przecieków. Co więcej, fakt, że obliczenia są wykonywane na urządzeniu fizycznym, wiąże się z pewnymi ograniczeniami w zakresie problemów, które można modelować. Z technicznego punktu widzenia twierdzenia o niekompletności sugerują pewne rzeczy, których nie można wewnętrznie udowodnić na temat systemów matematycznych, więc nawet matematyka ma „nieszczelne abstrakcje”.
CodexArcanum

2
Zawsze możesz znaleźć sytuację, w której wycieknie abstrakcja. Nie ma czegoś takiego jak idealna abstrakcja. To po prostu kwestia tego, ile wycieknie i czy możesz z tym żyć.
Dima,

@CodexArcanum 1. Procedura pobierająca intmniej niż (MAX_INT_SIZE / 2-1) i zwracająca kolejną, która jest dwa razy większa: int f(int a) { return a*2; }2. „handler” z prototypem, void (*) (void)który ma zostać wywołany, gdy ... uhmm, należy go wywołać zgodnie z umowa dzwoniącego - obie reprezentują abstrakcje (1 - szczegółowe informacje na temat jej realizacji (które dostarczyliśmy, ale które nie będą dostępne dla tych, którzy nie mają dostępu do kodu źródłowego), 2 - dokładnie to, co dokładnie obsługi robi (zauważ jednak, że jest to znane osobie, która wyznaczyła osobę
zajmującą się

Ograniczenie na MAX_INT_SIZE nie jest wyjaśnione nigdzie w sygnaturze twojej metody. O ile nie używasz języka, który umożliwia programowanie oparte na umowie (np. Eiffel), jest to wyciek. Wymienienie ograniczeń w dokumentacji nie ma znaczenia, ponieważ dokumentacja znajduje się poza systemem. A co, jeśli zasilanie wyłączy się w trakcie operacji? Co zrobić, jeśli musisz przesyłać dane przez sieć i występuje opóźnienie? Żaden paradygmat programowania nie jest w stanie oderwać fizyczności sprzętu systemu.
CodexArcanum

1

Jeden ze sposobów, w jaki staram się to opisać ludziom, może nie być najlepszym sposobem

Rozważ program, który dodaje 2 + 2 i generuje 4

Rozważmy program, który dodaje dwie liczby wprowadzone przez użytkownika, x + y = z

Co jest bardziej przydatne i ogólne?


Na tym właśnie polegał mój komentarz do odpowiedzi Kate Gregory. ;) Interesującą rzeczą jest fakt, że mniej ogólny program może korzystać z bardziej ogólnego, zapewnienie użytkownikowi, który poprosił pierwszego z drugim, prawdopodobnie byłby przeciwny ...
mlvljr

1

Twierdziłbym, że abstrakcja to coś, co ukrywa niepotrzebne szczegóły. Jedną z najbardziej podstawowych jednostek abstrakcji jest procedura. Na przykład nie chcę się martwić, w jaki sposób zapisuję dane do bazy danych, gdy czytam te dane z pliku. Więc tworzę funkcję save_to_database.

Abstrakcje można również łączyć, tworząc większe abstrakcje. Na przykład funkcje można łączyć w klasę, klasy można łączyć w celu utworzenia programu, programy można łączyć w celu utworzenia systemu rozproszonego itp.


Wywołanie kodu save_to_databasenie powinno martwić się o to, jak dokładnie dane są zapisywane, o ile / ponieważ wybrałeś implementację, której potrzebujesz ! To znaczy, że i tak będzie miejsce na dostarczenie (abstrakcyjnego „względnego” do niektórych fragmentów kodu) szczegółów, to tylko kwestia rozsądnego wybrania go - zapewniając łatwiejszą „zmianę zdania” itp.
mlvljr,

1

Zawsze myślę o abstrakcji w programowaniu jako o ukrywaniu szczegółów i zapewnianiu uproszczonego interfejsu. Jest to główny powód, dla którego programiści mogą rozkładać monumentalne zadania na łatwe do opanowania elementy. Za pomocą abstrakcji można utworzyć rozwiązanie części problemu, w tym wszystkich drobiazgowych szczegółów, a następnie udostępnić prosty interfejs do korzystania z rozwiązania. Następnie możesz w efekcie „zapomnieć” o szczegółach. Jest to ważne, ponieważ nie można w żaden sposób zachować w pamięci wszystkich szczegółów super złożonego systemu. Nie oznacza to, że szczegóły pod abstrakcją nigdy nie będą musiały być ponownie przeglądane, ale na razie należy pamiętać tylko interfejs.

W programowaniu tym uproszczonym interfejsem może być dowolna zmienna (oddziela grupę bitów i zapewnia prostszy interfejs matematyczny) do funkcji (oddziela wszelkie przetwarzanie do pojedynczego wywołania linii) do klasy i nie tylko.

Ostatecznie głównym zadaniem programistów jest zwykle wyodrębnienie wszystkich szczegółów obliczeniowych i zapewnienie prostego interfejsu, takiego jak GUI, z którego może skorzystać ktoś, kto nie wie jednej rzeczy na temat działania komputerów.

Niektóre zalety abstrakcji to:

  • Pozwala na podzielenie dużego problemu na łatwe do opanowania części. Dodając rekordy osoby do bazy danych, nie musisz mieć problemów z wstawianiem i równoważeniem drzew indeksów w bazie danych. Ta praca mogła zostać wykonana w pewnym momencie, ale teraz została wyabstrahowana i nie musisz się już o nią martwić.

  • Pozwala wielu osobom dobrze współpracować przy projekcie. Nie chcę znać wszystkich szczegółów kodu mojego kolegi. Chcę tylko wiedzieć, jak go używać, co robi i jak dopasować go do mojej pracy (interfejsu).

  • Umożliwia osobom, które nie mają wymaganej wiedzy, wykonanie złożonego zadania. Moja mama może zaktualizować swojego facebooka, a osoby, które zna w całym kraju, mogą to zobaczyć. Bez abstrakcji niezwykle złożonego systemu na prosty interfejs sieciowy nie ma mowy, żeby mogła zacząć robić coś podobnego (podobnie jak ja).

Abstrakcja może jednak mieć odwrotny skutek, sprawiając, że rzeczy są mniej podatne na zarządzanie, jeśli są nadużywane. Po rozbiciu problemu na zbyt wiele małych kawałków liczba interfejsów, które musisz zapamiętać, wzrasta i trudniej jest zrozumieć, co się naprawdę dzieje. Jak większość rzeczy, trzeba znaleźć równowagę.


1

Dodatkowy poziom pośredni.

Nie chcesz się przejmować, czy obiekt, którego używasz, jest a, Catczy też Dog, dlatego przejrzyj tabelę funkcji wirtualnych, aby znaleźć właściwą makeNoise()funkcję.

Jestem pewien, że można to zastosować również do poziomów „niższych” i „wyższych” - pomyśl o kompilatorze szukającym właściwej instrukcji dla danego procesora lub Monadabstrakcji Haskella nad efektami obliczeniowymi przez wywołanie wszystkiego returni >>=.


1

Jest to coś, o czym tak naprawdę chciałem pisać na blogu przez dłuższy czas, ale nigdy tego nie dostałem. Na szczęście jestem zombie rep i jest nawet nagroda. Mój post okazał się dość długi , ale oto istota:

Abstrakcja w programowaniu polega na zrozumieniu istoty obiektu w danym kontekście.

[...]

Abstrakcja jest nie tylko mylona z uogólnieniem, ale także z enkapsulacją, ale są to dwie ortogonalne części ukrywania informacji: moduł usług decyduje, co chce pokazać, a moduł klienta decyduje, co chce zobaczyć. Kapsułkowanie to pierwsza część, a abstrakcja to druga. Tylko oba razem stanowią pełne ukrywanie informacji.

Mam nadzieję, że to pomaga.


+1, tak, wydaje się, że wielu z nas naprawdę bagno;) Mam nadzieję (w końcu) uzupełnić twoją odpowiedź własnymi punktami, aby wzbudzić większe zainteresowanie dyskusją.
mlvljr

0

Tutaj odpowiedź matematyczna:

Rezygnacja z programowania to udawanie, że nie przejmujesz się teraz szczegółami, podczas gdy w rzeczywistości robisz to i powinieneś dbać o nie cały czas. Zasadniczo to udaje.


1
+1, ale nie zawsze tak myślę (pomyśl o naprawdę niepotrzebnych szczegółach :)). Początkowe pytanie brzmi: „Czy chodzi o usuwanie szczegółów na zawsze, tymczasowe zapominanie o nich, a nawet wykorzystywanie ich w jakiś sposób, nie wiedząc o tym?”
mlvljr

1
Nie obchodzi mnie, ile fotonów trafiło dziś moich klientów.
flamingpenguin,

0

Dla mnie abstrakcja jest czymś, co nie istnieje „dosłownie”, jest czymś w rodzaju pomysłu. Jeśli wyrażasz to matematycznie, nie jest to już abstrakcja, ponieważ matematyka jest językiem wyrażającym to, co dzieje się w twoim mózgu, dzięki czemu może być zrozumiany przez mózg innej osoby, więc nie możesz uporządkować swoich pomysłów, ponieważ jeśli tak, to nie jest to pomysł już: musisz zrozumieć, jak działa mózg, aby wyrazić model ideowy.

Abstrakcja jest czymś, co pozwala ci interpretować rzeczywistość w coś, co może być od niej niezależne. Możesz streścić plażę i sen, ale plaża istnieje, ale sen nie istnieje. Ale można powiedzieć, że oba istnieją, ale to nieprawda.

Najtrudniejszą rzeczą w abstrakcji jest znalezienie sposobu, aby wyrazić to, aby inni ludzie mogli to zrozumieć, aby mógł stać się rzeczywistością. To najtrudniejsza praca i nie da się tego zrobić samodzielnie: musisz wynaleźć model względny, który działa na twoich pomysłach i może być zrozumiany przez kogoś innego.

Dla mnie abstrakcja w języku komputerowym powinna nazywać się „matematycznym” modelem, dotyczy ponownego wykorzystywania pomysłów, które można przekazać, i jest to ogromne ograniczenie w porównaniu z tym, co można osiągnąć abstrakcyjnie.

Mówiąc prosto, atomy są obok siebie, ale ich to nie obchodzi. Duży zestaw cząsteczek zorganizowanych w istotę ludzką może zrozumieć, że jest on obok kogoś, ale nie może zrozumieć, w jaki sposób atomy ustawiły się w jakiś wzór.

Jeden obiekt, którym rządzi koncepcja, nie może sam „zrozumieć”. Dlatego staramy się wierzyć w boga i dlatego trudno nam zrozumieć nasz mózg.

Czy mogę teraz dostać mój medal?


0

Interesujące pytanie. Nie znam jednej definicji abstrakcji, która jest uważana za autorytatywną, jeśli chodzi o programowanie. Chociaż inni ludzie podali linki do niektórych definicji z różnych gałęzi teorii CS lub matematyki; Lubię myśleć o tym w sposób podobny do „superwizji”, patrz http://en.wikipedia.org/wiki/Supervenience

Kiedy mówimy o abstrakcji w programowaniu, zasadniczo porównujemy dwa opisy systemu. Twój kod jest opisem programu. Abstrakcja twojego kodu byłaby również opisem tego programu, ale na „wyższym” poziomie. Oczywiście możesz mieć jeszcze wyższy poziom abstrakcji oryginalnej (np. Opis programu w architekturze systemowej wysokiego poziomu w porównaniu z opisem programu w jego szczegółowym projekcie).

Co sprawia, że ​​jeden opis jest „wyższy poziom” niż inny. Kluczem jest „wielokrotna realizacja” - twoja abstrakcja programu może być zrealizowana na wiele sposobów w wielu językach. Teraz możesz powiedzieć, że można stworzyć wiele projektów dla jednego programu - dwie osoby mogą stworzyć dwa różne projekty wysokiego poziomu, które dokładnie opisują program. Równoważność realizacji robi różnicę.

Porównując programy lub projekty, musisz to zrobić w sposób umożliwiający identyfikację kluczowych właściwości opisu na tym poziomie. Możesz przejść do skomplikowanych sposobów stwierdzenia, że ​​projekt jest równoważny z innym, ale najłatwiej jest to przemyśleć - czy pojedynczy program binarny może spełnić ograniczenia obu opisów?

Co sprawia, że ​​jeden poziom opisu jest wyższy niż drugi? Powiedzmy, że mamy jeden poziom opisu A (np. Dokumenty projektowe) i inny poziom opisu B (np. Kod źródłowy). A jest na wyższym poziomie niż B, ponieważ jeśli A1 i A2 to dwa równoważne opisy na poziomie A, wówczas realizacje tych opisów, B1 i B2 również muszą być równoważne na poziomie B. Jednak odwrotność niekoniecznie musi być prawdziwa .

Więc jeśli nie mogę stworzyć jednego programu binarnego, który spełnia dwa odrębne dokumenty projektowe (tzn. Ograniczenia tych projektów byłyby ze sobą sprzeczne), kod źródłowy, który implementuje te projekty, musi być inny. Ale z drugiej strony, jeśli wezmę dwa zestawy kodu źródłowego, których nie da się skompilować do tego samego programu binarnego, nadal może się zdarzyć, że oba pliki binarne wynikające z kompilacji tych dwóch zestawów kodu źródłowego będą miały ten sam projekt dokument. Tak więc dokument projektowy jest „abstrakcją” kodu źródłowego.


0

Abstrakcje programistyczne to abstrakcje wykonane przez kogoś na elemencie programowym. Powiedzmy, że wiesz, jak zbudować menu z jego elementami i rzeczami. Potem ktoś zobaczył ten fragment kodu i pomyślał: hej, który mógłby być przydatny w innych strukturach podobnych do wynajmujących, i zdefiniował Wzorzec Projektowania Komponentów za pomocą abstrakcji pierwszego fragmentu kodu.

Zorientowane obiektowo wzorce projektowe są całkiem dobrym przykładem tego, czym jest abstrakcja, i nie mam na myśli prawdziwej implementacji, ale sposób, w jaki powinniśmy podejść do rozwiązania.

Podsumowując, abstrakcja programowania jest podejściem, które pozwala nam zrozumieć problem, jest sposobem na uzyskanie czegoś, ale nie jest prawdziwą rzeczą

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.