Jak nauczyliśmy maszyny liczyć i myśleć za nas? Część 23. Historia programowania obiektowego

W połowie lat 60. XX wieku w środowiskach informatyków zaczęła dojrzewać idea, że dane trzeba chronić. Postanowiono chować je w niedostępnych z zewnątrz „kapsułach”, gdzie jedynymi procedurami, które mogą na tych danych wykonywać określone działania, będą elementy owej „kapsuły”.

Publikacja: 12.05.2022 21:00

Jak nauczyliśmy maszyny liczyć i myśleć za nas? Część 23. Historia programowania obiektowego

Foto: Stock Adobe

We wcześniejszych odcinkach tej serii felietonów pisałem o różnych językach programowania. Przy okazji omawiania niektórych spośród tych języków pojawiało się stwierdzenie, że są to języki obiektowe. Nie było przy tym miejsca na wyjaśnienie, czym właściwie jest obiektowość i jaką drogę przebyła ta metoda myślenia o programach od ogólnej koncepcji do realizacji we współczesnych narzędziach programowania. Tę lukę wypełni dzisiejszy felieton.

Przy programowaniu komputerów możliwe są różne podejścia. Do dyspozycji jest wiele koncepcji, spośród których programista musi wybrać tę, do której chce się stosować. Z koncepcją taką wiąże się zawsze zbór spójnych zasad, wokół których organizowany jest tekst tworzonego programu. Ten zbiór zasad nazywany jest paradygmatem programowania. W tym felietonie będę opisywał paradygmat programowania obiektowego i jego historyczną ewolucję, ale muszę zacząć od tego, co było wcześniej, zanim ten paradygmat sformułowano.

Paradygmaty imperatywny i strukturalny

Pierwsze języki programowania, jakie stworzono po to, żeby proces stawiania zadań komputerowi uczynić łatwiejszym i wygodniejszym dla człowieka, ukierunkowane były głównie na specyfikację czynności, które komputer ma wykonać. Znajdowało to odbicie nawet w ich nazwach: FORTRAN, czyli tłumacz wzorów matematycznych, ALGOL, czyli język do zapisywania algorytmów – pisałem o nich w artykule „Pierwsze języki programowania” („Rzecz o Historii” z 31 grudnia 2021 r.). Ten paradygmat sformułowany na przełomie lat 50. i 60. XX wieku nazywamy obecnie paradygmatem imperatywnym. Program to był zestaw poleceń: zrób to, sprawdź tamto, wykonaj wielokrotnie itp. Taki sposób programowania pozwalał na szybkie uzyskanie programu o wymaganych cechach, był więc ceniony i chętnie używany. Jednak ten paradygmat miał istotne ograniczenie: programy tak pisane trudno było adaptować do nowych wymagań, a prawie każdy program po dłuższej eksploatacji wymaga pewnych zmian wynikających z ewolucji potrzeb użytkowników programu oraz ze zmienności otoczenia (choćby z przepisów prawnych).

Odpowiedzią był nowy paradygmat programowania strukturalnego. Zakładał on podzielenie programu na segmenty, z których każdy powinien mieć dokładnie zdefiniowany cel i zrozumiałą budowę. Taki sposób programowania bardzo porządkował działania programu, a w przypadku koniecznej modyfikacji wiadome było, co i gdzie należy zmienić. Był chętnie stosowany przez kilka dziesięcioleci, ale miał słaby punkt: wszystkie ładnie wydzielone segmenty operowały na wspólnych zasobach danych. Wprawdzie te dane mogły być przekazywane do segmentów przez specjalne mechanizmy parametrów formalnych i aktualnych, ale niestety „majstrowanie” na tych samych danych przez różne segmenty, pisane często przez oddzielnych programistów (bo duże programy tworzy się w dużych zespołach programistów), prowadziło czasem do trudno wykrywalnych błędów. Utarło się brzydkie powiedzenie, że często jeden programista „zapluwał” dane innemu programiście, który w efekcie nie wiedział, co się dzieje. To spostrzeżenie otworzyło drogę do omawianych w tym felietonie metod programowania obiektowego.

Paradygmat obiektowy

W połowie lat 60. XX wieku w środowiskach informatyków zaczęła dojrzewać idea, że dane trzeba chronić. Postanowiono chować je w niedostępnych z zewnątrz „kapsułach”, gdzie jedynymi procedurami, które mogą na tych danych wykonywać określone działania, będą elementy owej „kapsuły”. Wzorzec takiej kapsuły nosi nazwę klasy, a na podstawie tego wzorca można wytworzyć dowolnie dużo egzemplarzy konkretnych obiektów mających formę kopii owego wzorca (klasy), ale wypełnionych konkretnymi danymi. Całą pracę w programie wykonują obiekty (stąd nazwa „paradygmat obiektowy”), które mogą wzajemnie od siebie czegoś wymagać, wysyłając i odbierając komunikaty, ale wszelkie operacje na danych w środku kapsuły wykonują tylko procedury wbudowane w ściany tej kapsuły.

Ponieważ brzmi to może tajemniczo i zawile, posłużę się przykładem. Wyobraźmy sobie, że mamy dwie klasy: „krowa” i „rolnik”. Klasa „krowa” może wygenerować dużą liczbę konkretnych obiektów, którym można nadać indywidualne nazwy: Krasula, Czarna, Narowista itp. W każdym obiekcie zachodzą własne procesy: trawienie, wytwarzanie mleka, ewentualne choroby itp., ale nikt z zewnątrz tymi procesami nie steruje. Natomiast obiekt należący do klasy „rolnik” (np. Jan) może przesyłać do obiektów klasy „krowa” sygnały: nakarmić, napoić, wydoić itp. Skutki tych sygnałów wpływają na to, jakie procesy zachodzą wewnątrz obiektów klasy „krowa” (być może w każdym obiekcie inne), w następstwie czego obiekty tej klasy mogą wysyłać do obiektu klasy „rolnik” swoje sygnały: że głodne, że potrzebują wydojenia, że konieczne jest sprzątnięcie odchodów itp. Ale tylko elementy kapsuły obiektu Jan decydują o tym, jakie czynności zostaną wykonane.

Oczywiście paradygmat obiektowy ma całe mnóstwo dalszych atrybutów, m.in. takich jak dziedziczenie i polimorfizm, ale nie będę tu tego omawiał, bo ten artykuł nie ma nauczać technik programowania obiektowego, tylko ma opisywać historię powstania i rozwoju tego paradygmatu.

Zaczęli Norwegowie

Na podstawie licznych wcześniejszych felietonów z tego cyklu czytelnik mógł się dowiedzieć, że nowości w informatyce najczęściej rodziły się w USA. Tymczasem paradygmat obiektowy został stworzony przez Norwegów, Ole-Johana Dahla i Kristena Nygaarda, pracujących w Norweskim Centrum Obliczeniowym (Norsk Regnesentral). Po kilkuletniej pracy zaprezentowali oni w 1967 r. nowy język do symulacji komputerowych o nazwie Simula 67. Język jak język – używałem i nie byłem zachwycony. W dodatku pierwsze zastosowania zostały ukierunkowane na potrzeby norweskiej marynarki wojennej, były więc odległe od tego, czym sam się zajmowałem (modelowaniem funkcjonowania fragmentów mózgu). Dlatego Simuli 67 początkowo nie doceniłem.

Ale to właśnie w tym języku wprowadzono po raz pierwszy podstawowe pojęcia paradygmatu obiektowego. Do inspiracji Simulą przyznają się m.in. Bjarne Stroustrup (twórca języka C++) i James Gosling (twórca języka Java), obecnie najpopularniejszych języków obiektowych.

James Gosling, twórca języka Java. Inspiracją byli dla niego Norwegowie Dahl i Nygaard, którzy stwor

James Gosling, twórca języka Java. Inspiracją byli dla niego Norwegowie Dahl i Nygaard, którzy stworzyli paradygmat obiektowy Simula 67

ESTELLE GRUNBERG/FAIRFAX MEDIA/GETTY IMAGES

Nowości wnoszone przez język Simula docenili pracownicy bardzo zasłużonego dla rozwoju informatyki centrum badawczego firmy Xerox [Xerox Palo Alto Research Center]. W efekcie powstał język Smalltalk, rozwinięty przede wszystkim przez Alana Kaya z pomocą Dana Ingalsa oraz Adeli Goldberg. Język ten rozwijano i doskonalono, najpierw wewnętrznie w firmie Xerox, a po jego formalnym ogłoszeniu w 1980 r. w wielu ośrodkach naukowych na całym świecie. Był to język „do bólu” obiektowy, ponieważ wszystko w nim było klasą albo obiektem.

Do realizacji programów w Smalltalku jego twórcy wprowadzili pojęcie maszyny wirtualnej, obecnie wykorzystywane w wielu językach, zwłaszcza w Javie. W uproszczeniu mówiąc, idea maszyny wirtualnej polega na tym, że program napisany w określonym języku (w momencie wprowadzenia tej idei językiem tym był Smalltalk) nie jest tłumaczony przez translator aż do poziomu kodu binarnego komputera, który ma program wykonać, tylko do pewnej formy przejściowej nazywanej kodem bajtowym. Ten kod bajtowy steruje częścią programu translatora nazywaną maszyną wirtualną, a owa maszyna wirtualna, opierając się na kodzie bajtowym, porozumiewa się z elektronicznym procesorem komputera na różne sposoby, doprowadzając ostatecznie do wykonania wszystkich potrzebnych działań. Brzmi to trochę skomplikowanie, ale dobrze działa w praktyce, bo pozwala łączyć zalety translacji kompilacyjnej i interpretacyjnej. Nie rozwijam jednak dalej tego tematu od strony informatycznej, tylko odnotowuję historyczny fakt, że owa koncepcja maszyny wirtualnej narodziła się w Xerox właśnie wraz z powstaniem języka Smalltalk.

Języka Smalltalk mało kto dziś używa. Ja próbowałem kilka razy i raczej nie polubiłem. Ale aprobuję fakt, że w książce Ericha Gammy, Richarda Helma, Ralpha Johnsona oraz Johna Vlissidesa zatytułowanej „Inżynieria oprogramowania: Wzorce projektowe”, traktowanej jako biblia programistów, Smalltalkowi przyznaje się rolę języka pomnikowego.

Zalety programowania obiektowego docenili także twórcy języków programowania mających już ustaloną renomę, ale znacząco polepszających swoje właściwości dzięki dodaniu mechanizmów obiektowych. Na przykład z języka C, którego powstanie i rozwój opisywałem w artykule „Gwiazda wśród narzędzi programowania – język C” („Rzecz o Historii” z 28 stycznia 2022 r.), duński informatyk Bjarne Stroustrup wytworzył w roku 1979 język C++, czyli narzędzie łączące zalety programowania strukturalnego i obiektowego. Pierwsza wersja tego języka nazywała się „C with classes” i działała z translatorem Cpre, ale w 1983 r. zmieniono nazwę na C++ i stworzono nowy translator Cfront. Obecnie w użyciu jest 11. wersja języka C++ z 2017 r., ale możliwe są też dalsze modyfikacje.

Powstały też obiektowe wersje innych języków programowania.

Języki budowane od początku jako obiektowe

Pierwszym językiem budowanym od podstaw jako obiektowy był stworzony w 1986 r. przez Bertranda Meyera język Eiffel. Był udostępniany bezpłatnie przez organizację Nonprofit International Consortium for Eiffel (NICE). Został wyparty przez bardziej obecnie popularny język Java, który zainicjowali w 1991 r. James Gosling, Mike Sheridan i Patrick Naughton. Język ten był od początku oparty na metodologii obiektowej. Popularność zyskał po wprowadzeniu przez firmę Sun Microsystems w 1996 r. pierwszej publicznej implementacji tego języka, który zaczął być stosowany nie tylko w komputerach, ale także w smartfonach. Javę wykorzystują przeglądarki internetowe. Język i jego translatory stale podlegają modyfikacjom i modernizacjom, w 2006 r. zdefiniowane zostały nowe wersje: Java EE, Java ME i Java SE.

Gdy w 1991 r. powstała Java, został też zainicjowany obiektowy język Python. Jego twórcą był Guido van Rossum. Język ten bardzo się rozwija i zyskuje wciąż zwolenników, ponieważ jest udostępniany za darmo na zasadzie Open Source. Najnowsze wersje tego języka pochodzą ze stycznia br.

Autor jest profesorem AGH w Krakowie

We wcześniejszych odcinkach tej serii felietonów pisałem o różnych językach programowania. Przy okazji omawiania niektórych spośród tych języków pojawiało się stwierdzenie, że są to języki obiektowe. Nie było przy tym miejsca na wyjaśnienie, czym właściwie jest obiektowość i jaką drogę przebyła ta metoda myślenia o programach od ogólnej koncepcji do realizacji we współczesnych narzędziach programowania. Tę lukę wypełni dzisiejszy felieton.

Pozostało 95% artykułu
2 / 3
artykułów
Czytaj dalej. Kup teraz
Historia
Stanisław Ulam. Ojciec chrzestny bomby termojądrowej, który pracował z Oppenheimerem
Historia
Nie tylko Barents. Słynni holenderscy żeglarze i ich odkrycia
Historia
Jezus – największa zagadka Biblii
Historia
„A więc Bóg nie istnieje”. Dlaczego Kazimierz Łyszczyński został skazany na śmierć
Historia
Tadeusz Sendzimir: polski Edison metalurgii