Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Programowanie komponentowe jesień-zima 2013 Wykład 2 Interakcja komponentów Rodzaje apliakcji w Visual Studio dr inż. Wojciech Bieniecki Instytut Nauk.

Podobne prezentacje


Prezentacja na temat: "Programowanie komponentowe jesień-zima 2013 Wykład 2 Interakcja komponentów Rodzaje apliakcji w Visual Studio dr inż. Wojciech Bieniecki Instytut Nauk."— Zapis prezentacji:

1 Programowanie komponentowe jesień-zima 2013 Wykład 2 Interakcja komponentów Rodzaje apliakcji w Visual Studio dr inż. Wojciech Bieniecki Instytut Nauk Ekonomicznych i Informatyki 1

2 Zależność komponentów Komponenty są zależne – aby działać, muszą współpracować. Istotą programowania komponentów jest ich konfiguracja i łączenie bez konieczności modyfikacji kodu źródłowego. Konfiguracja polega na definiowaniu zależności pomiędzy nimi i ich rozwiązywaniu. Przykład: Samochód zawiera silnik. zawiera Samochód dla klienta tworzy zamkniętą funkcjonalną całość i jest gotowy do jazdy. Klient kupując auto chce mieć wpływ na niektóre podzespoły, np. rodzaj silnika. Pogodzenie tych dwóch wymagań może być trudne i jest istotą problemu definiowania zależności pomiędzy komponentami.

3 Rozwiązywanie zależności Klient tworzy instancję Samochodu, która z kolei tworzy zależną od niej instancję Silnika1.6. Hermetyzacja procesu tworzenia komponentu zależnego Samochód decyduje o wyborze poszczególnych komponentów, natomiast Klient nie ma na to żadnego wpływu. W zamian otrzymuje prawidłowo zmontowany pojazd. OK. – w przypadku projektowania obiektowego. ŹLE – w przypadkup projektowania komponentowego. Rozwiązanie tworzy silną zależność pomiędzy Samochodem i Silnikiem, na którą Klient nie ma wpływu: nie może zmienić rodzaju Silnika bez modyfikacji klasy Samochód. Zależność ta definiuje nie tylko kontrakt dotyczący cech Silnika (czyli interfejs), ale narzuca też instancję konkretnego modelu Silnika. public class Samochod { private Silnik silnik = null; public Samochod() { this.silnik = new Silnik1_6(); } public class Samochod { private Silnik silnik = null; public Samochod() { this.silnik = new Silnik1_6(); }

4 Tradycyjne rozwiązywanie zależności 4 KLIENT 1. Utwórz komponent A KOMPONENT A KOMPONENT B 2. A zależy od B 3. utwórz komponent B 4. Zmontuj A i B 1. Klient żąda utworzenia instancji komponentu A 2. Komponent A posiada zależność od komponentu B, dlatego nie może być utworzony przed nim 3. Komponent A musi utworzyć instancję komponentu B 4. Komponent A musi oraz zmontować je razem 5. Następuje przekazanie zmontowanego zestawu klientowi W efekcie klient otrzymuje żądaną instancję komponentu A, jednak nie ma żadnego wpływu na sposób montażu A i B ani na wybór zależnego komponentu B.

5 Osłabienie zależności 5 Aby osłabić rodzaj zależności pomiędzy komponentami, można wprowadzić pomiędzy nie interfejs. W tym przypadku komponent Samochód nie zależy bezpośrednio od klasy Silnik1_6, ale od implementowanego przez nią interfejsu Silnik. W praktyce jednak musi także utworzyć instancję klasy Silnik1_6, zatem po wprowadzeniu interfejsu Samochód nadal w pewien sposób będzie zależał od konkretnej klasy Silnik1_6, a ponadto powstanie zależność od interfejsu, który ta klasa implementuje. Takie rozwiązanie nadal nie spełnia swojego zadania.

6 Odwrócone rozwiązywanie zależności 6 Odwrócone sterowanie (ang. Inversion of Control, IOC) polega na zmianie odpowiedzialności poszczególnych komponentów. Komponenty stają się pasywne – nie tworzą samodzielnie innych komponentów, tylko je odbierają od innego obiektu. W ten sposób komponenty tracą wpływ na sposób zarządzania ich instancjami. Dominującą rolę przejmuje nowy uczestnik interakcji – kontener IoC Rola IoC polega na zarządzaniu tworzeniem wszystkich komponentów oraz dostarczaniu gotowych instancji klientowi. Komponenty, chcąc rozwiązać swoje zależności, zlecają tę czynność kontenerowi, który zna wszystkie komponenty (przechowuje ich konfigurację w tzw. rejestrze) i może dostarczyć ich instancje. Rola klienta nie ulega zmianie – ale ma on większą możliwość konfiguracji i wpływu na zachowanie komponentów Zamiast bezpośrednich powiązań pomiędzy implementacjami komponentów, zależą one od kontenera, którego konfiguracja decyduje o utworzeniu ich instancji.

7 Inverse of Control 7 KLIENT 1. Utwórz komponent A KONTENER ZARZĄDZAJĄCY 2. Znajdź komponent A Komponent A Komponent B 4. Znajdź komponent B 3. A zależy od B 5. Zwróć komponent A zmontowany z B

8 8 Inverse of Control Klient odwołuje się do Kontenera w celu uzyskania zmontowanej instancji Samochodu. Zależności wewnętrzne są ukryte przed Klientem. Jedyne zależności, jakie mogą wystąpić w warstwie komponentów, to żądane lub oferowane przez nie interfejsy, dzięki czemu komponenty stają się bardziej deklaratywne. Rozwiązywaniem zależności i tworzeniem instancji komponentów zajmuje się jedynie kontener, który jest także dla klienta rodzajem interfejsu umożliwiającego dostęp do komponentów.

9 IoC - podsumowanie 9 W IoC komponenty nigdy nie sterują same sobą. API komponentu staje się pasywne. Przesunięcie odpowiedzialności za tworzenie i konfigurację komponentów z nich samych na kontener Usunięcie mocnych powiązać z warstwy komponentów. Jedynym sposobem komunikacji pomiędzy nimi jest deklarowanie wymaganych zależności, które są rozwiązywane i spełniane przez kontener. Posiada on pełną władzę nad komponentami, także w zakresie tworzenia ich instancji oraz zarządzania cyklem ich życia.

10 Maszyna wirtualna.NET 10 CLR - Common Language Runtime środowisko uruchomieniowe dla platformy.NET. Jest to maszyna wirtualna, która wykonuje kod wyrażony w Common Intermediate Language (CIL). Common Intermediate Language (CIL) - język najniższego poziomu dla.NET odczytywalny przez człowieka. Jest to odpowiednik asemblera jako języka pośredniego dla typowych języków wysokiego poziomu (CLI) wyrażający kod w C#, Visual Basic.NET, Managed C++, F#, J# lub inym z 40 języków. CIL jest tłumaczony bezpośrednio na kod bajtowy. CIL jest wykonywany za pomocą maszyny wirtualnej..assembly HelloWorld.class auto ansi HelloWorldApp {.method public hidebysig static void Main() cil managed {.entrypoint.maxstack 1 ldstr "Hello world." call void [mscorlib]System.Console::WriteLine(string) ret }.assembly HelloWorld.class auto ansi HelloWorldApp {.method public hidebysig static void Main() cil managed {.entrypoint.maxstack 1 ldstr "Hello world." call void [mscorlib]System.Console::WriteLine(string) ret }

11 Common Language Infrastructure 11 CLI to część platformy Microsoft.NET Framework, wykorzystywana jako środowisko uruchomieniowe oprogramowania stworzonego w różnych językach. Specyfikacja CLI opisuje: Wspólny zestaw typów danych (Common Type System) – zbiór typów danych, które są obsługiwane przez wszystkie kompatybilne języki. Metadane – informacje o strukturze definiowanych klas, interfejsów i innych typów, pozwalające na ich wykorzystanie w różnych językach i narzędziach. CLS (Common Language Specification) – określa zbiór reguł, do których wszystkie języki zgodne z CLI muszą się stosować, aby były kompatybilne z pozostałymi językami. Wirtualny system wykonawczy (Virtual Execution System) – wczytuje i wykonuje programy kompatybilne z CLI.

12 C++ w Visual Studio 12

13 Trzy sposoby tworzenia programu 13 Korzystanie z Windows Forms – sposób tworzenia aplikacji oparty na formularzach, która jest uruchamiana w środowisku CLR tworzenie GUI budując projekt metodą przeciągnij i upuść bez konieczności pisania dużej ilości kodu. Jest to najszybszy i najprostszy sposób budowania aplikacji, która działa w środowisku CLR, które pogarsza nieznacznie wydajność. Korzystanie z API Windows jako podstawowego interfejsu systemu operacyjnego Windows do komunikacji między systemem operacyjnym i aplikacją Należy napisać cały kod dla wszystkich elementów GUI (pracochłonny) Korzystanie z biblioteki Microsoft Foundation Classes (MFC), która zawiera klasy C++ obejmujące API Windows korzystanie z gotowych kontrolek GUI, korzystając z metody wizualnego programowania. Należy jednak napisać sporo kodu do obsługi interakcji z użytkownikiem. Umożliwia to dużą kontrolę nad tworzonym GUI, większą niż w Windows Forms. Program działa natywnie na PC, więc nieznacznie ma lepszą wydajność.

14 Program w Windows API 14 #include int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK); return 0; } #include int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK); return 0; } Najprostszy program w języku C generujący MessageBox – okienko z przyciskiem OK. HINSTANCE hInstance Uchwyt do instacji wykonywanego programu (pliku.exe w pamięci) HINSTANCE hPrevInstance Zawsze NULL w przypadku programów Win32 LPSTR lpCmdLine Lista argumentów z jakimi program został wykonany. Nie zawiera nazwy programu int nCmdShow Wartość całkowita, która może zostać przesłana do funkcji ShowWindow(). later.

15 Program w Windows API - Okienko 15 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ WNDCLASSEX wc; HWND hwnd; MSG Msg; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)){ MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ WNDCLASSEX wc; HWND hwnd; MSG Msg; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)){ MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } Krok 1 – tworzymy i rejestrujemy tzw klasę okna

16 Program w Windows API - Okienko 16 hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL); if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL); if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); Krok 2 – tworzymy Okno programu

17 Program w Windows API - Okienko 17 while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } Krok 3 – implementujemy i uruchamiamy pętlę komunikatów (tzw. procedurę okna) LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg){ case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg){ case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }

18 Program w MFC 18 MFC – Microsoft Foundation Classes Zalety Opakowanie dla WinAPI, zestaw klas C++ umożliwiających wygodniejsze pisanie programów MFC od pewnego czasu jest wypierane przez.NET, ale jest rozwiązaniem przydatnym jeśli nie chcemy używać.NET Microsoft zapowiada stopniową integrację MFC z.NET MFC nie jest dostępne w wersjach Express produktów Visual Studio Znaczne uproszczenie tworzenia typowych aplikacji w stosunku do WinAPI Wygodniejsze zastosowanie w technologiach obiektowych (m. in. dziedziczenie z jednej klasy) Organizacja współpracy między warstwą dokumentu a warstwą prezentacji Organizacja wymiany danych z okienkami Dodatkowe klasy związane m. in. z kolekcjami i serializacją Wizardy wspierające tworzenie aplikacji

19 Program w MFC 19 Wady Rzeczy które nie zostały przewidziane przez twórców biblioteki często bardzo trudno zaimplementować. Konieczne jest modyfikowanie fragmentów generowanych przez wizardy, co często powoduje niekompatybilności i trudności w dalszej pracy z wizardami Zmiana rodzaju projektu po wygenerowaniu przez wizard jest praktycznie niemożliwa Architektura dokument-widok jest niezbyt przejrzysta, niektóre rozwiązania są niejasne Konieczność dołączania bibliotek

20 Program w MFC 20 Koncepcje: Prawie wszystkie elementy interfejsu dziedziczą po CWnd Możliwe są trzy zasadnicze rodzaje aplikacji: Dialog, SDI, MDI Interakcja między elementami jest oparta na standardowych komunikatach Windows, Obsługa dodawana przez wizardy Podejście obiektowe. Język CPP. Nazwy klas zaczynają się od C. Prawie wszystkie dziedziczą po CObject Podstawowe klasy aplikacji użytkownika dziedziczą po klasach MFC Duża część implementacji polega na pisaniu własnych implementacji funkcji zdefiniowanych w klasach bazowych

21 Rodzaje głównych okien Windows 21 Interfejs typu jednodokumentowy SDI (the single-document interface) Można otworzyć tylko jeden dokument - jeśli jest otwarty jeden dokument, nie można otworzyć drugiego okna

22 Rodzaje głównych okien Windows 22 Interfejs typu wielodokumentowy MDI (the multiple-document interface) Dokument – reprezentacja pliku w pamięci programu. Widok – okno prezentujace dokument. W programie można jednocześnie wiele dokumentów. Można generować różne widoki tego samego dokumentu.

23 Rodzaje głównych okien Windows 23 Interfejs typu Dialog Aplikacja składa się z jednego okna, na którym są okna sterujące (kontrolki). Dialog może być: Niemodalny Modalny Modalny systemowo

24 Rodzaje głównych okien Windows 24 interfejsu programu typu explorer-style Pojedyncze okno zawierające dwa panele - w lewym panelu zawierające zazwyczaj drzewo lub hierarchiczny widok, w prawym panelu wyświetla zawartość obszaru zaznaczonego w lewym panelu. Służy do wyboru lub nawigacji wśród dużej liczby plików, dokumentów, obrazów

25 Aplikacje typu Windows Forms 25


Pobierz ppt "Programowanie komponentowe jesień-zima 2013 Wykład 2 Interakcja komponentów Rodzaje apliakcji w Visual Studio dr inż. Wojciech Bieniecki Instytut Nauk."

Podobne prezentacje


Reklamy Google