ETO Efektywne tworzenie oprogramowania
Transkrypt
ETO Efektywne tworzenie oprogramowania
ETO Efektywne tworzenie oprogramowania 1. Wprowadzenie — Cykl życia oprogramowania Plan 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Wstęp — cykl życia Projektowanie za pomocą kontraktów Zbieranie wymagań Projekty z firmy InsERT; różne metodologie tworzenia orogramowania Rozwijanie oprogramowania sterowane testami Iteracyjne tworzenie oprogramowania - eXtreme Programming (XP) Projektowanie sterowane odpowiedzialnościami Wzorce przypisywania odpowiedzialności Modelowanie zachowania – przypadki użycia Dziedziczenie i refaktoryzacja Projektowanie interfejsu użytkownika Zarządzanie projektem Architektura oprogramowania Punkty funkcyjne - metryki oprogramowania Prezentacja projektów Tworzenie oprogramowania Naiwna perspektywa:kodowanie Specyfikacja Ale ... program – Skąd bierze się specyfikacja? – Skąd wiadomo, że specyfikacja odpowiada potrzebom użytkownika? – Jak podejmujemy decyzję o strukturze oprogramownia? – Skąd wiadomo, że oprogramowanie jest zgodne ze specyfikacją? – Skąd wiadomo, że oprogramowanie będzie zawsze działało poprawnie? – Co robić jeśli użytkownik zmieni potrzeby? – Jak dzielić zadania w zespole? Tworzenie oprogramowania • Praca zespołowa “dobre programowanie” nie wystarcza + komunikacja • Systemy programistyczne muszą się rozwijać lub „padają” zmiana jest normą, a nie wyjątkiem Czynności dotyczące tworzenia oprogramowania Zbieranie wymagań Określa potrzeby użytkownika Analiza Modeluje i specyfikuje wymagania (“co”) Modeluje i specyfikuje wymagania (“jak”) Konstrukcja rozwiązania w oprogramowaniu Walidacja rozwiązania pod względem wymagań Naprawa błędów i adoptowanie rozwiązania do nowych wymagań Projektowanie Implementacja Testowanie Pielęgnacja P.S.: to są występujące czynności, a nie fazy występujące sekwencyjnie! Klasyczny cykl życia oprogramowania Klasyczny cykl życia zbieranie oprogramowania mo- wymagań deluje tworzenie oprogramowania jako przejście krok po kroku między różnymi fazami tworzenia oprogramownaia. Analiza projektowanie Implementacja Testowanie Model kaskadowy „waterfall” jest nierealistyczny: • Zbyt szybko należy zamrozić wymagania • Zbyt późno wykonuje się walidację Pielęgnacja Problemy z cyklem życia oprogramowania 1. “Rzeczywiste projekty rzadko są tworzone według takiego modelu. Iteracja występuje zawsze i powoduje problemy” 3. “Często jest trudno klientowi jawnie określić wszystkie wymagania. Klasyczny cykl życia wymaga tego i trudno mu akomodować naturalne wątpliwości na początku” 5. “Klient musi być cierpliwy. Działająca wersja jest dostępna na końcu czasu przeznaczonego na wytworzenie oprogramowania.” — Pressman Iteracyjne wytwarzanie W praktyce, wytwarzanie jest zawsze iteracyjne, wszystkie czynności „postępują” równolegle. Zbieranie Wymagań Pielęgnacja przez iteracje Analiza Testowanie oparte na wymaganiach Testowanie Testowanie w czasie implementacji Walidacja przez prototypowanie Implementacja Projektowanie Projektowanie przez refaktoryzację Iteracyjne i przyrostowe tworzenie Planuj iterowanie analizy, projektowania i implementacji. Na pewno nie będzie o.k. za pierwszym razem, a więc integruj, wykonuj walidację i testuj tak często jak to możliwe. Iteracyjne i przyrostowe tworzenie Planuj tworzenie systemu przyrostowo (na przykład: prototypy). Jeśli możliwe, miej zawsze działającą wersję systemu, nawet gdy większość funkcjonalności nie jest jeszcze zaimplementowana. Integruj nową funkcjonalność tak szybko jak to możliwe. Wykonuj walidację kolejnej wersji ze względu na wymagania użytkownika. The Unified Process Inception Elaboration Construction Transition Requirements Analysis Design Implementation Test Iter. #1 Iter. #2 ... ... ... ... ... ... Jak planować liczbę iteracji? Jak zadecydować, że to już koniec? Iter. Iter. #n-1 #n Spiralny cykl życia według Boehma Planowanie = określenie celów, alternatyw i ograniczeń początkowe wymagania skompletowanie Analiza ryzyka =Analiza alternatyw i identyfikacja/ rozwiązywanie ryzyka Ryzyko = coś co opóźnia projekt lub zwiększa jego koszt Decyzja: kontynuować czy nie pierwszy prototyp alfa demo ewaluacja przez klienta = ocenawyników „inżyniera” inżynieria = wytwarzanie następnego evolving system poziomu produktu Zbieranie wymagań Wymagania użytkownika są często wyrażane nieformalnie: cechy scenariusze użycia Chociaż wymagania mogą być zapisane, jednak mogą być niekompletne, niejednoznaczne, a nawet niepoprawne. Zmieniające się wymagania Wymagania będą się zmieniać! nieadekwatnie wyrażone mogą się zmienić w czasie tworzenia projektu Walidacja jest konieczna przez cały czas cyklu życia oprogramowania, a nie tylko gdy zostanie dostarczony finalny produkt! wbuduj stały feedback do planu projektu planuj zmiany wcześnie prototypuj (np. interfejs użytkownika UI) pomaga w wyjaśnianiu wymagań Analiza wymagań i specyfikacja Analiza to proces specyfikowania co system będzie robił. Intencja – doprowadzenie do klarownego zrozumienia czego dotyczy system. Wynikiem analizy jest dokument specyfikacji. Czy specyfikacja wymagań odpowiada aktualnym potrzebom uż ytkownika? Analiza zorientowana obiektowo Wynikiem analizy zorientowanej obiektowo są modele systemu, które opisują: • klasy obiektów, które istnieją w systemie odpowiedzialności tych klas • związki między tymi klasami • przypadki użycia i scenariusze opisujące: operacje, które mogą być tworzone przez system dopuszczalne sekwencje tych operacji Prototypowanie (I) Prototyp jest oprogramowaniem wytwarzanym w celu testowania, badania lub walidacji hipotez, np., aby zredukować ryzyko. Prototyp badawczy, zwany również „throwaway prototype”, ma na celu przeprowadzenie walidacji wymagań lub zbadanie wyboru projektu. UI prototyp — walidacja wymagań użytkownika szybki prototyp — walidacja wymagań funkcjonalnych eksperymentalny prototyp — walidacja technicznej wykonalności Prototypowanie (II) Prototyp ewolucyjny ma na celu krokową ewaluację do produktu końcowego. iteracyjnie “rosnąca” aplikacja; w tym czasie jej przeprojektowanie i refaktoryzacja First do it, then do it right, then do it fast. Projektowanie Projektowanie to proces specyfikowania jak zostanie zrealizowane, za pomocą komponentów oprogra-mowania, zachowanie specyfikowanego systemu. Wynikiem jest architektura i dokumentacja szcze-gółowego projektu. Projektowanie obiektowo zorientowane dostarcza modele, które opisują: jak są implementowane operacje systemu przez współpracujące obiekty jak odwołują się do siebie klasy i jak są powiązane dziedziczeniem atrybuty i operacje związane z klasami Projektowanie jest procesem iteracyjnym przebiegającym równolegle z implementacją! Conway’s Law “Organizations that design systems are constrained to produce designs that are copies of the communication structures of these organizations” Implementacja i testowanie Implementacja jest czynnością programistycznego konstruowania rozwiązania wymagań użytkownika. Testowanie to proces walidacji, czy rozwiązanie odpowiada potrzebom użytkownika. Wynikim implementacji i testowania jest w pełni udokumentowane i ocenione rozwiązanie. Projektowanie, implementacja i testowanie Projektowanie, implementacja i testowanie są czynnościami iteracyjnymi Implementacja nie “implementuje projektu”, lecz raczej dokument projektowy dokumentuje implementację! • Testy systemu odnoszą się do specyfikacji wymagań • Testowanie i implementacja idą ręka w rękę Idealnie, jeśli specyfikacja przypadków testowych poprzedza projektowanie i implementację Pielęgnacja Pielęgnacja to proces zmian systemu po jego zainstalowaniu. Pielęgnacja korygująca: identyfikowanie i poprawianie defektów Pielęgnacja adaptacyjna: adaptująca istniejące rozwiązanie do nowej platformy Pielęgnacja ulepszająca: implementująca nowe wymagania Czynności dotyczące pielęgnacji “Pielęgnacja” zawiera: • Zarządzanie konfiguracją i wersjami • Re-inżynierię (przeprojektowanie i refaktoryzację) • Uaktualnianie analizy, projektu i dokumentacji użytkownika Powtarzają ce się, automatyczne testy umoż liwiają ewolucję i refaktoryzację Co jest najtrudniejszą częścią programowania? • • • • • • • • • Zrozumienie wymagań Projektowanie Testowanie Debugging Tworzenie struktur danych i algorytmy Projektowanie interfejsu użytkownika Optymalizacja Czytanie kodu Wymuszenie standardu kodowania Jak można uprościć programowanie? • Rzeczywiste programy zmieniają się! • Tworzenie oprogramowania jest przyrostowe • Projektowanie jest iteracyjne Projektowanie zorientowane obiektowo • Zidentyfikować minimalne wymagania • Uczynić wymagania tetstowalnymi • Zidentyfikować obiekty i ich powinności (odpowiedzialności) • Implementować i testować obiekty • Zrefaktoryzować, aby uprościć projekt • Iteracje! Projektowanie za pomocą kontraktu • Sformalizować kontrakt klient/serwer jako zobowiązania • Niezmiennik (inwariant) klasy — sformalizować ważne stany • Pre- and post-conditions dla wszystkich usług publicznych wyjaśnić powinności uprościć projekt uprościć debugging Projektowanie sterowane powinnościami • Obiekty są odpowiedzialne za pielęgnowanie informacji i dostarczanie usług • Dobry projekt wykazuje się: dużą spójnością operacji i danych wewnątrz klasy niskim powiązaniem (sprzężeniem) między klasami i podsystemami • Każda metoda powinna tworzyć jedno, dobrze zdefiniowane zadanie. • Wysoki poziom abstrakcji – pisz do interfejsu, nie do implementacji Extreme Programming • Kluczowe praktyki: Prosty projekt — Nigdy nie przewiduj funkcjonalności, którą możesz “need later” Wytwarzanie sterowane testami — Implementuj tylko to co testujesz! Refaktoryzacja — Agresywnie upraszczaj swój projekt, gdy rozwija się Programowanie w parach — Popraw produktywność programując w parach Testowanie • • • • • Formalizuj wymagania Wiedz kiedy już skończyłeś Uprość debugging Umożliwiaj wprowadzanie zmian Dokumentuj użycie Przykre zapachy kodu • • • • • • • Zdublowany kod Długie metody Duże klasy Publiczne zmienne instancyjne Brak komentarzy Bezużyteczne komentarze Nieczytelny kod Refaktoryzacja • “Refactoring is the process of rewriting a computer program or other material to improve its structure or readability, while explicitly keeping its meaning or behavior.” (wikipedia.org) • Powszechne operacje refaktoryzacji: Zmiana nazwy metod, zmiennych i klas Rozdzielenie powinności (odpowiedzialności) Wyciąganie na zewnątrz metod pomocniczych Przesuwanie metod w górę lub w dół hierarchii Wyciąganie (ekstrakcja) klas Narzędzia programistyczne • Znaj swoje narzędzia! System kontroli wersji — e.g., cvs Narzędzia tworzące — np. ant, make Ramy testujące — np. Junit Debuggers — np. jdb Profilers — np. java–prof. Generatory dokumentacji — np. javadoc 2. Projektowanie za pomocą kontraktu Niezmienniki klasy • Niezmiennik klasy jest wyrażeniem, które przedstawia poprawne (ważne) stany obiektów tej klasy: musi być spełniony przez każdy konstruktor każdą metodę publiczną — zakładamy, że zachodzi, gdy metoda startuje — musi z powrotem ustalić, gdy się skończyło jej działanie • Instancje stosu muszą spełniać następujący inwariant (niezmiennik) : size >= 0 Programowanie za pomocą kontraktu • Każdy ADT (abstract data type) jest tak zaprojektowany, aby oferować określone usługi przy zachodzeniu określonych warunków. • ADT ustala kontrakt ze swoimi klientami przez połączenie warunku początkowego (precondition) i warunku końcowego (postcondition) dla każdej operacji O, co oznacza: “If you promise to call O with the precondition satisfied, then I, in return, promise to deliver a final state in which the postcondition is satisfied.” Konsekwencja: • Jeśli warunek początkowy nie zachodzi, to od ADT nie wymaga się dostarczenia czegokolwiek! Warunki początkowe i końcowe • Warunek początkowy wiąże klienta: on definiuje czego ADT wymaga przy wywołaniu, aby operacja była legalna; może obejmować stan początkowy i argumenty. • Warunek końcowy natomiast wiąże dostawcę: definiuje warunki, jakie ADT spełnia przy powrocie; może tylko uwzględniać stany początkowe i końcowe, argumenty i wynik Korzyści i zobowiązania • Kontrakt dostarcza korzyści i zobowiązań obu: klientowi i dostawcy: Warunki początkowe i końcowe dla stosu Nasze stosy powinny dostarczać poniższy kontrakt: Asercje Asercja jest wyrażeniem boolean, które powinno być true w pewnym punkcie. Asercje mają podstawowe zastosowania: 1. Pomagają zapisać poprawne sformalizowane niezmienniki, warunki początkowe i końcowe 2. Pomoc w dokumentowaniu — specyfikują kontrakt 3. Pomoc w tolerancji wad oprogramowania — odkrywanie i obsługa awarii w czasie działania Testowanie niezmienników Każda klasa ma swój własny niezmiennik: Sprawdzanie warunków wstępnych Sprawdź warunek wstępny, aby poinformować klientów, gdy złamią kontrakt. Kiedy należy sprawdzać warunek wstępny metod? Zawsze sprawdzaj warunek wstępny, wyrzucając wyjątki, jeśli nie jest spełniony. Sprawdzanie warunku końcowego Sprawdzaj warunki końcowe i niezmienniki, aby wiedzieć kiedy łamiesz kontrakt. Kiedy należy sprawdzać warunki końcowe? Zawsze gdy implementacja nie jest prosta.