dareks_

  • Dokumenty2 821
  • Odsłony748 346
  • Obserwuję429
  • Rozmiar dokumentów32.8 GB
  • Ilość pobrań360 084

Programista 2014 02

Dodano: 6 lata temu

Informacje o dokumencie

Dodano: 6 lata temu
Rozmiar :20.3 MB
Rozszerzenie:pdf

Programista 2014 02.pdf

dareks_ CZASOPISMA
Użytkownik dareks_ wgrał ten materiał 6 lata temu.

Komentarze i opinie (0)

Transkrypt ( 25 z dostępnych 74 stron)

2/2014 (21) www•programistamag•pl Cena 12.90 zł (w tym VAT 23%) Index: 285358 WPF:STYLOWANIEKONTROLEK •POCZĄTKIZFORTRAN •CONCEPTSLITE:ROZSZERZENIE STANDARDUC++14 Własny debugger dla Windows Badanie jakości kodu C ++ Interface a implementacja Przedstwiamy szcze- góły interfejsu Windows Debug API O narzędziach i metry- kach do analizy jakości oprogramowania Separowanie interfejsu użytkownika od logiki aplikacji Javarewolucyjne zmiany

4 / 2 . 2014 . (21)  / REDAKCJA/EDYTORIAL W tym wydaniu Programisty absolutna gratka dla progra- mistów Java – obszerny artykuł Tomasza Nurkiewicza „Java 8 – najbardziej rewolucyjna wersja w historii” opisujący przełomo- we zmiany w nowej wersji tego języka. Współautor cyklu „Bliżej silikonu”, Mateusz Jurczyk, nadal pozostaje przy temacie niskopoziomowego programowania i, tym razem indywidualnie, przybliży nam, jak napisać własny debugger w systemie Windows. Dziś pierwsza część tego arty- kułu, a na drugą odsłonę zapraszamy już w kolejnym numerze. Jako że język C++ z pewnością nie należy do najprostszych, ciekawą propozycją dla jego użytkowników jest artykuł Sła- womira Zborowskiego o badaniu jakości kodu stworzonego w tymże języku. Tekst opisuje różne rodzaje metod badania jako- ści i narzędzia do tego przeznaczone – poczynając od detekcji copy-paste, aż po analizę statyczną. Programistów C# powinien zainteresować natomiast ar- tykuł Wojciecha Sury „Interface a implementacja” o rozwiązy- waniu problemów dotyczących łączenia GUI z implementacją. Prezentuje on złe i dobre podejścia do tego tematu i pokazuje, jak stworzyć aplikację, w której widoki można zmieniać niczym rękawiczki. To jednak nie wszystko, co można znaleźć w najnowszym wydaniu Programisty, więc jak zwykle zachęcamy do znalezie- nia wygodnego miejsca i dokładnego zapoznania się z najnow- szym wydaniem, w którym każdy, mamy nadzieję, znajdzie dla siebie interesujący temat. Z wyrazami szacunku Redakcja Wydawca/ Redaktor naczelny: Anna Adamczyk annaadamczyk@programistamag.pl Redaktor prowadzący: Łukasz Łopuszański lukaszlopuszanski@programistamag.pl Korekta: Tomasz Łopuszański Kierownik produkcji: Krzysztof Kopciowski bok@keylight.com.pl DTP: Krzysztof Kopciowski Dział reklamy: reklama@programistamag.pl tel. +48 663 220 102 tel. +48 604 312 716 Prenumerata: prenumerata@programistamag.pl Współpraca: Michał Bartyzel Mariusz Sieraczkiewicz Michał Leszczyński Marek Sawerwain Łukasz Mazur Rafał Kułaga Sławomir Sobótka Michał Mac Gynvael Coldwind Bartosz Chrabski Adres wydawcy: Dereniowa 4/47 02-776 Warszawa Druk: ArtDruk – www.artdruk.com ul. Napoleona 4 05-230 – Kobyłka Nakład: 5000 egz. Redakcja zastrzega sobie prawo do skrótów i opracowań tekstów oraz do zmiany planów wydawniczych, tj. zmian w zapowiadanych tematach artykułów i terminach publikacji, a także nakładzie i objętości czasopisma. O ile nie zaznaczono inaczej, wszelkie prawa do materiałów i znaków towarowych/firmowych zamieszczanych na łamach magazynu Programista są zastrzeżone. Kopiowanie i rozpowszechnianie ich bez zezwolenia jest Zabronione. Redakcja magazynu Programista nie ponosi odpowiedzialności za szkody bezpośrednie i pośrednie, jak również za inne straty i wydatki poniesione w związku z wykorzystaniem informacji prezentowanych na łamach magazy­nu Programista. Magazyn Programista wydawany jest przez Dom Wydawniczy Anna Adamczyk Zamów prenumeratę magazynu Programista przez formularz na stronie http://programistamag.pl/typy-prenumeraty/ lub zrealizuj ją na podstawie faktury Pro-forma. W spawie faktur Pro-Forma prosimy kontktować się z nami drogą mailową redakcja@programistamag.pl. Prenumerata realizowana jest także przez RUCH S.A. Zamówienia można składać bezpośrednio na stronie www.prenumerata.ruch.com.pl Pytania prosimy kierować na adres e-mail: prenumerata@ruch.com.pl lub kontaktując się telefonicznie z numerem: 801 800 803 lub 22 717 59 59 (godz.: 7:00 – 18:00 (koszt połączenia wg taryfy operatora).

5/ www.programistamag.pl / SPIS TREŚCI BIBLIOTEKI I NARZĘDZIA Interface a implementacja....................................................................................................................... Wojciech Sura 6 Wstęp do WPF – część 2: Stylowanie kontrolek w WPF..................................................................... Wojciech Sura 12 ASP.NET SignalR – czyli aplikacje czasu bardzo rzeczywistego. Część 2.......................................... Karol Rogowski 16 JĘZYKI PROGRAMOWANIA Java 8 – najbardziej rewolucyjna wersja w historii............................................................................... Tomasz Nurkiewicz 22 PoczątkizjęzykiemFortran...................................................................................................................... Radosław Suduł 30 Concepts Lite. Rozszerzenie standardu C++14................................................................................... Robert Matusewicz 36 PROGRAMOWANIE SYSTEMOWE Jak napisać własny debugger w systemie Windows – część 1.......................................................... Mateusz “j00ru” Jurczyk 38 TESTOWANIE I ZARZĄDZANIE JAKOŚCIĄ Badanie jakości kodu C++........................................................................................................................ Sławomir Zborowski 46 LABORATORIUM BOTTEGA Refaktoryzacja testów legacy w kierunku wykonywalnych specyfikacji. Część II: Techniki uła- twiające utrzymanie testów.................................................................................................................... Rafał Jamróz 54 Brakujący element Agile. Część 1: Feedback........................................................................................ Paweł Badeński 60 PLANETA IT Szczyt za szczytem..................................................................................................................................... Łukasz Sobótka 64 STREFA CTF Ghost in the Shellcode 2014 – Pwn Adventure 2................................................................................ Michał "Redford" Kowalczyk 66 KLUB LIDERA IT Jak całkowicie odmienić sposób programowania, używając refaktoryzacji (część 6)....................... Mariusz Sieraczkiewicz 70 KLUB DOBREJ KSIĄŻKI Scala od podszewki................................................................................................................................... Marek Sawerwain 72

6 / 2 . 2014 . (21)  / BIBLIOTEKI I NARZĘDZIA Wojciech Sura NIE METODA, A AKCJA Spróbujmy spojrzeć na interface użytkownika z nieco innej perspektywy. W momencie, gdy użytkownik klika przycisk lub wybiera opcję z menu, jego intencją jest wykonanie pewnej akcji: otwarcie nowego dokumentu, skopio- wanie fragmentu tekstu do schowka albo zamknięcie programu. Przez akcję rozumiemy zatem pojedynczą operację, którą można wywołać z poziomu in- terface'u użytkownika naszej aplikacji. Najprostszym sposobem zaimplementowania takiej akcji jest wywołanie określonej metody w momencie, gdy użytkownik wybierze odpowiedni ele- ment interface’u. Sytuacja skomplikuje się jednak nieco, gdy okaże się, że ta sama akcja może zostać wywołana z poziomu kilku różnych miejsc albo – co gorsza – że jej wywołanie uwarunkowane jest zaistnieniem pewnych szcze- gólnych okoliczności. Żaden z opisanych problemów nie jest oczywiście nie do rozwiązania. Tyle tylko, że oprogramowanie odpowiednich mechanizmów zajmuje czas, wymaga rozszerzenia architektury aplikacji i panowania nad wszystkim tak, aby na koniec nie utonąć w gąszczu zależności, warunków i flag. Odpowiedzią na powyższe potrzeby jest mechanizm, który spełnia nastę- pujące kryteria. Po pierwsze, pozwala na zdefiniowanie akcji jako osobnego bytu, stanowiącego pomost pomiędzy interfacem użytkownika a kodem źró- dłowym. Po drugie, umożliwia określenie zależności pomiędzy elementami interface’u, a później automatycznie pilnuje ich w trakcie pracy programu. Dzięki temu programista nie musi skupiać się na niepotrzebnej pracy, bo integralności interface’u pilnuje jeden spójny mechanizm. Na koniec dobrze byłoby, gdyby był on zaprojektowany w sposób, który ułatwia rozwój zarów- no jego samego, jak i aplikacji, którą zarządza. Chciałbym zaproponować dwa rozwiązania. Pierwszym z nich – z uwagi na brak takowego w standardowych bibliotekach .NET dla Windows Forms – jest otwarty mechanizm o nazwie Visual State Manager. Postaram się wyja- śnić, w jaki sposób można z niego skorzystać i go rozwijać, a także na jakich pomysłach opiera się jego działanie, co pozwoli w łatwy sposób przygotować w razie potrzeby jego odpowiednik dla innego języka programowania lub frameworka. Drugim z nich jest mechanizm przygotowany przez Microsoft działający w środowiskuWPF, którego można użyć zarówno w aplikacjach de- sktopowych, Windows 8, jak i dla Windows Store Apps lub Windows Phone. VISUAL STATE MANAGER Visual State Manager dla Windows Forms opiera się na istnieniu i współpracy trzech rodzajów obiektów: akcji, warunków i operatorów kontrolek (Action, Condition, Control operator). Zadaniem programisty jest zdefiniowanie zależ- ności pomiędzy tymi trzema warstwami, a następnie dostarczanie informacji o zajściu zdarzeń mogących mieć wpływ na warunki, a w efekcie na akcje. Warunek Warunek jest prostym obiektem przechowującym pojedynczą wartość typu bool mówiącą o tym, czy jest on w tym momencie spełniony, czy też nie. Mechanizm managera wykorzystuje warunki do regulowania dostępności, widoczności i zaznaczenia elementów interface'u odpowiedzialnych za wy- woływanie akcji. public interface ICondition { bool Value { get; } event ValueChangedHandler ValueChanged; } Warunek dostępny jest w postaci bardzo prostego w implementacji in- terface’u Icondition: wystarczy dostarczyć tylko własność informującą o obecnym stanie warunku oraz zdarzenie powiadamiające o tym, iż stan ów właśnie się zmienił. Dla wygody przygotowane jest kilka klas implemen- tujących ten interface. Pierwszą z nich jest Condition – najprostsza imple- mentacja. Ponadto możemy skorzystać z klasy CompositeCondition, któ- ra pozwala na połączenie kilku warunków przy pomocy operacji logicznych „i” oraz „lub”, a także NegateCondition, która neguje wskazania innego warunku. Akcja Akcja stanowi abstrakcję dla pewnego działania, które może podjąć użytkow- nik. Każdą akcję – jak już wcześniej wspomniałem – możemy scharakteryzo- wać trzema cechami: dostępnością, widocznością oraz zaznaczeniem. Do- stępność określa, czy użytkownik może w danym momencie akcję wywołać, widoczność informuje, czy kontrolki odpowiedzialne za tę akcję powinny być w ogóle wyświetlane, zaś zaznaczenie przydaje się w przypadku akcji odpo- wiadających za przełączenie jakiegoś stanu (na przykład zawijanie linii lub widoczność paska narzędzi). Zadaniem akcji jest również automatyczne przywiązanie się do wska- zanych kontrolek w interface użytkownika. Dzięki temu programista zwol- niony jest z obowiązku ustawienia tym kontrolkom odpowiednich handle- rów zdarzeń, a także dbania o synchronizację stanów – wszystko dzieje się automatycznie. Skorzystanie z akcji jest stosunkowo proste, ponieważ wystarczy tylko ją zainstancjonować, przekazując w locie parametry definiujące, w jaki sposób powinna działać: »» Metodę,któramazostaćwywołanapowybraniuakcjiprzezużytkownika; »» (opcjonalnie) warunek regulujący dostępność akcji; »» (opcjonalnie) warunek regulujący zaznaczenie elementów interface'u po- wiązanych z akcją; »» (opcjonalnie) warunek regulujący widoczność elementów interface'u po- wiązanych z akcją; »» (opcjonalnie) kontrolki, które będą odpowiadały za wywołanie akcji. Interface a implementacja W każdym programie okienkowym prędzej czy później programista staje przed zadaniem powiązania wizualnych kontrolek z kodem źródłowym, który realizuje za ich sprawą różne zadania. Najprostszym i często stosowanym sposobem jest napi- sanie kodu bezpośrednio w handlerach zdarzeń. Sposób ten oczywiście zadziała, ale to jest chyba wszystko dobre, co można o nim powiedzieć. W niniejszym artyku- le chciałbym zaproponować nieco inne podejście do rozwiązywania tego problemu.

8 / 2 . 2014 . (21)  / BIBLIOTEKI I NARZĘDZIA Operator kontrolek Ostatnią z opisywanych warstw stanowi operator kontrolek, który pozwala ujednolicić sposób współpracy akcji z komponentami wizualnymi. Domyśl- nie dostarczona jest implementacja dla większości standardowych kontrolek, więc jeśli skorzystamy z nich, nie trzeba robić już nic więcej. W przypadku mniej standardowych, Visual State Manager spróbuje ustawić odpowiednie właściwości przy pomocy refleksji, a jeśli i to rozwiązanie okaże się niesatys- fakcjonujące, programista może rozszerzyć mechanizmy VSM poprzez do- starczenie pośrednika, który umożliwi współpracę Visual State Managera z dowolnym zestawem niestandardowych komponentów. JAK TO DZIAŁA? Spróbujmy napisać prosty przykład – standardowe operacje na liście elemen- tów: dodawanie, edytowanie i usuwanie. Zaczniemy od zdefiniowania logiki zależności pomiędzy kontrolkami i akcjami. »» Dodać element możemy w każdym momencie; »» Edycja dostępna jest tylko wówczas, gdy zaznaczony jest dokładnie jeden element; »» Usuwanie dostępne jest wtedy, gdy zaznaczony jest przynajmniej jeden element (jeden lub więcej). Teraz możemy zaprojektować odpowiednią formatkę. Rysunek 1. Główne okno programu Kolejną czynnością będzie zaimplementowanie zdefiniowanych wcześniej zależności. Dla czytelności kodu proponuję umieścić odpowiednie pola wraz z ustawiającą je metodą w osobnym pliku – na przykład DataEditForm.Logic. cs. Zaczynamy od dodania skrótów do namespace’u i skrótu do typu: Listing 1. Wymagane odniesienia do namespace'ów using VisualStateManager; using Action = VisualStateManager.Action; Kolejnym krokiem będzie przygotowanie pól przechowujących odpowiednie warunki i akcje: Listing 2. Deklaracje warunków i akcji public partial class DataEditForm { private Condition singleItemSelected; private Condition itemsSelected; private Action addElementAction; private Action editElementAction; private Action removeElementsAction; } Definiowanie zależności jest stosunkowo proste, ponieważ odbywa się w kon- struktorach odpowiednich klas. W naszym przypadku możemy więc napisać: Listing 3. Metoda inicjalizująca warunki i akcje public void InitializeActions() { singleItemSelected = new Condition(false); itemsSelected = new Condition(false); addElementAction = new Action(DoAdd, bAdd); editElementAction = new Action(DoEdit, singleItemSelected, bEdit); removeElementsAction = new Action(DoRemove, itemsSelected, bRemove); } Jak wcześniej wspomniałem, konstruktory akcji są dosyć elastyczne i po- zwalają określić metodę, która ma zostać wykonana, gdy użytkownik wywoła akcję, warunki dla dostępności, zaznaczenia i widoczności kontrolek, a także listę komponentów, które będą tę akcję wyzwalały. Kontrolowanie stanów kontrolek będzie odbywało się automatycznie, ale musimy najpierw nauczyć VSM, w jakich sytuacjach warunki się zmieniają. Zrobimy to, implementując zdarzenie reagujące na zmianę zaznaczenia listy: Listing 4. Zmiana wartości warunku private void lbData_SelectedValueChanged(object sender, EventArgs e) { singleItemSelected.Value = lbData.SelectedItems.Count == 1; itemsSelected.Value = lbData.SelectedItems.Count > 0; } Na koniec warto wspomnieć o jednej rzeczy: ponieważ kontrolki wizualne muszą być już zainstancjonowane, gdy przygotowujemy logikę akcji, meto- da InitializeActions powinna zostać wywołana po wywołaniu metody InitializeComponent. Wygodnym miejscem jest więc konstruktor okna, w którym obie metody możemy wywołać we właściwej kolejności: Listing 5. Inicjalizowanie okna public DataEditForm() { InitializeComponent(); InitializeActions(); } I to wszystko – mechanizm jest już przygotowany do pracy. Naturalnie do za- implementowania pozostają jeszcze same akcje – przykładowy projekt moż- na odnaleźć w materiałach do artykułu dostępnych do ściągnięcia ze strony magazynu Programista. Jakie zalety ma zastosowane powyżej rozwiązanie? Po pierwsze, me- chanizm będzie pilnował za nas, aby użytkownik nie wywołał akcji, gdy nie będzie takiej możliwości: ogranicza to liczbę błędów mogących powstać w trakcie pracy programu. Zauważmy też, że każda kontrolka, która jest odpo- wiedzialna za wywołanie akcji, automatycznie będzie kontrolowana przez mechanizm (przynajmniej dopóki nie spróbujemy ręcznie ustawiać handle- rów zdarzeń na metody realizujące akcje, ale przed tym Visual State Manager ani inny gotowy mechanizm nie jest już w stanie zabezpieczyć). Drugą zaletą jest stosunkowa łatwość rozbudowy możliwości formatki. Jeśli zmienią się okoliczności wywołania niektórych akcji, wystarczy dodać odpowiednie warunki lub zbudować warunki kompozytowe, a wszystko wciąż będzie działało prawidłowo. Bardziej wymagającym programistom pozostanie oczywiście opcja implementacji interface’u ICondition w celu wprowadzenia bardziej skomplikowanych zależności. Jeśli zaistnie- je potrzeba dodania jeszcze jednego miejsca, z poziomu którego będzie można wywołać akcję, sprowadzi się to tylko do dodania odpowiedniej kontrolki do konstruktora klasy Action. Poza tym wprowadzenie do- datkowej warstwy pomiędzy interfacem użytkownika i implementację pozwala na bardzo łatwą wymianę tego pierwszego. Sprowadzi się to bowiem tylko do wprowadzenia odpowiednich modyfikacji w metodzie InitializeActions. Trzecią zaletą jest fakt, iż podczas korzystania zVisual State Managera pro- gramista może zdefiniować zależności rządzące formatką w bardzo naturalny sposób. Jest to znacznie wygodniejsze od ręcznego implementowania me- chanizmów zabezpieczających.

9/ www.programistamag.pl / INTERFACE A IMPLEMENTACJA WINDOWS PRESENTATION FOUNDATION Biblioteki Windows Presentation Foundation, w przeciwieństwie do Windows Forms, dostarczają gotowe rozwiązanie dla zadanego problemu. ICommand Kluczową rolę odgrywa tu interface ICommand, który jest odpowiednikiem akcji z zaprezentowanego wcześniej mechanizmu, i wygląda następująco: Listing 6. Interface ICommand public interface ICommand { event EventHandler CanExecuteChanged; bool CanExecute(object parameter); void Execute(object parameter); } Przeznaczenia składowych ICommandmożna się łatwo domyślić: Executema wykonać komendę, CanExecute powinno stwierdzić, czy w danym momen- cie może ona zostać wykonana, zaś zdarzenie CanExecuteChanged infor- muje o sytuacji, w której dostępność komendy uległa zmianie. CanExecute jest zazwyczaj wywoływana w reakcji na zdarzenie CanExecuteChanged. Najprostszym sposobem wykorzystania komend jest po prostu zaimple- mentowanie interface'u ICommand, a następnie przypisanie instancji takiej klasy do własności Command kontrolek wizualnych. Przykładowa implemen- tacja dostępna jest na Listingu 7. Listing 7. Przykładowa implementacja ICommand internal class SimpleCommand : ICommand { private bool canExecute; private Action executeAction; protected void OnCanChangeExecuted() { if (CanExecuteChanged != null) CanExecuteChanged(this, EventArgs.Empty); } public bool CanExecute(object parameter) { return canExecute; } public SimpleCommand(Action newExecuteAction, bool newCanExecute = true) { if (newExecuteAction == null) throw new ArgumentNullException("newExecuteAction"); executeAction = newExecuteAction; canExecute = newCanExecute; } public void Execute(object parameter) { if (executeAction != null) executeAction(parameter); } public bool IsExecutable { get { return canExecute; } set { canExecute = value; OnCanChangeExecuted(); } } public event EventHandler CanExecuteChanged; } Dalej postępujemy podobnie, jak w przypadku Windows Forms. Najpierw musimy osadzić nasze komendy w klasie okna, w którym będą funkcjonowa- ły, i udostępnić je przy pomocy własności (by potem można było przywiązać je do odpowiednich kontrolek w XAMLu): Listing 8. Udostępnienie własności przez okno public partial class MainWindow : Window { private SimpleCommand addCommand; (...) public ICommand AddCommand { get { return addCommand; } } (...) } Kolejnym krokiem jest zainstancjonowanie ich w konstruktorze klasy: Listing 9. Przygotowanie komend do pracy public MainWindow() { addCommand = new SimpleCommand(DoAdd); (...) DataContext = this; } Nie zapomnijmy o ustawieniu własności DataContext, która umożliwi pra- widłowe działanie bindingów. Oprócz tego trzeba oczywiście zaimplemento- wać metody realizujące komendy. Dla prostoty przykładu zrezygnuję w tym przypadku z naturalnego w WPFie modelu MVVM; bardziej właściwym miej- scem dla umieszczenia komend jest bowiem viewmodel. Teraz musimy zadbać o weryfikację dostępności komend. WPF nie dostar- cza wprawdzie dedykowanego mechanizmu, który pozwoliłby zautomatyzo- wać ten proces w podobny sposób, jak ma to miejsce w Visual State Manage- rze, ale z drugiej strony nic nie stoi na przeszkodzie, by skorzystać z natywnych WPFowych mechanizmów, jakimi są bindingi i konwertery.W naszym przypad- ku ograniczymy się tylko do zaimplementowania odpowiednich zdarzeń. Listing 10. Reagowanie na zmianę warunków private void lbData_SelectionChanged(object sender, SelectionChangedEventArgs e) { editCommand.IsExecutable = lbData.SelectedItems.Count == 1; removeCommand.IsExecutable = lbData.SelectedItems.Count > 0; } Ostatnim etapem jest przywiązanie kontrolek do przygotowanych akcji. Mo- żemy zrobić to poprzez zdefiniowanie odpowiednich własności w XAMLu okna, które projektujemy: Listing 11. Wiązanie elementów interface'u z komendami