ASP.NET Wprowadzenie provided by Przemysław Bykowski
Strona internetowa vs aplikacja internetowa
Aplikacja internetowa Nie ustępuje możliwościami od standardowej aplikacji desktopowej Przeglądarka pośredniczy miedzy aplikacją a użytkownikiem Pierwszymi aplikacje internetowe dotyczyły obsługi poczty elektronicznej Bardzo wygodna. Użytkownik nie musi instalować oprogramowania, by uzyskać taką sama funkcjonalność, jak standardowy program Oceń, przykładową aplikacje - tu
Dodawanie formatki do projektu
Budowa formularza Pojedynczy (prosty) formularz składa się z trzech części: Nazwa_Formatki.aspx wygląd aplikacji. Posiada dwa tryby widoku: kod źródłowy (X)HTML tryb graficzny Nazwa_Formatki.aspx.cs cześć logiczna aplikacji Nazwa_Formatki.aspx.designer.cs logiczna reprezentacja elementów GUI
Kompilacja aplikacji Nazwa_Formatki.aspx nie ulega kompilacji. W takiej samej postaci musi zostać umieszczony na serverze Nazwa_Formatki.aspx.cs Nazwa_Formatki.aspx.designer.cs - oba pliki muszą zostać skompilowane przed umieszczeniem na serwerze. Pliki te kompilują się do bibliotek *.dll i w takiej postaci muszą zostać umieszczone na serverze
Kompilacja aplikacji <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="cos_popsulem._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
Podstawowe własności strony <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Nazwa_Formatki.aspx.cs" Inherits="Nazwa_Projektu.Nazwa_Formatki" %> Language określa język programowania jaki będziemy wykorzystywać do pisania warstwy logicznej aplikacji. Inne możliwości to VS i JS. AutoEventWireup określenie, czy wywołane zdarzenia będą automatycznie powiązane z funkcja ich obsługi. CodeBehind powiązanie bieżącego pliku z plikiem przechowującym logikę. Inherits dziedziczenie. Przeważnie jest to nazwa klasy zaimplementowanej w pliku kodu określonego parametrem CodeBehind.
Inne przydatne właściwości Trace szczegółowe informacje na temat żądań Więcej na http://msdn.microsoft.com/enus/library/ydy4x04a(v=vs.85).aspx
ASP.NET Praca z danymi provided by Przemysław Bykowski
Praca z bazą danych Możliwość podawania ręcznych zapytań do bazy danych. Wykorzystywanie procedur zdefiniowanych w bazie danych do wykonywania operacji na niej. Entity Framework genialne narzędzie ORM. Bardzo wygodne wygoda. Prawdopodobnie wydajność naszej aplikacji spada o około 20% niż w przypadku wykosztowania ręcznych zapytań. Istnieje kilka podobnych narzędzi ORM. Przykładowo bardzo popularny oparty o licencje GNU NHibernate.
Lokalizacja bazy danych Baza danych może istnieć lokalnie (*.sdf). Taką bazę danych należy umieścić w specjalnie przeznaczonym do tego katalogu App_Data. Możemy nawiązać zdalne połączenie z bazą danych. Nie jest wymagane, aby baza danych znajdowała się lokalnie na serwerze. W obu przypadkach zostanie utworzony tzw. ConnectionString
ConnectionString Przechowuje dane do połączenia z bazą danych. Domyślnym miejscem przechowywania connectionstringa jest plik Web.config Przykładowy CS: <connectionstrings> <add name= ObiektReprezentujacy" connectionstring="metadata=res://*/model1.csdl res://*/model1.ssdl res://*/model1.msl;pr ovider=system.data.sqlclient;provider connection string="data source=nazwa_hosta;initial catalog=nazwa_bazy_danych;integrated security=true;multipleactiveresultsets=true;app=typ_polaczenia"" providername="system.data.entityclient" /> </connectionstrings>
Tworzenie ConnectionString Nie musimy ręcznie tworzyć połączeń Wszystko za programistę załatwiają kreatory
GridView Niektóre kontrolki są w stanie automatycznie pobrać zawartość dla siebie z bazy danych. Same wykonują odpowiednie zapytania do bazy danych GridView pozwala wyświetlić użytkownikowi zawartość wybranej tabeli, a następnie pozwolić na ich modyfikacje.
LINQ Umożliwia pobieranie danych na poziomie kodu Składnia podobna do SQL Służy do zadawania pytań na obiektach a nie elementach bazy danych Przykład zapytania LINQ var wynik = from x in mojakolekcja where x.id > 10 select x SELECT * To samo w SQL INTO #wynik FROM mojatabela WHERE id > 10 W przeciwieństwie do składni C# - zapytania w LINQ nie są key sensitive
ASP.NET Testy jednostkowe provided by Przemysław Bykowski
Test jednostkowe co to? Metoda, która sprawdza inną metodę, czy owa metoda, działa poprawie Stosuje się go tylko (to nie jest sztywna zasada) w projektach regularne rozwijanych. Wzięła swój początek w programowaniu ekstremalnym
Test jednostkowe jakie one powinny być Możliwie najprostszą logikę Często pisane są one przez testerów, a nie samych programistów (w zależności od wielkości korporacji) Jeden test wykonuje (powinien) jedno działanie/sprawdza jedna metodę Jeżeli istnieje taka potrzeba, można sprawdzać wiele klas oraz ich metod w jednym teście
Test jednostkowe po co to komu? Wspomagają pracę programisty i testera Przyspiesza proces wytwarzania oprogramowania (o dziwo?) Stosuje się go tylko (to nie jest sztywna zasada) w projektach regularne rozwijanych. Bo wymaga tego Agile - wprowadzona w metodykach programowania Agile (zwinne) czy wszyscy wiedzą czym jest Agile?
Refaktoryzacja Refaktoryzacja (czasem też refaktoring, ang. refactoring) to pojęcie związane z wytwarzaniem systemów informatycznych, w szczególności z programowaniem. Jest to proces wprowadzania zmian w projekcie/programie, w wyniku których zasadniczo nie zmienia się funkcjonalność. Celem refaktoryzacji jest więc nie wytwarzanie nowej funkcjonalności, ale utrzymywanie odpowiedniej, wysokiej jakości organizacji systemu. W ramach refaktoryzacji podejmowane są następujące działania: modyfikowanie elementów systemu w celu wpasowania ich w przyjęte standardy i wzorce poszukiwanie nowych standardów i wzorców, które pojawiły się w systemie w trakcie jego rozwoju i ich precyzyjne definiowanie (łącznie z wpasowywaniem istniejących elementów w te definicje). Źródło Wikipedia : http://pl.wikipedia.org/wiki/refaktoryzacja
Test driven development (TTD) Etap 1 piszemy test jednostkowy Etap 2 upewniamy się, że dany test zwraca negatywny wynik Etap 3 implementujemy daną metodę/funkcjonalność w naszym projekcie zalecane nawet, aby była ona napisana w sposób łopatologiczny Etap 4 wykonujemy test jednostkowy. Jeśli nie otrzymamy poprawności wykonania testu patrz etap 3 Etap 5 refaktoryzacja metody/funkcjonalności Etap 6 ponowne wykonanie testu jednostkowego. W przypadku nie powtórzenia patrz etap 3
Przykład wykonywania testu Zakładam nowy projekt Zastanawiam się co ma realizować mój projekt np. dodawanie zaimplementowanie w klase liczenie.cs Tworze projekt testu jednostkowego Implementuj test jednostkowy określając parametry wejściowe i oczekiwany wynik Implementuje metodę dodawania w klasie liczenie.cs Sprawdzam poprawność działania mojej metody if (poprawnoscmetody == Test.passed) else { } Optymalizuj.Metode(dodawanie) Popraw.Metode(dodawanie) SprawdzPoprawnosc.Metody(dodawanie) Koniec.Pracy(DataTime.Now()) Anegdota - przeciętny programista pisze 10-15 linijek kodu dziennie
Wniosek TEST JEDNOSTOWY ZAWSZE I TO ZAWSZE WYKONUJE PRZED ZAIMPLEMENTOWANIEM LOGIKI MOJEJ APLIKACJI INACZEJ NIE MA ON SENSU! Dlatego często test jednostkowy wykonuje inna osoba niż ta implementująca funkcjonalność. Testy jednostkowe warto jest wykonywać tylko wtedy, gdy: - projekt jest dalej rozwijany - będzie w przyszłości wykorzystywany
Jak tworzyć test w VS? Tworze dowolny projekt bardzo często.asp dlaczego?
Co chce osiągnąć realizując swoją aplikacje? Kalkulator! Dodaje moja klasę LiczMnie ale tylko po to, aby uzyskać podpowiadanie składni w moim projekcie testowym
Tworze test jednostkowy Pamiętaj, że test jednostkowy dodaje się do solucji a nie projektu!
Dodaje projekt testu
Mam już dwa projekty Otrzymuje dwa projekty Jeden projekt aplikacji Drugi projekt testu Pamiętamy o podpięciu referencji, aby oba projekty widziały się nawzajem
Mam już dwa projekty Otrzymuje dwa projekty Jeden projekt aplikacji Drugi projekt testu Pamiętamy o podpięciu referencji, aby oba projekty widziały się nawzajem
Mam już dwa projekty Otrzymuje dwa projekty Jeden projekt aplikacji Drugi projekt testu Pamiętamy o podpięciu referencji, aby oba projekty widziały się nawzajem
Implementuje swoje testy Otrzymuje dwa projekty Jeden projekt aplikacji Drugi projekt testu Pamiętamy o podpięciu referencji, aby oba projekty widziały się nawzajem
Mam już dwa projekty Otrzymuje dwa projekty Jeden projekt aplikacji Drugi projekt testu Pamiętamy o podpięciu referencji, aby oba projekty widziały się nawzajem
Pisze test jednostkowy w klasie projektu MojTest
Wykonuje test w nadziei, że się nie wykona poprawnie
Implementuje logikę programu
Sprawdzam testy
Poprawiam testy i refaktoryzuje klasę logiki
Sukces!
Pytania?
Dziękuje za uwagę provided by Przemysław Bykowski przemyslaw@bykowski.pl
Wzorce projektowe provided by Przemysław Bykowski
Wzorzec projektowy Rozwiązuje problemy projektowe Ułatwia powtórne wykorzystywanie poprawnie zaprojektowanych architektur Nie zmienia logiki programu Dotyczą projektów środowiska obiektowego zorientowanego Ułatwia utrzymanie, oraz rozbudowywanie oprogramowania Jest opisem rozwiązania, a nie jego konkretną implementacją
Budowa wzorca Każdy wzorzec projektowy składa się z 4 kluczowych elementów: Nazwa wzorca uniwersalna indykacja wzorca Opis problemu, który dany wzorzec rozwiązuje Rozwiązanie Konsekwencje (jeśli istnieją)
Rodzaje wzorców projektowych Konstrukcyjne (Creational) związane z procesem tworzenia obiektów. Strukturalne (Structural) dotyczą struktury klas lub/i obiektów Operacyjne (Behavioral) sposób współdziałania, zachowania klas lub/i obiektów
Przykłady najpopularniejszych wzorców
Singleton wzorzec konstrukcyjny Gwarantuje tylko jedna instancje obiektu Pozwala na globalny dostęp do utworzonej instancji Wykorzystywany do przechowywania zmiennych publicznych Połączeń z bazą danych, połączeń z portami szeregowymi
Singleton rozwiązanie Singleton implementuje się przez stworzenie klasy, która posiada statyczną metodę, która najpierw sprawdza, czy istnieje już instancja tej klasy, w razie potrzeby tworząc ją. Następnie instancja zwracana jest przez referencję. Instancję przechowuje się w prywatnym lub chronionym, statycznym polu, do którego dostęp ma tylko opisana wyżej metoda, która jest jedyną drogą pozyskania instancji obiektu singletonu aby uniemożliwić tworzenie dodatkowych instancji, konstruktor klasy deklaruje się jako prywatny lub chroniony. Źródło Wikipedia : http://pl.wikipedia.org/wiki/singleton_(wzorzec_projektowy)
Singleton przykład Java } } public class ClassicSingleton { private static ClassicSingleton instance = null; protected ClassicSingleton() { public static ClassicSingleton getinstance() { if(instance == null) { instance = new ClassicSingleton(); } return instance; }
Metoda wytwórcza (Factory method) wzorzec konstrukcyjny Tworzenie obiektów w sposób dynamiczny Kod otwarty na rozbudowę Przykład: W zależności od akcji użytkownika zostanie zwrócony mu odpowiedni obiekt
Metoda wytwórcza rozwiązanie We wzorcu występują dwie ogólne klasy bądź interfejsy definiujące pewien typ zasobów (Product) oraz sposób ich tworzenia (Creator, metoda factorymethod()). Od nich wyprowadza się konkretne klasy zasobów (ConcreteProduct) wraz z tworzącymi je klasami wytwórczymi (ConcreteCreator), które dostarczają odpowiednią implementację metody factorymethod(). Komponent pragnący tworzyć zasoby i operować na nich, korzysta z ogólnych interfejsów Product oraz Creator, umożliwiając wybór konkretnej implementacji w sposób dynamiczny. Źródło : Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Inżynieria oprogramowania: Wzorce projektowe (Wyd. II). Warszawa: Wydawnictwo Naukowo-Techniczne, 2008
Metoda wytwórcza przykład Java class Wynagrodzenie { private const UInt16 STAWKA_GODZINOWA_PIEKARZA = 10; private const UInt16 STAWKA_GODZINOWA_NAUCZYCIELA = 21; private const UInt16 STAWKA_GODZINOWA_KIEROWNIKA = 50; public static float ObliczWynagrodzenia(TypZawodu zawod, UInt16 iloscprzepracowanychgodzin) { switch (zawod) { case TypZawodu.PIEKARZ: return STAWKA_GODZINOWA_PIEKARZA * iloscprzepracowanychgodzin; case TypZawodu.NAUCZYCIEL: return STAWKA_GODZINOWA_NAUCZYCIELA * iloscprzepracowanychgodzin; case TypZawodu.KIEROWNIK: return STAWKA_GODZINOWA_KIEROWNIKA * iloscprzepracowanychgodzin; default: return 0; } }}
interface IPracownik { float ObliczWynagrodzenie(UInt16 iloscprzepracowanychgodzin); } // każdy pracownik musi implementować metodę ObliczWynagrodzenie class Piekarz : IPracownik { private const UInt16 STAWKA_GODZINOWA = 10; public float ObliczWynagrodzenie(UInt16 iloscprzepracowanychgodzin) { return STAWKA_GODZINOWA * iloscprzepracowanychgodzin; } } class Nauczyciel : IPracownik { private const UInt16 STAWKA_GODZINOWA = 21; public float ObliczWynagrodzenie(UInt16 iloscprzepracowanychgodzin) { return STAWKA_GODZINOWA * iloscprzepracowanychgodzin; } }
class Kierownik : IPracownik { private const UInt16 STAWKA_GODZINOWA = 50; public float ObliczWynagrodzenie(UInt16 iloscprzepracowanychgodzin) { return STAWKA_GODZINOWA * iloscprzepracowanychgodzin; } } //użycie: IPracownik pracownik = WynagrodzenieFactoryMethod.MakePracownik(TypZawodu.NAUCZYCIEL); pracownik.obliczwynagrodzenie(120); //jeśli będziemy chcieli dodać kolejny zawód, to musimy tylko utworzyć nowa klasę, która implementuje interface IPracownik oraz dodać do metody MakePracownik kolejnego case'a Źródło Wikipedia : Przykład http://wyprogramowanie.blogspot.com/2008/04/wzorce-projektowefactory-method-metoda.html
Pula obiektów (Object pool) wzorzec strukturalny Zarządzanie pulą obiektów reprezentujących zasoby wielokrotnego użycia Ograniczenie kosztów (głównie czasowych) tworzenia i usuwania obiektów Zwiększenie wydajności systemu
Pula obiektów - rozwiązanie Zdefiniowanie punktu dostępu do obiektów (zarówno do ich tworzenia, jak i zwrotu) oraz zarządzanie cyklem ich życia: tworzeniem, inicjalizacją i usuwaniem. Klient może otrzymać instancję klasy Obiekt wyłącznie za pomocą Puli obiektów i w ten sam sposób zwalnia przydzielony obiekt. Źródło Wikipedia : http://pl.wikipedia.org/wiki/singleton_(wzorzec_projektowy)
Pula obiektów przykładowy algorytm 1. Pula obiektów tworzy określoną ilość obiektów zadanych klas/klasy. 2. Obiekty te przechowywane są w puli. 3. W momencie kiedy klient zgłasza zapotrzebowanie na dany obiekt - nie trzeba będzie go inicjalizować, wystarczy pobrać istniejący z puli. PrzykładowaKlasa PrzykladowePole : String PrzykladowaMetoda() Klient PulaObiektow UtworzObiekt() PobierzObiekt() Wzorzec często wykorzystywany przy aplikacjach współpracujących z bazami danych. Nawiązanie nowego połączenia trwa długo pobranie już istniejącego skraca ten czas.
Dziękuje za uwagę provided by Przemysław Bykowski przemyslaw@bykowski.pl