Języki i metodyka oprogramowania
Transkrypt
Języki i metodyka oprogramowania
2011-02-22 Języki i metodyka oprogramowania Automatyka i Robotyka sem.2 (część III) Rok akademicki 2010/2011 Dr inż. Wojciech Koziński Projekt – produkty fazy Podstawowymi produktami fazy projektu są: Model projektowy składający się z pakietów, klas, ich interfejsów, ich relacji. Model alokacji poszczególnych modułów. Projekty podsystemów. Realizacje przypadków użycia – projekt, testy. Testy poszczególnych metod, klas. Uaktualniony słownik. JIMO cz. III 2010/2011 2 Implementacja - definicja Faza implementacji polega na utworzeniu kodu dla projektu sporządzonego w poprzedniej fazie. W terminologii wybranego sposobu implementacji (Java) jest utworzenie klas, interfejsów, pakietów oraz wygenerowanie plików typu *.class. (pakowanie – jar). Podstawowe produkty fazy implementacji: Model implementacyjny zbudowany przy użyciu języka Java. Model alokacji (deployment), gdzie poszczególne moduły zostaną fizycznie zainstalowane. Opis architektury systemu. Opis współdziałających modułów (bibliotek). JIMO cz. III 2010/2011 3 1 2011-02-22 Implementacja - czynności Podstawowe czynności implementacyjne. implementacja oprogramowania systemowego zgodnie z projektem, definicja modelu implementacyjnego, implementacja podsystemów, klas i interfejsów z testowaniem, integracja podsystemów. 4 JIMO cz. III 2010/2011 Implementacja – pytania do modelu Czy zrealizowany system odpowiada modelowi? Konieczność zapewnienia jednoznaczności między modelem projektowym i implementacyjnym. (dokumentacja producenta). Czy każda klasa nadal pełni tylko jedną rolę? To pytanie jest zawsze uzasadnione. Czy każda metoda pełni tylko jedną funkcję? Jak wyżej. Czy w implementacji nie zwiększono uzależnień między klasami? To mogło nastąpić na skutek nie zrozumienia idei projektu lub ograniczeń języka implementacji. Utrudni przyszłe modyfikacje. Zwielokrotnienie (duplikacja) funkcjonalności może być korzystna dla dalszego rozwoju. Czy wykorzystuje się istniejące zasoby? Nie wymyślać powtórnie koła! Czy zastosowano wzorce programowe? 5 JIMO cz. III 2010/2011 Relacja dwukierunkowa jeden-do-jednego Model na poziomie projektu Advertiser 1 1 Account Kod w języku Java public class Account { /* The owner field is initialized * during the constructor and * never modified. */ private Advertiser owner; public class Advertiser { /* The account field is initialized * in the constructor and never * modified. */ private Account account; public Advertiser() { account = new Account(this); } public Account getAccount() { return account; } } public Account(owner:Advertiser) { this.owner = owner; } public Advertiser getOwner() { return owner; } } JIMO cz. III 2010/2011 6 2 2011-02-22 Relacja dwukierunkowa jeden-do-wielu Model na poziomie projektu 1 Advertiser * Account Kod w języku Java public class Advertiser { public class Account { private Advertiser owner; private Set accounts; public void setOwner(Advertiser public Advertiser() { newOwner) { accounts = new if (owner != newOwner) { HashSet(); Advertiser old = owner; } owner = newOwner; if (newOwner != null) public void newOwner.addAccount(this); addAccount(Account a) { if (oldOwner != null) accounts.add(a); old.removeAccount(this); a.setOwner(this); } } } } public void removeAccount(Account a) { accounts.remove(a); a.setOwner(null); } 7 JIMO cz. III 2010/2011 } Relacja dwukierunkowa wielu-do-wielu Model na poziomie projektu Tournament * {ordered} * Player Kod w języku Java public class Tournament { private List players; public Tournament() { players = new ArrayList(); } public void addPlayer(Player p) { if (!players.contains(p)) { players.add(p); } public class Player { private List tournaments; public Player() { tournaments = new ArrayList(); } public void addTournament(Tournament t) { if (!tournaments.contains(t)) { p.addTournament(this); } } } tournaments.add(t); t.addPlayer(this); } } JIMO cz. III 2010/2011 8 Implementacja A – generacja kodu JIMO cz. III 2010/2011 9 3 2011-02-22 Implementacja A – generacja kodu (1) package cplx; public class Complex { private double re; private double im; public Complex () { } public Complex (double re) { } public Complex (double re, double im) { } public static Complex add2 (Complex a, Complex b) { return null; } public Complex add1 (Complex a) { return null; } } JIMO cz. III 2010/2011 10 Implementacja A – generacja kodu (2) package cplx; public class MyVector { private java.util.Vector<Complex> vec; public MyVector () { } public boolean addEl (Complex val) { return true; } } JIMO cz. III 2010/2011 11 Implementacja A – generacja kodu (3) package cplx; public class Polynomial { private int deg; private double coeff; private Complex zeroes; public Polynomial (int deg, double coeff) { } public Complex eval (Complex val) { return null; } public double eval (double val) { return 0.0; } public Complex roots (Polynomial p) { return null; } } JIMO cz. III 2010/2011 12 4 2011-02-22 Implementacja B – generacja kodu JIMO cz. III 2010/2011 13 Implementacja B – generacja kodu (1) package katedra; package katedra; public class Edukator { private String email; public String getEmail () { return email; } public void setEmail (String val) { this.email = val; } } public class Adiunkt extends Edukator { public Adiunkt (String email) { } } package katedra; public class Profesor extends Edukator { public Profesor (String email) { } } package katedra; public class Wykladowca extends Edukator { public Wykladowca (String email) { } } JIMO cz. III 2010/2011 14 Implementacja C – generacja kodu JIMO cz. III 2010/2011 15 5 2011-02-22 Implementacja C – generacja kodu (1) package sam; import java.util.ArrayList; public class Car { private Wheel mWheel; private Body mBody; private Engine mEngine; public Car () { } public Body getBody () { return mBody; } public void setBody (Body val) { this.mBody = val; } public Engine getEngine () { return mEngine; } public void setEngine (Engine val) { this.mEngine = val; } public Wheel getWheel () { return mWheel; } public void setWheel (Wheel val) { this.mWheel = val; } public void setWheel (ArrayList<Wheel> val) { this.mWheel = val; } } package sam; public class Wheel { public Wheel () { } } JIMO cz. III 2010/2011 16 Wzorce – motywacja i definicje (1) Motywacja wprowadzenia wzorców. Powtarzalność pewnych schematów myślowych – budowa oparta na zebranym doświadczeniu, a nie od początku. Elementy oprogramowania wspierają powtórne użycie kodu, a nie powtórne użycie wiedzy. Wzorce wspierają powtórne użycie projektu oraz kodu. Kompromisy projektowe oraz wiedza ekspercka są stracone. Doświadczeni programiści nie startują za każdym razem od zera lecz budują na swym doświadczeniu. Musi więc istnieć skuteczna koncepcja rozwiązania. Przekazanie koncepcji architektury jest kiepsko udokumentowane, jest ona zwykle „w głowie” projektanta. JIMO cz. III 2010/2011 17 Wzorce – motywacja i definicje (2) Ponieważ wzorce są projektami (a nie kodem) wielokrotnego użytku, są na wyższym stopniu abstrakcji, co czyni je trudnym do udokumentowania. Dokumentacja projektu ma trzy cele, które muszą być spełnione: Cel wzorca, Sposób użycia wzorca, Szczegółowy projekt wzorca. Powstają książki kucharskie projektów. Opisują one jedno wykorzystanie wzorca. Zwykle zastosowanie wzorca, w konkretnym przypadku nie było przewidziane przez tworzącego ten wzorzec. Koniecznym jest kompletne zrozumienie projektu i jego sposobu użycia. Wzorce budowane są w sposób szczególny, z uwagą na powtórne użycie. JIMO cz. III 2010/2011 18 6 2011-02-22 Wzorce - dokumentacja Dokumentacja wzorca. Motywacja (cel) wzorca. Warunki wstępne, konieczne, by było można użyć wzorca. Opis struktury programowej definiującej wzorzec. Lista uczestników (elementów) niezbędnych we wzorcu. Skutki użycia wzorca (korzystne i niekorzystne). Przykłady użycia wzorca. 19 JIMO cz. III 2010/2011 Wzorce – strony silne, strony słabe Silne strony: Dostarczenie pewnego ujednoliconego słownictwa. Kumulacja wiedzy eksperckiej i kompromisów projektowych. Pomoc w komunikacji między twórcami systemu. Łatwość utrzymania, Szkielet struktury do ewentualnych zmian. Słabe strony: Wzorce nie prowadzą do prostego ponownego użycia kodu. Wzorce są myląco proste. Łatwo próbować znaleźć nieodpowiedni wzorzec. Wzorce są uznane przez doświadczenie (praktykę), a nie testowanie. Brak metodologii. 20 JIMO cz. III 2010/2011 Wzorce - taksonomia Pattern Creational Pattern Structural Pattern Behavioral Pattern Command Mediator Adapter Bridge Observer Strategy Facade JIMO cz. III 2010/2011 Abstract Factory Builder Pattern Proxy 21 7 2011-02-22 Wzorce GoF (Gang of Four) lista (1) Kreacyjne (Creational) Fabryka abstrakcyjna, (Abstract Factory) Budowniczy (Builder) Fabryka (Factory Method) Prototyp (Prototype) Singleton (Singleton) Strukturalne (Structural) Adapter (Adapter) Most (Bridge) Kompozyt (Composite) Dekorator (Decorator) Fasada (Facade) Lekki (Flyweight) Zastępujący (Proxy) JIMO cz. III 2010/2011 22 Wzorce GoF (Gang of Four) lista (2) Zachowań (Behavioral) Łańcuch odpowiedzialności (Chain of Resposibility), Polecenie (Command) Interpreter (Interpreter) Iterator (Iterator) Pośrednik (Mediator) Memento (Memeneto) Obserwator (Observer) Stan (State) Strategia (Strategy) Metoda wzorcowa (TemplateMethod) Wizytator (Visitor) JIMO cz. III 2010/2011 23 Wzorce Kreacyjne – krótki opis (1) Fabryka abstrakcyjna, (Abstract Factory) Definiuje interfejs używany do tworzenia obiektów w sposób generyczny, bez specyfikowania konkretnej klasy. Budowniczy (Builder) Konstrukcja (budowa) złożonego obiektu jest odseparowana od jego reprezentacji, tak więc ten sam proces konstrukcji może utworzyć różne reprezentacje. Fabryka (Factory Method) Dostarcza interfejsu do zbudowania obiektu. Podklasy implementujące wzorzec Fabryki mogą decydować w czasie działania jakiego rodzaju obiekt utworzyć. JIMO cz. III 2010/2011 24 8 2011-02-22 Wzorce Kreacyjne – krótki opis (2 ) Prototyp (Prototype) Dostarcza interfejsu, z którego klient może uzyskać szczegóły niezbędne do zbudowania dokładnego duplikatu. Singleton (Singleton) Wzorzec gwarantujący, że powstanie tylko jeden taki obiekt i zapewniający globalny dostęp do tego obiektu wszystkim zainteresowanym klientom. JIMO cz. III 2010/2011 25 Wzorce Strukturalne – krótki opis (3) Adapter (Adapter) Dopasowuje interfejs klasy do interfejsu oczekiwanego przez klienta. Adapter eliminuje niekompatibilne interfejsy, umożliwiając współpracę klas. Most (Bridge) Dostarcza abstrakcyjnego mechanizmu, który pozwala specyficznym implementacjom na zmianę specyfiki zachowania. Kompozyt (Composite) Umożliwia klientom manipulowanie w jednorodny sposób obiektami, które zawieraja inne obiekty. JIMO cz. III 2010/2011 26 Wzorce Strukturalne – krótki opis (4) Dekorator (Decorator) Dynamicznie dołącza dodatkową funkcjonalność do obiektu. Dekorator dołącza nową funkcjonalność stanowiąc alternatywę dla tworzenia podklasy. Fasada (Fasade) Dostarcza nowe, o wyższym poziomie wejście do potencjalnie złożonego podsystemu, ułatwiając zadanie klientowi. Lekki (Flyweight) Współdzielenie (ang. sharing) zapewnia efektywne wspieranie znacznej liczby drobnych obiektów. Zastępujący (Proxy) Dostarcza obiekt zastępujący inny obiekt, który steruje dostępem do niego. JIMO cz. III 2010/2011 27 9 2011-02-22 Wzorce Zachowań– krótki opis (5) Łańcuch odpowiedzialności (Chain of Reponsibility) Więcej niż jeden obiekt otrzymuje szansę obsłużenia żądania. Pozwala to na odsprzężenie nadawcy i odbiorcy. Odbiorcy tworzą łańcuch i żądanie jest przekazywane wzdłuż łańcucha, aż zostanie obsłużone. Sterowanie (Command) Parametryzowanie różnych żądań klientów przez tworzenie z żądań obiektów. Można w ten sposób rejestrować żądania. Interpreter (Interpreter) Definiuje reprezentację gramatyki języka. Służy do interpretacji zdań utworzonych w tym języku. Iterator (Iterator) Dostarcza jednorodny mechanizm do przeglądu różnorodnych elementów kolekcji, bez ujawniania szczegółów dotarcia do elementu. JIMO cz. III 2010/2011 28 Wzorce Zachowań – krótki opis (6 ) Mediator (Mediator) Definiuje obiekt, który hermetyzuje komunikację między innymi obiektami. Wprowadza luźne powiązania między komunikującymi się obiektami i daje możliwość wpływania na ich interakcje. Memento (Memento) Wewnętrzny stan obiektu jest przechwycony i zapamiętany na zewnątrz, co pozwala na odtworzenie stanu obiektu. Hermetyzacja zostaje zachowana. Obserwator (Observer) Definiuje zależność jeden do wielu między obiektami. Gdy jeden obiekt zmienia stan, wszystkie pozostałe obiekty zostają powiadomione. Stan (State) Mechanizm pozwalający na zmianę zachowania się obiektu, gdy zmienił się jego wewnętrzny stan JIMO cz. III 2010/2011 29 Wzorce Zachowań– krótki opis (7 ) Strategia (Strategy) Rodzina algorytmów zostaje zahermetyzowana, tak że każdy może zostać użyty (jest wymienność) niezależnie od klienta. Metoda wzorcowa (Template Method) Definiuje szkielet algorytmu, które pewne kroki są realizowane przez podklasy. Bez zmiany struktury algorytmu, podklasy mogą zmienić pewne kroki algorytmu. Wizytator (Visitor) Wizytator reprezentuje operację, która jest wykonywana na elementach obiektów pewnej struktury. Można zdefiniować nową operację bez zmian w odwiedzanych klasach. JIMO cz. III 2010/2011 30 10 2011-02-22 Wzorzec – Mediator (1) Cel: Zbudowanie obiektu hermetyzującego zachowanie się (współdziałanie) zbioru obiektów. Mediator dostarcza luźnego (elastycznego) sprzężenia między obiektami, bez konieczności bezpośredniego sprzężenia. Motywacja: Projektowanie obiektowo zorientowane umożliwia dystrybucję czynności między obiekty składowe. Jednakże, może to prowadzić do skomplikowanych powiązań między obiektami. W najgorszym przypadku każdy obiekt musi wiedzieć o (lub mieć powiązanie z) każdym innym. Może to wpływać negatywnie na utrzymanie i ponowne użycie indywidualnych klas. Obiekt mediatora usuwa te problemy. W tym schemacie obiekty biorące udział połączone są przy pomocy centralnego mediatora tworzącego gwiazdopodobną strukturę. Mediator jest odpowiedzialny za sterowanie i koordynowanie interakcji grupy obiektów. JIMO cz. III 2010/2011 31 Wzorzec – Mediator (2) Stosowalność: Wzorzec mediatora zaleca się używać tam gdzie: Zbiór obiektów komunikuje się między sobą w dobrze zdefiniowany lecz skomplikowany sposób. Współzależności nie mają wyraźnej struktury i są trudne do zrozumienia. Powtórne użycie obiektów jest trudne ponieważ współpracują z wieloma innymi obiektami. Zachowanie się systemu jest realizowane przez dystrybucję funkcji do poszczególnych klas. Chcemy kształtować to zachowanie stosując jak najmniej dziedziczenia. JIMO cz. III 2010/2011 32 Wzorzec – Mediator (3) Diagram klas wzorca Mediator. JIMO cz. III 2010/2011 33 11 2011-02-22 Wzorzec – Mediator (4) Klasy uczestniczące: Mediator: (abstrakcyjny lub interfejs) obsługuje komunikację między obiektami – kolegami. KonkretnyMediator: opisuje jak mediator powinien koordynować interakcje między poszczególnymi kolegami. On zna i pamięta kolegów. Klasy kolegów: Każdy kolega zna obiekt mediatora. Komunikuje się z mediatorem by przesłać wiadomość do kolegi. JIMO cz. III 2010/2011 34 Wzorzec – Mediator (5) Współpraca: Obiekt mediatora otrzymuje wiadomości od kolegów i przekazuje je do innych (zgodnie z regułami). Konsekwencje: Wzorzec mediatora ma następujące zalety i wady: Ogranicza możliwość utworzenia podklasy mediatora (zmiana algorytmu przesyłania zmienia zachowanie systemu). Odsprzęga kolegów. Upraszcza protokóły obiektów z wielu do wielu na jeden do wielu. Pozwala na abstrakcję współpracy. Centralizuje sterowanie. Implementacja: Istotne zagadnienia przy implementacji wzorca: Opuszczenie klasy abstrakcyjnej (interfejsu) Mediatora, gdy występuje tu tylko jedna klasa mediatora. Komunikacja między kolegami i mediatorem. Obiekty kolegów muszą powiedzieć mediatorowi, że wydarzyło się coś ciekawego, co trzeba przekazać innym kolegom. To może być realizowane przez mechanizm zależności (wzorzec obserwatora) lub bez pośredni komunikat z obiektu. JIMO cz. III 2010/2011 35 Wzorzec – Mediator (6) Znane przykłady użycia wzorca: Biblioteki klas języków ET++ oraz THINK C używają obiektów „dyrektorów” w dialogach jako mediatorów pomiędzy widgetami. Smalltak/V używa tego wzorca jako podstawowego w architekturze aplikacji. Pokrewne wzorce: Fasada (Facade) rożni się do Mediatora tym, że tworzy abstrakcję podsystemów dla zbudowania łatwiejszego interfejsu. Protokół tam jest jednokierunkowy, podczas gdy w Mediatorze jest dwukierunkowy. Koledzy mogą komunikować się z Mediatorem przy pomocy wzorca Obserwatora. JIMO cz. III 2010/2011 36 12 2011-02-22 Wzorce - taksonomia Pattern Creational Pattern Structural Pattern Behavioral Pattern Command Mediator Adapter Bridge Observer Strategy Facade Composite Abstract Factory Builder Pattern JIMO cz. III 2010/2011 37 Wzorzec – Kompozyt (1) Cel: Zbudowanie obiektu składającego się z pojedynczych elementów lub z hierarchii elementów (struktura drzewiasta). Motywacja: Programiści tworzą skomplikowane, zmieniające się w czasie struktury. Większość z nich może być przedstawiona w postaci drzewa. Wzorzec Kompozyt (ang. Composite) umożliwia jednakowe ( w sposób zunifikowany) traktowanie wszystkich elementów, niezależnie czy jest to liść (ang. leaf) czy też kompozyt (składający się z głębszych struktur). JIMO cz. III 2010/2011 38 Wzorzec – Kompozyt (2) Stosowalność: Wzorzec kompozytu zaleca się używać tam gdzie: jest konieczne reprezentowanie hierarchii obiektów część – całość, klienci mają ignorować różnice między kompozytem obiektów a pojedynczym obiektem. Klienci mają jednakowo traktować wszystkie obiekty w strukturze kompozytu. JIMO cz. III 2010/2011 39 13 2011-02-22 Wzorzec – Kompozyt (3) Diagram klas wzorca Kompozyt. JIMO cz. III 2010/2011 40 Wzorzec – Kompozyt (4) Klasy uczestniczące: Komponent: (abstrakcyjny lub interfejs) definiuje operacje, które musi wykonywać każdy obiekt, który należy do kompozytu. Liść: Obiekt, który nie posiada relacji do innych obiektów zależnych od niego. Kompozyt: Obiekt, który zawiera inne obiekty. Obiekt ten, jak i obiekty od niego zależne muszą spełniać warunki opisane przez komponent. Klient: Wykorzystuje obiekt Komponent do realizacji metod. JIMO cz. III 2010/2011 41 Wzorzec – Kompozyt (5) Współpraca: Obiekt Kompozytu tworzy złożoną strukturę, której elementy mogą być traktowane w ten sam (zunifikowany sposób). Konsekwencje: Wzorzec Kompozytu ma następujące zalety i wady: Kompozyt występuje w podwójnej roli (jako liść – pojedynczy obiekt i jako złożona struktura - komponent). Upraszcza strukturę klienta, który widzi jeden interfejs. Elastyczna możliwość dodawania podobnych obiektów/struktur. Wymusza zbytnie uogólnienie interfejsów, przez co stają się one mniej czytelne i efektywne. Implementacja: Istotne zagadnienia przy implementacji wzorca: Kolejność komponentów jest nieokreślona. Czasami jest duża trudność w stosowaniu wzorca. W dużych komponentach występuje konieczność buforowania wyników pośrednich dla szybszej realizacji obliczeń. JIMO cz. III 2010/2011 42 14 2011-02-22 Wzorzec – Kompozyt (6) Znane przykłady użycia wzorca w języku Java: Wzorzec Kompozyt opisuje hierarchię klas JFrame, JPanel, JComponent w każdym oprogramowaniu z GUI. Klasy te są kontenerami, które mogą zawierać dowolna liczbę innych kontenerów. Każdy kontener może zawierać komponenty wizualne (liście), JLabel, JButton, które nie mogą mieć potomków. JIMO cz. III 2010/2011 43 15