Programowanie strukturalne
Struktura programu musi stanowić odzwierciedlenie struktury problemu. Metody konstruowania programu zmierzające do osiągnięcia takiej odpowiedniości struktur określa się nazwą programowanie strukturalne. Kluczowym zagadnieniem jest systematyczne użycie poziomów opisu (lub abstrakcji) w toku opracowywania programu. Program przedstawia się najpierw w postaci działań na bardzo wysokim (ogólnym) poziomie opisu, a następnie uszczegóławia. Równocześnie opracowuje się struktury danych.
Opracowanie zostaje zakończone gdy działania i sposoby reprezentacji danych mają postać i poziom szczegółowości, które można wyrazić w danym języku programowania.
Celem programowania strukturalnego jest rygorystyczna organizacja procesu projektowania i kodowania programu w dążeniu do zapobieżenia większości błędów.
Cechy programowania strukturalnego:
projektowanie zstępujące (metoda analityczna) lub wstępujące (syntetyczne)
projektowanie modułowe
kodowanie strukturalne
Projektowanie zstępujące polega na naszkicowaniu wszystkich funkcji programu, opisaniu najważniejszych struktur danych i procesów ich przetwarzania. Opis każdego modułu powinien zawierać opis danych testowych.
Programowanie strukturalne wymusza przemyślenie struktury programu, danych i trybu testowania oraz utworzenie niezbędnej dokumentacji.
Programowanie zstępujące pozwala na wczesne wykrycie błędów i nieścisłości.
Poznane typy konstrukcji programowych:
sekwencja,
rozgałęzienie,
pętla,
podprogram.
Omówione dotychczas instrukcje:
przypisania
wprowadzania danych,
wyprowadzania danych,
warunkowa, wyboru
iteracyjna WHILE, REPEAT, FOR
złożona,
procedury,
stanowią zbiór implementujący podstawowe konstrukcje, pozwalający zapisać każdy program jako strukturalny.
→ Są to tzw. D-struktury [Dijkstra].
→ D-struktury wystarczają do napisania każdego programu [Boehm, Jacopini].
Dowolny program nie jest D-strukturą jeżeli występuje w nim jeden z poniższych przypadków:
skok na zewnątrz pętli ,
skok do środka pętli,
skok do środka instrukcji warunkowej,
skok bezwarunkowy do dalszej części programu.
Przekształcenie dowolnej konstrukcji programowej na D-strukturę może wymagać nowych operacji, warunków i zmiennych.
Algorytm jest strukturalny jeżeli w wyniku kolejnych redukcji daje się przekształcić do jednego bloku. Redukcje wykonuje się w ten sposób, że wyszukuje się w nim podstawowe konstrukcje, które zastępuje się jednym blokiem. Wszystkie z tych konstrukcji algorytmu, które posiadają jedno wejście i jedno wyjście mogą zostać zastąpione jednym blokiem
Programowanie wykorzystujące ten zbiór instrukcji i omówione powyżej zasady jest nazywane programowaniem strukturalnym. Podstawową cechą jest składanie konstrukcji strukturalnych z konstrukcji prostych. Dotyczy to zarówno struktur danych jak i struktur sterowania.
Niestrukturalny i strukturalny algorytm wyszukiwania
liczby o podanej wartości w ciągu n liczb
Inżynieria oprogramowania obejmuje takie zagadnienia jak:
sposoby prowadzeni przedsięwzięć informatycznych,
techniki planowania, szacowania kosztów, harmonogramowania i monitorowania przedsięwzięć programistycznych,
metody analizy i projektowania systemów,
techniki zwiększania niezawodności oprogramowania,
sposoby testowania systemów i szacowania niezawodności,
sposoby przygotowywania dokumentacji technicznej i użytkowej,
procedury kontroli jakości,
metody redukcji kosztów konserwacji (usuwania błędów, modyfikacji i rozszerzeń),
techniki pracy zespołowej i czynniki psychologiczne wpływające na efektywność pracy.
Model Cyklu Życia Oprogramowania
Faza strategiczna
Jest to faza, w której rozważana jest i planowana produkcja nowego programu lecz nie została jeszcze podjęta ostateczna decyzja o rozpoczęciu prac.
Prowadzone są negocjacje z klientem i/lub firma bierze udział w przetargu.
W fazie strategicznej wykonywane są następujące czynności:
dokonanie serii rozmów (wywiadów) z przedstawicielami klienta,
określenie celów przedsięwzięcia z punktu widzenia klienta,
określenie zakresu oraz kontekstu przedsięwzięcia,
ogólne określenie wymagań, wykonanie zgrubnej analizy i projektu systemu,
propozycja kilku możliwych rozwiązań (sposobów realizacji systemu),
oszacowanie kosztów oprogramowania,
analiza rozwiązań,
prezentacja wyników fazy strategicznej przedstawicielom klienta oraz korekcja wyników na podstawie uzyskanych uwag,
określenie wstępnego harmonogramu przedsięwzięcia oraz struktury zespołu realizującego przedsięwzięcie,
określenie standardów zgodnie z którymi realizowane będzie przedsięwzięcie.
Przykłady celów przedsięwzięcia
Program podatkowy:
przyspieszenie obsługi klienta,
zmniejszenie ryzyka popełnienia błędów.
System informacji geograficznej
możliwość łatwego, dialogowego projektowania mapy,
możliwość łatwego i wygodnego przeglądania mapy.
W fazie strategicznej należy określić zakres przedsięwzięcia (jakie usługi klienta będzie realizował lub wspomagał projektowany system) oraz opisać kontekst systemu, czyli systemy zewnętrzne, z którymi współpracować będzie tworzony system. Jako system zewnętrzny traktuje się klasę użytkowników (czyli grupę ludzi wykorzystujących system w podobny sposób ), inny program lub sprzęt albo organizacje (działy firmy) wykorzystujące program.
W omawianej fazie należy podjąć szereg strategicznych decyzji dotyczących dalszego sposobu realizacji przedsięwzięcia. Decyzje te to między innymi:
wybór modelu, zgodnie z którym realizowane będzie przedsięwzięcie,
wybór technik stosowanych w fazach analizy projektowania,
wybór środowisk implementacji,
wybór narzędzi CASE,
określenia stopnia wykorzystania gotowych komponentów,
podjęcie decyzji o współpracy z innymi producentami i/lub zatrudnieniu ekspertów z zewnątrz.
Bardzo często rozważa się kilka możliwych rozwiązań, tj. sposobów realizacji przedsięwzięcia, uwzględniając przy tym istniejące ograniczenia, takie jak:
maksymalne nakłady jakie można ponieść na realizację przedsięwzięcia,
dostępny personel,
dostępne narzędzia,
ograniczenia czasowe.
Dla oszacowania kosztów oprogramowania stosuje się następujące techniki:
Modele algorytmiczne. Techniki te wymagają opisu danego przedsięwzięcia za pomocą szeregu atrybutów liczbowych lub opisowych. Odpowiedni algorytm daje następnie w wyniku spodziewany nakład pracy.
Ocena przez ekspertów.
Ocena przez analogię.
Prawo Parkinsona, które stwierdza, że przedsięwzięcia praktycznie zawsze są wykonywane przy założonych nakładach.
Wycena dla wygranej. Koszt oprogramowania szacowany jest na podstawie oceny możliwości klienta oraz przewidywanych działań konkurentów.
Szacowanie wstępujące. Realizację przedsięwzięcia dzieli się na mniejsze zadania, których koszt jest łatwiejszy do oszacowania.
Podstawowe rezultaty fazy strategicznej to:
udostępniany klientowi raport obejmujący:
definicję celów przedsięwzięcia,
opis zakresu przedsięwzięcia (jakie usługi system będzie realizował lu wspierał),
opis systemów zewnętrznych, z którymi system będzie współpracować (kontekst),
opis ogólny wymagań,
ogólny model systemu,
opis proponowanego rozwiązania,
oszacowanie kosztów,
wstępny harmonogram prac,
raport oceny rozwiązań, zawierający informacje o rozważanych rozwiązaniach oraz przyczynach wyboru jednego z nich,
opis wymaganych zasobów - pracownicy, oprogramowanie, sprzęt,
definicje standardów,
harmonogram fazy analizy.
Faza określania wymagań.
Celem tej fazy jest dokładne określenie wymagań klienta wobec tworzonego systemu. W fazie tej dokonywana jest więc zamiana celów klienta na konkretne wymagania zapewniające osiągnięcie tych celów.
Dobry opis wymagań powinien:
być kompletny oraz niesprzeczny,
opisywać zewnętrzne zachowanie systemu, a nie sposób jego realizacji,
obejmować ograniczenia przy jakich musi system pracować,
być łatwy w modyfikacji,
brać pod uwagę przyszłe możliwe zmiany wymagań wobec systemu,
opisywać zachowanie systemu w niepożądanych sytuacjach.
Trudność określenia wymagań wynika z następujących czynników:
Klient z reguły nie wie dokładnie w jaki sposób osiągnąć założone cele. Z drugiej strony cele te można osiągnąć na wiele sposobów.
Duże systemy są wykorzystywane przez wielu użytkowników - ich cele często są sprzeczne.
Zleceniodawcy, których głos w tej fazie jest decydujący, nie zawsze potrafią przewidzieć potrzeby rzeczywistych użytkowników systemu.
Wymagania wobec oprogramowania można podzielić na dwa zasadnicze rodzaje:
Wymagania funkcjonalne. Opisują one funkcje (czynności, operacje) wykonywane przez system.
Wymagania niefunkcjonalne. Opisują ograniczenia, przy zachowaniu których system powinien realizować swoje funkcje.
Wymagania powinny zostać zebrane w dokumencie - opisie wymagań. Powinien on być podstawą formalnego, szczegółowego kontraktu między klientem a producentem. Powinien obejmować następujące części:
Wprowadzenie - cel, zakres i kontekst systemu (wyniki fazy strategicznej, być może częściowo zmodyfikowane).
Opis ewolucji systemu - opis przewidywanych zmian wymagań wobec systemu.
Opis wymagań funkcjonalnych.
Opis wymagań niefunkcjonalnych.
Model systemu.
Słownik wyjaśniający terminy niejasne dla jednej ze stron.
Dokument ten może zostać uzupełniony o następujące dodatki:
Specyfikacja wymagań funkcjonalnych. (w sposób sformalizowany - może być niezrozumiała dla klienta)
Specyfikacja wymagań niefunkcjonalnych.
Wymagania sprzętowe.
Wymagania dotyczące bazy danych.
Indeks pomocny w wyszukiwaniu konkretnych informacji.
W fazie określania wymagań powinien powstać plan testów.
Wymagania funkcjonalne opisują funkcje (czynności, operacje) wykonywane przez system. W celu uściślenia wymagań i uniknięcia niejednoznaczności stosuje się stosuje się formularze do zapisu wymagań funkcjonalnych, np.
Nazwa funkcji |
Edycja dochodów podatnika |
Opis |
Funkcja pozwala edytować łączne dochody podatnika uzyskane w danym roku |
Dane wejściowe |
Informacje o dochodach podatnika uzyskanych z różnych źródeł: kwoty przychodów, koszty uzyskania przychodów oraz zapłaconych zaliczek na poczet podatku dochodowego. Informacje o dokumentach opisujących dochody z poszczególnych źródeł. |
Źródło danych wejściowych |
Dokumenty oraz informacje dostarczone przez podatnika |
Wynik |
|
Warunek wstępny |
Kwota dochodów = kwota przychodów - kwota kosztów |
Warunek końcowy |
Kwota dochodów = kwota przychodów - kwota kosztów |
Efekty uboczne |
Uaktualnienie podstawy opodatkowania |
Powód |
Funkcja pomaga przyspieszyć obsługę klientów oraz zmniejszyć ryzyko popełnienia błędów |
Ponieważ liczba wymagań funkcjonalnych może być bardzo duża stosowane są dwie metody ułatwiające zapanowanie nad dużą liczbą wymagań:
hierarchiczny zapis wymagań ( w formie tekstowej lub graficznej )
diagramy przypadków użycia
Specyfikacja
Specyfikacją nazywamy precyzyjne zdefiniowanie problemu, przedstawiające wszystkie cechy istotne dla jego rozwiązania. Powinna być dokonana pisemnie. Jest pierwszym etapem na drodze do formalizacji problemu, który z reguły jest źle określony.
Specyfikacja jest sporządzana na pewnym poziomie abstrakcji. Ułatwia to uświadomienie sobie struktury problemu i pozwala na początkowe abstrahowanie od szczegółów, które będą uwzględnione później.
Specyfikacji dokonujemy przy pomocy jakiegoś formalnego języka specyfikacji, który nie powinien zależeć od konstrukcji komputera. Specyfikacji można dokonać korzystając z narzędzi matematycznych np. teorii grafów lub teorii zbiorów, formalizmów graficznych wywodzących się z teorii automatów lub języków deklaratywnych np. PROLOG.
Dokumentacja
Potrzeba dokumentacji wynika z długotrwałości systemu oraz zmian osobowych.
Dokumentacja jest słabym punktem systemu
projektanci uważają ją za dodatkowe obciążenie nieistotne dla samego opracowania systemu;
najczęściej sporządza się ją po opracowaniu systemu co wymaga dodatkowych nakładów;
ludzie nie znają zasad techniki pisania dokumentacji.
Zasady pisania dokumentacji
na bieżąco, równolegle z procesem opracowywania systemu;
należy zacząć od opracowania planu strukturalnego zamierzanej dokumentacji. Wprowadzane zmiany rzutują na treść dokumentacji w różnych miejscach;
należy pomóc czytelnikowi: dobry styl, właściwa treść, ułatwianie w wyszukiwaniu informacji i streszczenie;
wybrać odpowiednią terminologię i konsekwentnie ją przestrzegać, skorowidze przedmiotowe.
Testowanie i uruchamianie programów
Opracowanie każdego programu o istotnym znaczeniu wymaga wyodrębnienia ważnego etapu obejmującego sprawdzenie poprawności działania i usuwanie stwierdzonych w nim błędów.
błędy sprzętowe
błędy programowe - oprogramowania systemowego
- oprogramowania użytkowego
Poprawność programu oznacza, że program dla dowolnych dopuszczalnych danych wejściowych da właściwe wyniki.
Formalne dowodzenie poprawności programów jest stosowane tylko w wyjątkowych przypadkach, gdyż jest żmudne i podatne na błędy wprowadzane przez ludzi.
Weryfikacja programu jest metodą analityczną, która dowodzi, że po każdej akcji spełniane są zawsze pewne warunki zwane asercjami. Warunki poprzedzające instrukcje nazywamy przesłankami P, zaś występujące po instrukcji - wnioskami Q.
Testowanie polega na wybraniu dozwolonych danych wejściowych (wartości początkowych), wykonaniu dla nich programu oraz porównaniu otrzymanych wyników ze znanymi już poprzednio wynikami poprawnymi. Empiryczne testowanie programu co najwyżej wykaże obecność błędów, nigdy nie zagwarantuje poprawności programu.
Testem nazywamy zestaw danych wejściowych potrzebnych do wykonania programu, łącznie z warunkami w których odbywa się testowanie. Określając test należy też określić spodziewany wynik.
Testujemy funkcje i stukturę programu (test ścieżek).
Testować program możemy na biurku lub z komputerem.
Testowanie za pomocą danych losowych nie gwarantuje sprawdzenia każdej ścieżki programu i jest trudne do oceny.
Należy opracować wykaz zmiennych i miejsc ich pojawiania się w programie (deklaracji, inicjalizacji, użycia i zmiany wartości), zmienna nie może po raz pierwszy wystąpić w instrukcji wyjścia, po prawej stronie wyrażenia, w warunku.
Testowanie krok po kroku wykonuje się dla specjalnie dobranych, prostych wartości zmiennych. Jest pracochłonne, zwłaszcza dla dłuższych programów. Najczęściej stosowane jest na etapie lokalizacji i usuwania błędów.
W Turbo Pascalu:
F4 Go to cursor
F7 Trace into
F8 Step over
Ctrl+F8 breakpoint
Testowanie ciągłe
Rodzaje testów i warunki testowania mogą być różne w zależności od celu testowania:
Testowanie diagnostyczne - dla lokalizacji błędów.
Testowanie odbiorcze - dla pokazania własności funkcjonalnych programu.
Testowanie weryfikujące program ma na celu pokazanie poprawności zachowania się programu w warunkach sztucznych.
Testowanie walidujące program ma na celu pokazanie poprawności zachowania się programu w warunkach naturalnych.
Testowanie certyfikujące program ma na celu pokazanie poprawności zachowania się programu dla testów standardowych.
Zanalizować przypadki skrajne i mogące powodować stany osobliwe (np. 30 luty).
Testowanie zacząć już na etapie analizy. Pisząc program pamiętać o jego uruchamianiu (odpowiednie punkty kontrolne itp.).
Dane testowe przygotować dla każdej drogi w programie, testować sytuacje normalne, krańcowe i wyjątkowe (błędne dane, awarie systemu).
Po każdej modyfikacji programu - powtórzyć testowanie.
Sztuka znajdowania i usuwania błędów nosi nazwę uruchamiania. Uruchamianie zajmuje często ponad 50% czasu poświęconego na napisanie programu.
Uruchamianie mylone jest często z testowaniem. Testowanie ma na celu sprawdzenie poprawności pracy programu. Gdy działa on źle - wtedy ma miejsce uruchamianie.
Rodzaje błędów:
Błędy w sformułowaniu zadania. Żądać opisu założeń programu (czasami użytkownik nie wie co chce).
Niewłaściwy algorytm (błędny lub nieefektywny).
Błędy podczas analizy:
przekroczenie zakresu danych
brak inicjalizacji
niewłaściwe indeksowanie pętli
błędy ogólne:
nieznajomość języka lub komputera,
zła kolejność instrukcji,
błędy syntaktyczne,
błędy wykonania (np. dzielenie przez 0),
Styl programowania
Konieczność przestrzegania reguł określonego stylu programowania (zasad pisania programów) wynika z dużej złożoności współczesnych programów i konieczności pracy zespołowej. Programowanie polega na pisaniu tekstów, które będą później czytane.
Zalecenia:
Zwróć uwagę na znaki, które łatwo pomylić: 0 i O, 1 i l itp.
Nazwy zmiennych i inne nadawać intuicyjne.
Dążyć do uzyskania przejrzystej struktury programu.
Używać komentarzy.
Stosować wcięcia dla ukazania struktury pętli.
Każdy arkusz powinien posiadać nagłówek (tytuł, autora, datę).
Należy zapisywać wszelkie uwagi krytyczne wynikłe w toku opracowywania programu oraz warianty odrzucone
Określenie
wymagań
Projektowanie
Implementacja
Testowanie
Konserwacja
Faza
strategiczna
Analiza
Instalacja
Dokumentacja