Różnorodność struktur programów

Z Otwarta edukacja
Wersja z dnia 20:28, 26 cze 2017 autorstwa Admin (dyskusja | edycje) (Utworzono nową stronę "== Wszystko płynie …. == Dwa i pół tysiąca lat temu grecki filozof [https://pl.wikipedia.org/wiki/Heraklit Heraklit] opisywał przy pomocy metafory rzeki ciągle...")
(różn.) ← poprzednia wersja | przejdź do aktualnej wersji (różn.) | następna wersja → (różn.)
Przejdź do nawigacji Przejdź do wyszukiwania

Wszystko płynie ….

Dwa i pół tysiąca lat temu grecki filozof Heraklit opisywał przy pomocy metafory rzeki ciągle zmieniający się świat. Wszystko płynie i „nie można wejść dwa razy do tej samej wody”. Także czas odmierzany zegarem komputera płynie nieustannie. Czy jednak metafora rzeki pasuje do opisu działania komputera? Próba odpowiedzi na to pytanie pozwala lepiej zrozumieć strukturę programów komputerowych.

Przepływy w komputerze

Działanie programu jest napędzane zegarem komputera, który nigdy się nie zatrzymuje (chyba, że wskutek awarii lub wyłączenia zasilania). Nie mamy możliwości wpływania na ten proces. Raz uruchomiony program działa bez naszej ingerencji a czasem nawet wiedzy – deterministycznie i automatycznie.

W rytm zegara następują w programach dwa rodzaje przepływów: przepływ danych i przepływ sterowania.

Upraszczając nieco problem można rzec, że przepływ sterowania wiąże się z wykonywaniem przez komputer kolejnych instrukcji programu, a przepływ danych z wykonywanymi przez ten program działaniami:

komputer → sterowanie → dane

Czyli komputer wykonuje instrukcje, a te instrukcje powodują zmiany stanu (pamięci) komputera. Nic nie stoi na przeszkodzie, aby taki sam stan mógł pojawiać się wielokrotnie. W odniesieniu do świata maszyn Heraklit nie miał więc racji. Jednokierunkowość zmian w czasie jest jedną z różnic między człowiekiem a maszyną.

Drugą istotną różnicą jest determinizm. Przepływ danych i sterowania odbywa się w sposób automatyczny. Po uruchomieniu programu komputer samodzielnie (automatycznie) wykonuje kolejne jego instrukcje. Można z góry przewidzieć kolejność wykonywania działań (na tym przecież polega programowanie maszyn). Człowiek tymczasem przed każdym działaniem podejmuje świadomą decyzję.

Te dwa zagadnienia wyglądają paradoksalnie:

1. Istnieje pozorna sprzeczność między trwałością a przemijaniem. Komputer może bez końca wracać do stanu początkowego (trwałość), a jednak każdy program zaczyna się i kończy (przemijanie).

2. W przypadku większości programów następuje interakcja z otoczeniem. Jeśli program wydrukował raport na drukarce, to nie może już tego cofnąć. Nie ma powrotu do stanu w którym kartka była czysta! Jak to pogodzić z tezą o możliwości powrotu do stanu początkowego?

3. Z kolei interakcja między komputerami i ludźmi (lub ludźmi za pośrednictwem komputerów) wiąże się z brakiem determinizmu, gdy tymczasem komputery działają deterministycznie (automatycznie).

Aby wyjaśnić te paradoksy, musimy dobrze rozumieć na czym polega przepływ sterowania, co to jest stan komputera oraz jak wygląda automatyzm działania w przypadku interakcji z otoczeniem.

1. Przepływ sterowania. Co to jest sterowanie w komputerze? Człowiek myśli sekwencyjnie (po kolei) i tak tworzy programy. Każe komputerowi wykonywać kolejne instrukcje programu. Wskazanie na aktualnie wykonywaną instrukcję nazywa się potocznie sterowaniem. Każdy program kiedyś się zaczyna i zazwyczaj kiedyś się kończy. Początek to przejście sterowania do pierwszej instrukcji. Koniec – to przejście do instrukcji zakończenia (stop). Jeśli w programie pojawi się instrukcja warunkowa (if) – sterowanie może zmieniać się zależnie od sprawdzanego warunku. W programie mogą też występować pętle – a więc powrót do wcześniej wykonywanych instrukcji. W pętli następuje powtarzanie bloku tych samych instrukcji dopóki nie wystąpią warunki zakończenia pętli. Programy, które nigdy się nie zatrzymują (jakaś pętla nigdy się nie kończy) zazwyczaj uważa się za błędne.

2. Pojęcie stanu. Programy działają na zmiennych – czyli odczytują i zmieniają stan pamięci komputera. Stan komputera – rozumiany jako zawartość pamięci (łącznie z zapamiętanym sterowaniem) może być identyczny w różnych momentach (przynajmniej w zakresie istotnym dla programu). Skutkiem działania programu jest przejście systemu komputerowego od jednego stanu (początkowego dla programu) do drugiego (końcowego dla tego programu). Kolejne kroki tego „przechodzenia” wiążą się z wykonywaniem kolejnych instrukcji (przepływ sterowania). Ten sam program lub jego fragment może być uruchamiany wielokrotnie i zawsze będzie działał tak samo o ile uzyska takie same dane.

3. Interakcja z otoczeniem. Nie da się cofnąć operacji drukowania kartki. Tak – ale stan kartki nie wyznacza stanu komputera, tylko otoczenia w którym on funkcjonuje. Powyższy opis sterowania i stanu (pamięci) dotyczył świata komputerów, a nie świata w którym komputer działa!

4. Automatyzm i determinizm. Gdy dane do komputera wprowadza człowiek, komputer nie ma wpływu na to co odczytuje. Jednak programista musiał przewidzieć różne możliwości i komputer nie może znaleźć się wskutek odczytania danych w innym stanie, niż to wynika z jego konstrukcji (działania programu). Indeterminizm dotyczy wyłącznie świata zewnętrznego. Interakcja z programem nie może zmieniać zasad działania ustalonych przez programistę! To odróżnienie jest ważne i obowiązuje zawsze – nawet w przypadku systemów sterujących różnymi urządzeniami – gdy komputer odczytuje informacje na temat zewnętrznych skutków generowanych sygnałów.


Sterowanie Stan (dane)
Maszyna Automatyzm / determinizm Trwałość – możliwość powrotu do stanu początkowego
Człowiek Wolna wola / indeterminizm Jednokierunkowe zmiany w czasie
Interakcja Sposób reakcji na dowolne zmiany otoczenia nie jest swobodny ale zdeterminowany strukturą programu (zdefiniowany przez programistę). Trwałe zmiany dotyczą otoczenia, a nie wnętrza komputera.

Przepływ danych i sterowania w różnych rodzajach programów

Powyższe aspekty (sterowanie, dane, interakcja) wyczerpują w całości zagadnienie przepływów w programach. Wiele idei, jakie powstały w dziedzinie tworzenia oprogramowania to realizacja różnych pomysłów na to jak sobie radzić z przepływami w tych trzech aspektach.

A oto przegląd różnego rodzaju interakcji dla różnych typów programów.


Sterowanie Stan (dane)
Konsola Program interpretera wykonuje instrukcje pojedynczo (podawane przez operatora)
Program wsadowy Program uruchamiany dla przetworzenia danych – zazwyczaj bez dodatkowych interakcji. Program wczytuje dane, przetwarza je i zapisuje wyniki.
Potoki i gniazda Program obecny w pamięci (na przykład fragment systemu operacyjnego) – komunikuje się najczęściej przez tak zwane „gniazda”. Podobny do programów wsadowych, ale przetwarza dane przesłane przez inne programy i przekazuje im wyniki.
Obiekty Funkcje (metody) obiektów wywoływane przez inne obiekty/programy. Działanie funkcji zazwyczaj ogranicza się do zmian w obrębie obiektu (zmian własności obiektu).
Zdarzenia Program uruchamiany w reakcji na sygnały świadczące o zajściu jakiegoś zdarzenia. Może to być interakcja z użytkownikiem, lub inne zdarzenie.
Wyjątki Przerwanie bieżącego wątku (sekwencji sterowania) wskutek nadzwyczajnych okoliczności. Przejście do miejsca w którym przewidziano obsługę wyjątku. Jeśli nie przewidziano – wyjątek przekazywany wyżej – do programu/procedury w której aaninisjowano wątek (na przykład uruchomiono procedurę).
Obiekty rozproszone, programy wielowarstwowe i interfejsy Obiekty lub programy uruchamiane na tym samym lub innym komputerze mogą komunikować się ze sobą poprzez interfejsy. Każdy program działa autonomicznie w swoim środowisku, zmiany na zewnątrz tego środowiska zleca innym programom.


Najlepszym objaśnieniem do powyższej tabelki jest rozdział przygotowywanego podręcznika programowania w Pythonie zatytułowany „Przepływ danych i sterowania[1]"