Rozdział III Programowanie obiektowe i strukturalne, przygotowanie funkcjonalnych aplikacji, analiza złożoności projektu, optymalizacja kodu

/Paweł Bensel/

Programowanie polega na zapisie rozwiązania określonego problemu w języku zrozumiałym dla komputera. Rozwiązywanym zadaniem może być proste sumowanie kolejnych liczb, ale może ono dotyczyć również skomplikowanych algorytmów obliczeniowych czy przetwarzających dane użytkowników.

Programowanie pozwala na przetwarzanie danych w określony przez programistę sposób – może ono dotyczyć zarówno wyświetlania ich na ekranie, formatowania wydruku czy przeprowadzenia obliczeń i zapisywania danych do bazy danych w celu ich późniejszego wykorzystania.

Wybór sposobu programowania zależny jest od rozwiązywanych problemów. Do prostych, niepowtarzalnych zadań można wykorzystać proste programowanie przy użyciu funkcji; bardziej złożone zadania dotyczące przetwarzania danych najczęściej wykorzystują programowanie obiektowe, które dzięki swoim cechom takim jak dziedziczenie czy polimorfizm pozwalają na szybsze i wygodniejsze tworzenie aplikacji.

III.1. Programowanie strukturalne

Programowanie strukturalne zakłada tworzenie programów jako zestawu funkcji, których kolejność wykonania kontrolowana jest poprzez instrukcje warunkowe oraz pętle. Funkcje te definiowane są przez programistów w celu zwrócenia określonego wyniku działania na parametrach wejściowych lub wykonania pewnego działania.

Programowanie strukturalne w przeciwieństwie do programowania obiektowego trudniej odwzorowuje rzeczywistość, gdyż bardziej koncentruje się na algorytmach przetwarzania danych, a nie na strukturach i ich metodach.

III.2. Programowanie obiektowe

Najbardziej rozpowszechnionym paradygmatem (wzorcem) programowania jest programowanie obiektowe, gdzie wykonywany program składa się z obiektów komunikujących się między sobą w przeciwieństwie do programowania strukturalnego gdzie program składa się z sekwencyjnie wykonywanych funkcji.

Programowanie obiektowe pozwala na lepsze odwzorowanie rzeczywistości w języku programowania, pozwala na lepszą organizację kodu oraz jego wielokrotne wykorzystanie, dzięki czemu oprogramowanie powstaje szybciej, a co za tym idzie kosztuje mniej.

Każdy obiekt w programowaniu podobnie jak w rzeczywistości posiada pewne cechy(właściwości), które go charakteryzują oraz zachowania(metody), które służą do jego przetwarzania, np.

Obiektem może być kwadrat, jego własnością jest długość boków, a metodami funkcje zwracające pole powierzchni oraz obwód.

Aby w języku programowania stworzyć obiekt, w pierwszym kroku należy zdefiniować jego strukturę - w tym celu tworzymy tzw. Klasę opisującą własności oraz funkcje a następnie tworzymy konkretny obiekt danej klasy.

Ogólny zapis definicji klasy i stworzenia obiektu wygląda w sposób następujący:

Przykład:

Class KwadratKlasa { //deklaracja klasy o nazwie KwadratKlasa int dlugosc_boku; //deklaracja właściwości o nazwie dlugosc_bok u function przypisz_dlugosc_boku(int bok) //deklaracja funkcji przypisz_dlugosc_boku służąca do przypisania obiektowi właściwości dlugosc_boku { dlugosc_boku=bok; //instrukcja przypisania właściwości dlugosc_boku zmiennej bok będącej parametrem funkcji } function pole() //deklaracja funkcji pole zwracającej pole powierzchni kwadratu o zadeklarowanej długości boku { return dlugosc_boku* dlugosc_boku; } function obwod()//deklaracja funkcji obwod zwracającej obwód kwadratu o zadeklarowanej długości boku { return 4* dlugosc_boku; } } kwadrat = new KwadratKlasa; //utworzenie obiektu o nazwie kwadrat klasy KwadratKlasa kwadrat.przypisz_dlugosc_boku(4); //uruchomienie funkcji przypisz_dlugosc_boku z parametrem 4 print(‘Pole kwadratu wynosi ’, kwadrat.pole()); //Wypisanie wartości funkcji pole dla obiektu kwadrat print(‘Obwód kwadratu wynosi’, kwadrat.pole());//Wypisanie wartości funkcji obwód dla obiektu kwadrat

III. 2.1 Programowanie obiektowe charakteryzuje się następującymi cechami:

Hermetyzacja – to mechanizm ukrywania danych składowych obiektu (zarówno metod jak i właściwości) przed innymi klasami w ten sposób, aby były one dostępne tylko metodom wewnętrznym danej klasy. Takie blokowanie dostępu pozwala łatwiej kontrolować przetwarzane dane – np. udostępniane właściwości mogą być zapisywane i przetwarzane tylko przez wewnętrzne metody danej klasy, co pozwala na łatwiejszą kontrolę zarówno przetwarzania danych jak i również tworzenia kodu.

Ze względu na fakt, że komunikacja pomiędzy obiektami następuje tylko i wyłącznie poprzez metody danej klasy hermetyzacja pozwala m.in. na łatwiejszy podział prac przy dużych projektach programistycznych – definiując metody komunikacji między obiektami można rozdzielić implementacje poszczególnych klas pomiędzy programistów, którzy muszą przestrzegać ustalonych reguł komunikacji.

Zakresy dostępu do metod oraz właściwości obiektów mogą być zdefiniowane wraz z klasą przy użyciu słów kluczowych Public, private protected.

Metody i właściwości opisane jako public widoczne są publicznie, dla wszystkich innych obiektów, opisane jako protected będą dostępne dla obiektów należących do klas potomnych, opisane jako private dostępną są tylko dla danego obiektu.

Dziedziczenie – to mechanizm pozwalający na współdzielenie tworzonych funkcjonalności pomiędzy klasami (a więc również obiektami danych klas). Klasa dziedzicząca (zwana także pochodną lub potomną) może dziedziczyć po innej klasie (tzw. klasa bazowa) dzięki czemu oprócz swoich własnych właściwości i metod posiada również własności i metody klasy bazowej.

Dziedziczenie pozwala na wielokrotne wykorzystanie tworzonego kodu – tworząc oprogramowanie gdzie klasy wykonują podobne zadania można stworzyć uogólnione klasy ze wspólnymi metodami i własnościami, a następnie tworząc klasy pochodne można uszczegółowić funkcjonalności do konkretnych potrzeb np.

Projektując aplikację gdzie przetwarzane będą dane Klientów oraz pracowników można utworzyć klasę Osoba, która będzie zawierać wspólne własności takie jak imię, nazwisko, data urodzenia, PESEL, adres, numer telefonu oraz metody do zapisu i odczytu do bazy danych zapisz oraz czytaj.

Klasa Klient będzie dziedziczyć własności oraz metody po klasie osoba oraz zawierać specyficzne własności takie jak adres kontaktowy, nazwa firmy czy numer NIP. Klasa Pracownik będzie zawierać dodatkowe własności takie jak data zatrudnienia, wysokość pensji czy metody takie jak oblicz premię.

Taki podział na klasę bazową oraz klasy potomne pozwala na wykorzystanie tego samego kodu, dzięki czemu tworzone oprogramowanie powstaje szybciej, jest mniej podatne na błędy oraz łatwiejsze do testowania.

Polimorfizm - to mechanizm pozwalający na zmianę zachowania takich samych metod w zależności od obiektu, który je wywołuje.

Analizując poprzedni przykład polimorfizm umożliwia, aby metoda dziedziczona – zapisz do bazy inaczej działała, gdy zostanie wywołana przez obiekt klasy Klient oraz inaczej gdy wywołana zostanie przez obiekt klasy Pracownik – w pierwszym przypadku oprócz wspólnych danych imię, nazwisko, data urodzenia, PESEL, adres, numer telefonu zapisane zostaną dodatkowo adres kontaktowy, nazwa firmy oraz numer NIP, w drugim przypadku oprócz danych wspólnych dodatkowo zachowane zostaną dane typowe dla pracowników: data zatrudnienia, wysokość pensji

III. 2.2 Konstruktory i Destruktory

Programowanie obiektowe pozwala na stworzenie specjalnych metod które uruchamiane są w momencie utworzenia obiektu danej klasy (konstruktory) i w momencie usunięcia obiektu z pamięci (destruktory). Konstruktory pozwalają na przypisanie wstępnych (domyślnych) parametrów danego obiektu.

Deklaracja konstruktorów i destruktorów jest zależna od języka programowania – może to być funkcja, która nazywa się tak samo jak klasa, której nazwa jest określona w języku programowania lub której deklaracja jest poprzedzona wymaganym słowem np. (constructor).

Poprzedni rozdział Następny rozdział