Professional Documents
Culture Documents
�����������������������������������
�����������������������������������������������������������������������������
�����������������������������������������������������������������������������
�������������������������������������������������������������������������������
����������������������������
���������������������������������������������������������������������������
��������������������������������������������������������������������������������
������������������
�����������������������������������������������������������������������������������
��������������������������������������������������������������������������������
���������������������������������������������������������������������������������
������������������������������������������������������������������������������
���������������������������������������������
�����������������������������������������������������������������������������������������������
03/2010 (183)
SPIS TREŚCI
15 Opis DVD SZTUCZNA INTELIGENCJA
20 Paradygmat programowania CLP
– Metody rozwiązywania trudnych problemów
kombinatorycznych
BIBLIOTEKA MIESIĄCA Łukasz Mazur
Wysoka efektywność metod CLP jest rezultatem wykorzystania
6 Boost String Algorithms – Eleganckie i efektywne procedur propagacji ograniczeń oraz dystrybucji zmiennych,
przetwarzanie napisów w języku C++ w celu poszukiwania rozwiązań spełniających wszystkie przyjęte
Rafał Kocisz ograniczenia. Procesy te realizowane są w sposób klasyczny, jak
Czy próbowałeś kiedyś budować zaawansowane narzędzia do i rozproszony, dając bardzo dobre rezultaty obliczeniowe.
przetwarzania tekstu, bazując na funkcjonalności klasy std::
string? Jeśli tak, to założę się, że nie wspominasz zbyt dobrze tego
doświadczenia. Podstawowe udogodnienia związane z przetwa-
rzaniem napisów w C++ są, delikatnie mówiąc... mało wygodne.
Na szczęście – istnieje alternatywa!
BEZPIECZEŃSTWO
32 Niezawodność systemów informatycznych
Andrzej Olchawa
Nieustanny postęp technologiczny, zwłaszcza ten dotyczący
PROGRAMOWANIE C++ świata IT, sprawia, że mamy do czynienia z globalną komputery-
zacją oraz informatyzacją, która z dnia na dzień zatacza coraz to
12 Tworzenie kopii obiektów – Wzorzec prototypu szersze kręgi. Postęp służyć powinien globalnemu dobru, jednak
Robert Nowak wraz postępem pojawiają się coraz to nowe problemy oraz pułap-
Kopiowanie obiektów, czyli tworzenie duplikatów, przechowu- ki, których nie sposób traktować z przymrużeniem oka.
jących te same informacje bez niszczenia oryginału, jest jedną
z podstawowych operacji, które wykorzystujemy w programowa-
niu. Artykuł opisuje tę czynność, analizując techniki wspierające
proces tworzenia kopii w języku C++.
WARSZTATY
36 Hibernate Search API – Mechanizm
wyszukiwania pełnotekstowego w Hibernate
PROGRAMOWANIE JAVA Łukasz Antoniak
Aplikacje bazodanowe stanowią obecnie znaczący odsetek
16 Przewodnik po SCJP oprogramowania tworzonego na zlecenie prywatnych firm, jak
– czyli certyfikat z Javy - część 3 i ogromnych korporacji. Większość aplikacji realizuje warstwę do-
Krzysztof Rychlicki - Kicior stępu do danych za pomocą relacyjnie zorientowanej implemen-
Proces zdobywania certyfikatów, potwierdzających umiejętno- tacji bazy danych (ang. Relational Database Management Sys-
ści z różnych dziedzin wiedzy, stał się jednym z ważniejszych tem). Wybór ten ogranicza swobodę przeszukiwania zawartych
elementów osobistego rozwoju. Proces ten ma miejsce również informacji do zbioru ściśle sformalizowanych zapytań udostęp-
w branży IT; certyfikaty dla programistów (Java lub .NET), admini- nianych przez aplikację. Artykuł ten wprowadza w zagadnienia
stratorów czy sieciowców (Cisco) można coraz częściej odnaleźć przeszukiwania pełnotekstowego oferowanego przez Hibernate
w CV osób starających się o pracę, zwłaszcza w owianym złą sła- Search oraz Apache Lucene.
wą kryzysie gospodarczym.
4 03/2010
APLIKACJE BIZNESOWE
Miesięcznik Software Developer’s Journal (12 numerów w roku)
56 SOA – Tworzenie serwisów wspomagających jest wydawany przez Software Press Sp. z o.o. SK
proces integracji
Paweł Pietrasz
Redaktor naczelny:
Tworzenie rozwiązań integracyjnych to nie trend, ale wymóg sta- Łukasz Łopuszański lukasz.lopuszanski@software.com.pl
wiany przed projektantami systemów informatycznych. Coraz bar-
dziej złożone procesy biznesowe wymagają od nas projektowania Projekt okładki: Agnieszka Marchocka
rozwiązań dotykających coraz to większej ilości systemów, które
w przeszłości często nie były projektowane w sposób zapewniający Skład i łamanie:
Tomasz Kostro www.studiopoligraficzne.com
łatwą możliwość integracji.
Kierownik produkcji:
Andrzej Kuca andrzej.kuca@software.com.pl
macje pomaga przekuć na mierzalne konkrety. Wszystkie znaki firmowe zawarte w piśmie są własności
odpowiednich firm.
Zostały użyte wyłącznie w celach informacyjnych.
www.sdjournal.org 5
Biblioteka miesiąca
S
tandardowe udogodnienia biblioteki znaków (ang. search, replace, erase). Zanim rozważymy szczegółowo możliwości
języka C++, dedykowane przetwarza- Boost String Algorithms skonstruowa- biblioteki Boost String Algorithms, spójrzmy
niu napisów, pozostawiają wiele do ży- na jest w sposób, który nie ogranicza jej do na krótki, prosty przykład jej użycia (patrz:
czenia. Wielu programistów uważa, że klasa współpracy z jednym, z góry narzuconym ty- Listing 2).
std::string to jedna z większych wpadek
twórców standardu tego języka. Szablon std:
Listing 1. Implementacja operacji przycięcia zbędnych znaków (np. spacji) z początku i końca
:basic_string jest przykładem klasy o roz- napisu, bazująca na funkcjonalności std::string
dmuchanym, niespójnym interfejsie, mało in-
tuicyjnej w użyciu, udającej kontener STL, ale void trim( string& str )
nie będącej nim do końca i nieelastycznej. Je- {
śli nie wierzysz, to spróbuj przy pomocy std: string::size_type pos = str.find_last_not_of( ' ' );
:basic_string wykonać operację przycię-
cia zbędnych znaków (np. spacji) z początku if (pos != string::npos)
i końca napisu (ang. trimming)... {
Oczywiście, da się to zrobić – po uprzed- str.erase( pos + 1 );
nim zapoznaniu się z takimi metodami klasy pos = str.find_first_not_of( ' ' );
std::string jak find_first_not_of, find_
last_not_of oraz erase (patrz: Listing 1). if ( pos != string::npos )
Ale czy nie można by zrobić tego prościej...? {
A co w sytuacji, kiedy nasz napis reprezento- str.erase( 0, pos );
wany jest jako wektor char'ów? }
Zanim załamiesz ręce, poczekaj! Na szczę- }
ście – jest... else
{
...światełko w tunelu... str.erase( str.begin(), str.end() );
...w postaci biblioteki Boost String Algori- }
thms. Biblioteka ta oferuje uogólnione (ang. }
generic) implementacje algorytmów działają-
6 03/2010
Programowanie w języku C++
Zadanie, które ma zrealizować nasz przy- padku Boost String Algorithms. Patrząc na • Przekazywanie argumentów: w odróżnie-
kład, jest bardzo proste: chcemy usunąć białe przykład z Listingu 2, da się zauważyć kilka niu od STL Boost String Algorithms prefe-
znaki z początku i końca napisu, a następnie podstawowych konwencji: ruje przekazywanie kontenera do funkcji
stworzyć nowy napis będący kopią poprzed-
niego, z tą różnicą, że wszystkie litery z orygi-
nalnego napisu zamienione będą na małe. Bo-
Szybki start
Aby rozpocząć pracę z Boost String Algorithms musimy zainstalować pakiet bibliotek Bo-
ost String Algorithms pozwala zrealizować to ost. Pakiet ten można pobrać pod adresem http://www.boost.org. Przeważająca część biblio-
zadanie za pomocą dwóch prostych, intuicyj- tek wchodzących w skład tego pakietu jest zakodowana w plikach nagłówkowych i z tej racji
nych funkcji. Morał z tego przykładu jest na- można ich używać od ręki. Tak właśnie jest w przypadku biblioteki prezentowanej w niniej-
stępujący: nie mając pod ręką odpowiedniej bi- szym artykule. Jeśli używasz kompilatora z rodziny Microsoft Visual Studio to wystarczy we
właściwościach projektu (ang. Properties), w zakładce Con�guration Properties \ C/C++ \ Ge-
blioteki, musielibyśmy funkcje do przycinania
neral odpowiednio ustawić pole Additional Include Directories (patrz: Rysunek 1). Ja de�niuję
i konwersji zaimplementować sami. Niby pro- sobie zawsze zmienną środowiskową %BOOST_HOME%, która wskazuje na miejsce (katalog),
sta rzecz, aczkolwiek nie do końca. Jeśli two- w którym zainstalowany jest pakiet Boost. Na Rysunku 1 pokazane jest jak odwołuję się do
rzony przez nas kod miałby być kodem pro- tej zmiennej. Oczywiście można tutaj podać również względną (w odniesieniu do katalogu,
dukcyjnym, to należałoby poważnie zastano- w którym znajduje się projekt) bądź bezwzględną ścieżkę wskazującą na to miejsce.
wić się nad takimi aspektami jak: poprawność Trochę więcej zachodu jest ze skon�gurowaniem biblioteki Boost Regex. Nie jest stano-
wi ona co prawda meritum niniejszego artykułu, aczkolwiek – z racji tego, iż korzystam z niej
(szczegółowe rozważenie wszystkich przypad-
w kilku prezentowanych tu przykładach – pozwolę sobie napisać klika słów na temat jej in-
ków użycia), wydajność, rozszerzalność, ob- stalacji. Boost Regex jest jednym z nielicznych komponentów Boost, które wymagają od-
sługa błędów itd. Trzeba by zapewne zapro- dzielnego zbudowania. Na szczęście, pakiet posiada swój własny system budowania źró-
jektować i zaimplementować zestaw testów deł – w dużej mierze niezależny od platformy. Aby skorzystać z tego systemu potrzebny
modułowych. Krótko mówiąc, trywialne zda- jest programu bjam. Link do strony na której można pobrać ten program (oczywiście za dar-
mo) znajduje się pod adresem http://www.boost.org/doc/libs/1_41_0/more/getting_started/
nie, które chcielibyśmy rozwiązać w kilka se-
windows.html. Pod tym samym adresem znajduje się również bardzo szczegółowa instrukcja
kund, urasta nam nagle do rozmiarów tworze- budowania źródeł pakietu Boost. Proces kompilacji całej biblioteki jest czasochłonny i wy-
nia własnej biblioteki – co już trywialnym za- maga sporej ilości wolnego miejsca na dysku. Na szczęście istnieje możliwość zbudowania
daniem nie jest. wybranych komponentów. W celu zbudowania biblioteki Boost Regex w katalogu głównym
Dla odmiany, Boost String Algorithms da- biblioteki (tam gdzie znajduje się plik Jamroot) należy wydać polecenie:
je nam dokładnie to, czego potrzebujemy:
bjam --with-regex
proste, dobrze przetestowane, wydajne im-
plementacje operacji na napisach. Wystar- Zanim to uczynimy, należy upewnić się, czy program bjam.exe znajduje się w ścieżce wykona-
czy dołączyć właściwy nagłówek (#include nia (zmienna środowiskowa PATH) oraz czy z poziomu konsoli dostępne są narzędzia dewelo-
<boost/algorithm/string.hpp>) i po kłopo- perskie Microsoft Visual Studio C++ (aby uzyskać dostęp do tych narzędzi należy uruchomić
cie. Aż chciałoby się zacytować motto użyt- plik vcvars32.bat znajdujący się w podkatalogu bin, w miejscu gdzie zainstalowano wspomnia-
ne środowisko).
kowników języka Perl: niechaj proste rzeczy po- Podana wyżej komenda spowoduje zbudowanie biblioteki Boost Regex i zainstalowa-
zostaną proste. nie jej w katalogu %BOOST_HOME%\bin.v2. Uruchamiając przykłady zamieszczone w niniej-
szym artykule należy pamiętać o tym aby skon�gurować program łączący (ang. Linker) tak
Konwencje aby używał skompilowanej biblioteki Boost Regex. W przypadku korzystania z pakietu Mi-
Każda biblioteka narzuca pewne zasady doty- crosoft Visual Studio wystarczy we właściwościach projektu (ang. Properties) w zakładce Con-
�guration Properties \ Linker \ General ustawić odpowiednio pole Additional Library Directories,
czące korzystania z niej. Podobnie jest i w przy-
tak aby podana tam ścieżka wskazywała na miejsce, w którym znajduje się plik ze skompilo-
waną biblioteką.
Listing 2. Prosty przykład użycia biblioteki
Boost String Algorithms
#include <boost/algorithm/string.hpp>
#include <iostream>
int main()
{
string str1(" Hello WOrLd! ");
cout << '[' << str1 << ']' << endl;
trim( str1 );
cout << '[' << str1 << ']' << endl;
return 0;
}
Rysunek 1. Kon�guracja narzędzia Microsoft Visual Studio przy pracy z biblioteką Boost String Algorithms
www.sdjournal.org 7
Biblioteka miesiąca
w postaci pojedynczego argumentu. Kon- wych ułatwiających implementację algo- dwie potrzeby i udostępnia swoje algo-
wencja STL (przekazywanie pary iterato- rytmów uogólnionych i w tym przypadku rytmy zarówno w wersjach modyfikują-
rów) daje oczywiście wielką elastyczność, idealnie spełnia swoją rolę. cych argumenty, jak i kopiujących nowy
aczkolwiek wiąże się z pewnymi ograni- • Modyfikowanie argumentów: w przy- wynik (te ostatnie można rozpoznać po
czaniami, między innymi z brakiem moż- kładzie pokazanym na Listingu 2 widzi- końcówce _ copy w nazwie funkcji).
liwości składania wywołań kilku funkcji my, że przy przetwarzaniu napisów cza- • Nazewnictwo: w tym przypadku Boost
czy z mniejszą czytelnością kodu. Złotym sami występuje potrzeba modyfikacji ar- String Algorithms trzyma się konwencji
środkiem stosowanym przez Boost String gumentów przekazywanych do funkcji, narzuconej przez bibliotekę standardową.
Algorithms jest inna biblioteka z pakie- a czasami chcielibyśmy zachować sobie W związku z tym nazwy algorytmów pi-
tu Boost: Range Library. Biblioteka ta jest kopię oryginalnego napisu. Biblioteka sane są małymi literami, zaś słowa w na-
zbiorem konceptów i narzędzi użytko- Boost String Algorithms respektuje oby- zwie rozdzielone są znakiem podkreśle-
nia. Oprócz końcówki _ copy, w przy-
Listing 3. Przykład użycia algorytmów przycinania padku funkcji zwracających wynikowy
napis, pojawia się jeszcze przedrostek i,
#include <boost/algorithm/string.hpp> występujący wtedy, gdy dany algorytm
#include <iostream> działa w sposób niezależny od wielkości
znaków (np.: ifind _ first()). Podobnie
using namespace std; postfiks _ if zarezerwowany jest dla algo-
using namespace boost; rytmów wykorzystujących predykaty de-
finiowane przez użytkownika.
#define DUMP( str ) cout << #str << " == \"" << str << "\"" << endl;
Operacje przycinania
int main() Gratuluję Ci Drogi Czytelniku! Szczęśliwie
{ przebrnąłeś przez wprowadzenie do tematu!
string str1 = " hello world! "; Czas przejść do konkretów. Na początek omó-
wimy operacje przycinania.
string str2 = trim_left_copy( str1 ); Idea tego typu operacji jest prosta: chodzi
DUMP( str2 ); // str2 == "hello world! " o to, aby usunąć z napisu zbędne znaki znaj-
dujące się na jego początku i/lub końcu. Mogą
string str3 = trim_right_copy( str1 ); być to wcięcia w kodzie źródłowym, znaki no-
DUMP( str3 ); // str3 == " hello world!" wego wiersza w kolejnych liniach pliku teksto-
wego czy pomyłkowo wpisane przez użytkow-
trim( str1 ); nika spacje w polu formularza.
DUMP( str1 ); // str1 == "hello world!" Boost String Algorithms oferuje nam trzy al-
} gorytmy odpowiadające za przycinanie:
8 03/2010
Programowanie w języku C++
Predykaty i klasyfikacja
Głównym zadaniem predykatu, w kontekście Listing 5. Przykład użycia algorytmu wyszukiwania
biblioteki Boost String Algorithms, jest spraw- #include <boost/algorithm/string.hpp>
dzenie, czy zadany napis spełnia określony wa- #include <boost/assign.hpp>
runek. Prezentowana biblioteka oferuje szereg #include <boost/foreach.hpp>
podstawowych predykatów (wszystkie one są #include <iostream>
zdefiniowane w nagłówku boost/algorithm/
string/predicate.hpp). Dla przykładu, predykat using namespace std;
istarts_with() weryfikuje, czy napis podany using namespace boost;
jako pierwszy argument rozpoczyna się od cią- int main()
gu znaków przekazanego jako argument drugi. {
Dodatkowo, przedrostek i na początku nazwy vector< char > text = boost::assign::list_of
predykatu sugeruje, iż w tym przypadku roz- ('H')('e')('l')('l')('o')(',')(' ')
miary liter w obydwu napisach nie będą bra- ('w')('o')('r')('l')('d')('!');
ne pod uwagę. iterator_range< vector< char >::iterator > result
Predykaty są bardzo użytecznym narzę- = find_last( text, "world" );
dziem w bibliotece Boost String Algorithms, if ( result )
gdyż można przekazywać je do algorytmów po {
to, aby dostosować ich działanie do indywidu- to_upper( result );
alnych potrzeb użytkownika. Co więcej, moż- }
na je łączyć ze sobą za pomocą operatorów lo- BOOST_FOREACH( char ch, text )
gicznych. Rozważmy przykład przedstawiony {
na Listingu 4. cout << ch;
Widać tutaj, na czym polega siła predyka- }
tów: w elegancki i prosty sposób jesteśmy w sta- cout << endl;
nie dopasować funkcjonalność algorytmów }
z rodziny trim do naszych potrzeb. W roz-
ważanym tu przypadku predykat złożony
Listing 6. Wyszukiwanie frazy na podstawie wyrażenia regularnego
jest z trzech klasyfikatorów. Zadaniem klasy-
fikatora jest sprawdzenie, czy wszystkie znaki #include <boost/algorithm/string.hpp>
w określonym napisie należą do określonej kla-
sy (np. czy są to cyfry bądź znaki alfabetu). Peł- // Dołączamy odpowiedni nagłówek, aby móc skorzystać z find_regex().
na lista klasyfikatorów dostępnych w ramach #include <boost/algorithm/string/regex.hpp>
Boost String Algorithms znajduje się w nagłów- #include <iostream>
ku boost/algorithm/string/classification.hpp.
W kolejnych punktach niniejszego artyku- using namespace std;
łu będę powracał jeszcze do tematu predyka- using namespace boost;
tów, pokazując konkretne przykłady ich zasto-
sowania. int main()
{
Operacje wyszukiwania // Wyrażenie regularne opisujące wzorzec adresu e-mail.
Biblioteka Boost String Algorithms udostęp- const static boost::regex email_regex(
nia cały szereg algorytmów pozwalających "[\\w.%-]+"
znajdować zadane ciągi znaków w napisach: "@"
"[A-Za-z0-9.-]+"
• find _ first() –znajduje pierwsze wystą- "\\.[A-Za-z]{2,4}" );
pienie napisu w wejściowym ciągu;
• find _ last() – znajduje ostatnie wystą- // Tekst zawierający adres e-mail.
pienie napisu w wejściowym ciągu; string text("my email adress is Rafal.Kocisz@gmail.com");
• find _ nth() – znajduje n-te wystąpienie
napisu w wejściowym ciągu (licząc od // Wyszukiwanie adresu e-mail w napisie.
zera); iterator_range< string::iterator > result = find_regex( text, email_regex );
• find _ head() – znajduje początkowy
fragment napisu o zadanej długości; // Jeśli wyszukiwanie się powidło, to zamieniamy wszystkie litery w
• find _ tail() – znajduje końcowy frag- // wyszukanym ciągu na małe.
ment napisu o zadanej długości; if ( result ) to_lower( result );
• find _ token() – znajduje pierwszy pasu-
jący token w napisie; // Wyświetlamy wyszukany ciąg na standardowym wyjściu.
• find _ regex() – znajduje fragment napi- cout << "Found: \"";
su pasujący do zadanego wyrażenia regu- copy( result.begin(), result.end(), ostream_iterator< char >( cout ) );
larnego; cout << "\"" << endl;
• find() – uogólniony algorytm wyszuki- }
wania.
www.sdjournal.org 9
Biblioteka miesiąca
10 03/2010
Programowanie w języku C++
www.sdjournal.org 11
Programowanie C++
K
opiowanie obiektów jest operacją ży robić głęboką kopię. Składową tą jest licz-
wykonywaną bardzo często: prze- Kopiowanie opóźnione nik odniesień lub flaga. Można pozbyć się
kazując argumenty przez wartość, Kopiowanie opóźnione lub leniwe wyko- tej składowej, tworząc głęboką kopię obiek-
zwracając wyniki obliczeń, przechowując rzystuje obie strategie kopiowania opisa- tu za każdym razem, gdy wołana jest opera-
elementy w kontenerach i w wielu innych
sytuacjach są tworzone kopie. Jeżeli obiekt Listing 1. Tworzenie kopii płytkiej i głębokiej
jest dostępny pośrednio, na przykład przez
wskaźnik, to można wykonać kopię wskaźni- class Foo { //klasa pomocnicza
ka (lub innego uchwytu) albo całego obiek- public:
tu. W związku z tym możemy wyróżnić trzy Foo() : i_(0) {}
rodzaje kopiowania: kopiowanie płytkie, gdy int get() const { return i_; }
kopiujemy uchwyty (wskaźniki), kopiowa- void set(int i) { i_ = i; }
nie głębokie, gdy tworzymy kopię obiektu, };
oraz kopiowanie leniwe, które łączy kopiowa- Foo* shellCopy(Foo* f) { //płytka kopia
nie płytkie i głębokie. Do demonstracji tych return f; //wskaźniki pokazują na ten sam obiekt
technik będziemy używali klasy Foo pokaza- }
nej na Listingu 1. Foo* deepCopy(Foo* f){ //głęboka kopia
Kopią płytką nazywa się kopiowanie jedy- return new Foo(*f); //wskaźniki pokazują na różne obiekty
nie obiektów pośredniczących, wskaźników, }
referencji, uchwytów itp. Kopia taka jest Foo* p1 = new Foo();
tworzona szybko, ponieważ wskaźnik lub in- Foo* p2 = shellCopy(p1); //płytka kopia
ny obiekt pośredniczący jest zazwyczaj ma- Foo* p3 = deepCopy(p1); //głęboka kopia
łym obiektem. Po wykonaniu płytkiej kopii p1->set(2); //zmiana obiektu wskazywanego przez p1
ten sam obiekt jest dostępny z wielu miejsc, assert( p2->get() == 2 ); //obiekt wskazywany przez p2 został zmieniony
obiekt wskazywany nie jest kopiowany, zmia- assert( p3->get() == 1 ); //obiekt wskazywany przez p3 nie został zmieniony
na jego stanu będzie widoczna we wszystkich
kopiach. Głęboka kopia oznacza rzeczywiste
12 3/2010
Wzorzec prototypu
cja modyfikująca, ale wtedy wiele kopii jest cja fastDeepCopy, pokazana na Listingu 3, SDJ 2/2010), a my dysponujemy tylko ty-
zbędnych. wykorzystuje dodatkowy argument, który pem interfejsu. Rzeczywisty typ obiektu
Przykład leniwego kopiowania został jest tworzony w czasie kompilacji na podsta- może być inny.
pokazany na Listingu 2. Przedstawiona wie informacji o typie. Jego wartość nie jest Wzorzec prototypu, nazywany też wir-
tam klasa wykorzystuje sprytne wskaźni- istotna, natomiast typ pozwala wybrać od- tualnym konstruktorem, opisany w książce
ki boost::shared_ptr, które zostały omó- powiednią funkcję kopiującą. Jeżeli obiekty ,,Wzorce projektowe'' przez „bandę czworga''
wione w SDJ 11/2009. Sprytne wskaźniki mogą być kopiowane za pomocą funkcji ko- (Gamma, Helm, Johnson, Vlissides), pozwa-
to szablony, które pozwalają automatycznie piującej fragmenty pamięci, to jest ona wo- la na tworzenie głębokiej kopii w takich przy-
usuwać obiekt utworzony na stercie, prze- łana, w przeciwnym wypadku woła się kon- padkach. Pomysł polega na przeniesieniu od-
chowują one i aktualizują licznik odnie- struktor kopiujący. Technika trejtów została powiedzialności za tworzenie obiektów do
sień do wskazywanego obiektu. Szablony opisana w SDJ 11/2009. klas konkretnych, wykorzystując mechanizm
te wspierają tworzenie leniwej kopii, dostar- funkcji wirtualnych. Klasa bazowa dostarcza
czają metodę unique, która pokazuje, czy Wzorzec prototypu metody czysto wirtualnej, która jest nadpi-
zarządzany obiekt jest wskazywany przez Jeżeli posługujemy się wskaźnikiem lub re- sywana w klasach konkretnych (gdzie znany
jeden, czy więcej wskaźników. Metoda ta ferencją do klasy bazowej, to możemy wy- jest typ), więc można utworzyć głęboką kopię
jest wykorzystana w klasie LazyFoo do roz- konać jedynie płytką kopię. Kopia głęboka obiektu. Przykład pokazano na Listingu 4,
strzygania, czy można modyfikować bieżący jest niedostępna, ponieważ przy tworzeniu klasa bazowa Figure dostarcza metody czy-
obiekt, czy raczej należy zrobić kopię. obiektu należy podać konkretny typ (patrz sto wirtualnej clone. Metoda ta jest nadpisy-
Tworząc kopię głęboką obiektu tymcza-
sowego, który będzie usunięty po zakoń- Listing 2. Leniwa kopia z użyciem boost::shared_ptr
czeniu operacji kopiowania, można wyko-
nać kopię płytką i nie usuwać tego obiek- class LazyFoo { //przechowuje leniwą kopię obiektu typu Foo (Listing 1)
tu, co przypomina przeniesienie właściciela public:
obiektu. Taki mechanizm dla wskaźników LazyFoo(int i) : ptr_(new Foo(i) ) {}
dostarcza std::auto_ptr (SDJ 11/2009), LazyFoo(const LazyFoo& l) : ptr_(l.ptr_) {}
w ogólnym przypadku wymaga on wspar- int get() const { return ptr_->get(); }
cia w języku. Takie wsparcie będzie dostar- void set(int i) { //metoda zmienia stan obiektu
czone w nowym standardzie C++200x po- if(ptr_.unique() ) { ptr_->set(i); } //bada czy istnieje konieczność
przez referencję do r-wartości, co pozwoli tworzenia kopii
na implementację różnych konstruktorów else { ptr_ = PFoo(new Foo(i) ); }
kopiujących. Używając konstruktora ko- }
piującego do r-wartości, będzie można prze- private:
nieść zawartość obiektu, unikniemy wtedy typedef shared_ptr<Foo> PFoo;
zbędnej kopii. PFoo ptr_;
};
Szybkie kopiowanie głębokie
Dla pewnych typów obiektów kopia głęboka
może być wykonana bez użycia konstrukto- Listing 3. Wykorzystanie klasy cech do wyboru algorytmu kopiowania
ra kopiującego za pomocą operacji kopiują-
cych fragmenty pamięci. Obiekty, które bę- template<typename T> //kopiowanie za pomocą memcpy
dą w ten sposób kopiowane, nie mogą mieć T* doFastDeepCopy(const T* element, true_type) {
składowych, które są wskaźnikami, bo wska- char* mem = new char[sizeof(T)]; //przydziela pamięć
zywane przez te składowe obiekty także bę- memcpy(mem, element, sizeof(T));
dą musiały być kopiowane przy tworze- return reinterpret_cast<T*>(mem);//zwraca obiekt odpowiedniego typu
niu kopii głębokiej. Informacji o tym, czy }
obiekt może być kopiowany za pomocą ko- template<typename T> //woła konstruktor kopiujący
piowania bajtów, dostarcza klasa cech (trejt) T* doFastDeepCopy(const T* element, false_type) {
has_trivial_copy , który jest dostarcza- return new T(*element);
ny przez bibliotekę boost::traits. Funk- }
template<class T> //algorytm tworzenia kopii wykorzystuje trejty
T* fastDeepCopy(const T* element) {
www.sdjournal.org 13
Programowanie C++
ROBERT NOWAK
Więcej w książce Adiunkt w Zakładzie Sztucznej Inteligencji Insty-
Zagadnienia dotyczące współcześnie stosowanych technik w języku C++, wzorce projekto-
we, programowanie generyczne, prawidłowe zarządzanie zasobami przy stosowaniu wy- tutu Systemów Elektronicznych Politechniki War-
jątków, programowanie wielowątkowe, ilustrowane przykładami stosowanymi w bibliotece szawskiej, zainteresowany tworzeniem aplikacji
standardowej i bibliotekach boost, zostały opisane w książce ,,Średnio zaawansowane pro- bioinformatycznych oraz zarządzania ryzykiem.
gramowanie w C++'', która ukaże się niebawem. Programuje w C++ od ponad 10 lat.
Kontakt z autorem:rno@o2.pl
14 3/2010
Opis DVD
15
Programowanie Java
Przewodnik po SCJP
Czyli certyfikat z Javy – część 3
Proces zdobywania certyfikatów, potwierdzających umiejętności
z różnych dziedzin wiedzy, stał się jednym z ważniejszych elementów
osobistego rozwoju. Proces ten ma miejsce również w branży IT;
certyfikaty dla programistów (Java lub .NET), administratorów czy
sieciowców (Cisco) można coraz częściej odnaleźć w CV osób starających
się o pracę, zwłaszcza w owianym złą sławą kryzysie gospodarczym.
List lista = new List();
Dowiesz się: Powinieneś wiedzieć: lista.add(new Integer(3));
• Jakie klasy uczestniczą w procesie i18n; • Jak skompilować i uruchomić programy
• Jakie klasy wejścia/wyjścia musisz znać do w Javie; Ten krótki fragment kodu prezentuje działa-
egzaminu; • Jakie są podstawy składni języka; nie klasy opakowującej (z ang. wrapper) dla ty-
• Na czym polega mechanizm autoopakowy- • Jakie są ogólne zasady korzystania z API pu int. Wartość typu prymitywnego (3) zo-
wania. w Javie. stała przekazana do konstruktora tej klasy. No-
wo utworzony obiekt możemy bez przeszkód
dodać do listy.
niach (podstawy omówimy jedynie w przy- Na podobnej zasadzie funkcjonują pozo-
padku asercji); kluczowe są przeróżne sztuczki stałe klasy opakowujące. Tabela 1 zawiera spis
Poziom i ruczki, za pomocą których twórcy egzaminu wszystkich typów prymitywnych i odpowiada-
trudności chcą utrudnić programistom zdanie go. jących im klas.
Wiemy już, jak zamienić wartość typu pry-
Typy prymitywne a sprawa klas mitywnego na obiekt, a co z operacją odwrotną?
Programowanie w Javie wiąże się nieodłącznie Wystarczy skorzystać z metody intValue(),
W
trzeciej części cyklu artykułów, z wykorzystywaniem obiektów. Trudno zna- aby uzyskać wartość prymitywną:
poświęconego przygotowaniom leźć program, który ich nie używa. Jak już zosta-
do egzaminu Sun Certified Java ło wcześniej napisane, w Javie posługujemy się Integer obiekt = (Integer)lista.get(0);
Programmer for Java SE 6, zajmiemy się kolej- referencjami do obiektów, a nie obiektami sa- int liczba = obiekt.intValue();
nym zagadnieniem – API Contents, czyli głów- mymi w sobie. Oznacza to, że dowolna zmien-
nie (acz nie tylko) funkcjonalnością J2SE. na nie przechowuje obiektu, a jedynie odniesie- Przedstawione powyżej rozwiązania są jak
W trakcie omawiania niniejszego zagadnie- nie (wskaźnik) do niego. Gwoli ścisłości trzeba najbardziej poprawne. Już w tym momen-
nia zwrócimy uwagę na kilka zasadniczych po- jednak zaznaczyć, że nie wszystkie zmienne są cie wiem, że niejeden Czytelnik zdążył zapro-
dzagadnień: powiązane z obiektami! W przypadku typów testować – „Przecież wywołanie rodzaju li-
prymitywnych (int, char, byte, boolean, float, sta.add(3); działa! O co tutaj chodzi?”.
• Klasy opakowujące typy prymityw- double, short, long) zmienne przechowują war- Problem wynika, jak to zwykle w takich sy-
ne (m.in. Integer, Character, Byte) tości tych typów, a nie referencje do nich. Teoria tuacjach, z powodów historycznych. Powyższe
i związane z nimi operacje automatyczne- teorią, ale jak to stwierdzenie ma się do codzien- rozwiązanie jest jedynym poprawnym rozwią-
go pakowania/rozpakowania; nej pracy programisty? zaniem w Javie do wersji 1.4 włącznie. Od Javy
• Operacje na łańcuchach znaków i podobne; Zasada jest prosta. Z formalnego punktu wi- 5 wprowadzono mechanizm autoopakowania
• Operacje na plikach z wykorzystaniem dzenia we wszystkich metodach, które przyj- (ang. autoboxing), który odpowiada za automa-
klas czytających/zapisujących (Reader / mują jako parametr(y) obiekt(y), przekaza- tyczne opakowywanie wartości prymitywnych,
Writer i pochodne); nie zmiennej typu prymitywnego to błąd. Ko- jak i ich powrotną konwersję:
• Dostosowywanie informacji (teksto- nieczne jest zastosowanie obiektu specjalnej kla-
wych, liczbowych, dat) do ustawień sy (innej dla każdego typu prymitywnego), któ- lista.add(5);
regionalnych – klasy DateFormat, ry „opakuje” zmienną prymitywną. Jako pełno- int liczba = (int)lista.get(0);
NumberFormat, Locale ; prawny obiekt będzie można go przekazać do
• Wykorzystywanie wyrażeń regularnych żądanych metod. Rzutowanie jest niezbędne do wykonania kon-
w praktyce. O jakich metodach mowa? Chociażby o naj- wersji z typu Object (nasza przykładowa lista
prostszych operacjach związanych z kolekcja- nie jest generyczna), jednak pośrednia kon-
Podobnie jak w poprzednich artykułach, nie mi (więcej na ich temat w jednym z kolejnych wersja do typu Integer dokonuje się automa-
będziemy skupiać się na całych zagadnie- artykułów): tycznie.
16 03/2010
Certyfikat SCJP
Na szczęście zadania związane z klasami opa- go fragmentu brzmi: 3 (dwa z nich zostały wyja- StringBuilder i StringBuffer
kowującymi nie są trudne; część z nich (związa- śnione, a trzeci musisz znaleźć samodzielnie). – tacy sami, ale nie ci sami...
na z przeciążaniem metod) została omówiona Na zakończenie tego podzagadnienia nie Przy przetwarzaniu względnie dużej ilości in-
w pierwszej części kursu (SDJ 11/09). Przede mógłbym pominąć kwestii puli łańcuchów formacji z użyciem klasy String mogą wystąpić
wszystkim, musisz pamiętać dokładnie nazwy (ang. string pool). Dzięki niezmienności łańcu- problemy związane z wydajnością. Załóżmy, że
klas. Trzeba uważać, aby nazwy klas opakowują- chów możemy osiągnąć pewne korzyści. Załóż- w jakimś programie podczas wczytywania da-
cych nie pomyliły Ci się z nazwami typów. my, że tworzysz łańcuch za pomocą bezpośred- nych cyklicznie dołączamy znaki do łańcucha.
niego przypisania: Oznacza to, że każde dołączenie tworzy nowy
Łańcuchowe szaleństwo łańcuch, a jednocześnie przeznacza do usunię-
Krótki opis klas opakowujących z poprzednie- String s = "tekst"; cia stary. Co za tym idzie – jeśli w swoim pro-
go ustępu ułatwia zrozumienie działania typów gramie chcesz intensywnie modyfikować i two-
prymitywnych w obiektowym świecie. Nie Java w tym momencie dodaje do owej puli wy- rzyć nowe łańcuchy, absolutnie nie powinieneś
wspomniałem w nim jednak o jednej z klas, któ- żej wymieniony literał tekstowy. Jeśli w dal- używać do tego celu klasy String.
ra chyba najczęściej jest zaliczana do typów pry- szym fragmencie kodu ten sam literał pojawi Z powyższego kłopotu wybawią Cię kla-
mitywnych w Javie. Mowa o klasie String. się ponownie: sy StringBuilder i StringBuffer. Obie kla-
Klasa String odpowiada za przechowywanie sy mają identyczną funkcjonalność, która spro-
tekstów – zbiorów znaków. Klasa ta otrzymała String s2 = "tekst"; wadza się do możliwości dynamicznego dołą-
(jako jedyna) od twórców Javy specjalne przywi- czania, usuwania i modyfikacji znaków w ob-
leje – możemy w jej przypadku korzystać z ope- to zamiast tworzyć nowy obiekt, JVM skorzy- rębie wewnętrznego bufora. Różnią je dwie
ratorów + i = (co nie jest możliwe w przypadku sta z obiektu istniejącego już w puli! Nie daj się cechy – klasa StringBuffer jest synchronizo-
innych klas, bo przeciążanie operatorów jako ta- zatem zwieść – wywołanie dwóch instruk- wana (dzięki czemu dostęp do obiektu tej kla-
kie w Javie nie występuje). Początkujący progra- cji w obrębie jednego bloku kodu spowoduje sy przez różne wątki nie spowoduje powstania
mista, widząc taki zapis: utworzenie tylko jednego obiektu! Jednak już bezsensownych danych), a StringBuilder nie
utworzenie łańcucha znaków za pomocą kon- (dzięki czemu działa ona nieznacznie szybciej);
String s = "tekst"; struktora: ponadto klasa StringBuilder została wprowa-
s = s + "inny"; dzona dopiero w Javie 5.
String s3 = new String("tekst"); Funkcjonalność obu klas stanowi połączenie
może istotnie pomylić klasę String i uznać ją niektórych możliwości klasy String (np. meto-
za typ prymitywny. To jednak nie koniec pro- spowoduje utworzenie nowego obiektu. dy substring(), length(), indexOf()) z ope-
blemów – z klasą String wiąże się wiele cie- racjami dołączania (append()), wstawiania (in-
kawych zagadnień, które mogą znaleźć się na Metody klasy String sert()) i usuwania (delete()) znaków. Zwróć
Twoim egzaminie. Nie będziemy w tym miejscu dogłębnie oma- uwagę, że te trzy metody, wraz z kilkoma po-
Zaczniemy z wysokiego c – zajmiemy się wiać metod klasy String. Opis działania moż- dobnymi metodami tej klasy, zwracają zmody-
kwestią modyfikowalności, inaczej zwaną na zobaczyć w dokumentacji. Warto jednak fikowany obiekt. Dzięki temu możesz tworzyć
zmiennością (z ang. mutability). Cechą charak- zwrócić uwagę na kilka szczegółów, dotyczą- (nomen omen) łańcuchy wywołań:
terystyczną łańcuchów jest ich niezmienność. cych wszystkich metod:
Oznacza to, że w raz utworzonym łańcuchu nie StringBuffer sb = new StringBuffer();
możesz zmienić np. drugiego znaku. Co więcej, • Opanuj arytmetykę łańcuchową, czyli wy- sb.append("tekst").append("
nie możesz także dołączać innych łańcuchów liczanie znaku na danej pozycji, a także inny").delete(1, 2);
na początku, ani na końcu już istniejącego łań- uwzględnianie w obliczeniach długości łań-
cucha. To zdanie jest sprzeczne z powyższym cuchów. Nie jest to skomplikowane, jednak Konwersję do zwykłego łańcucha znaków uzy-
przykładem, więc spieszę z wyjaśnieniem – w bardziej złożonych przykładach określa- skuje się za pomocą metody toString(). Na
drugi wiersz (z operacją konkatenacji – złącza- nie podłańcuchów może zająć trochę czasu. egzaminie podchwytliwymi mogą okazać się
nia łańcuchów) nie zmienia obiektu tekst, tylko • Zapoznaj się z metodą intern(). W prak- pytania związane z arytmetyką łańcuchów –
tworzy zupełnie nowy obiekt, zawierający tekst tyce jest ona wykorzystywana niezwykle zwróć uwagę, że w metodzie delete() (i kilku
tekstinny. Nie zapominaj, że zmienna s jest jedy- rzadko, jednak na egzaminie może poja- podobnych) indeks początkowy jest wliczany
nie referencją! Po wykonaniu pierwszej instruk- wić się w kontekście zagadnienia opisane- do wykonywanej operacji (inclusive), a indeks
cji wskazuje ona na jeden obiekt, a po wykona- go w poprzednim akapicie. końcowy – nie (exclusive)!
niu drugiej – już na zupełnie inny! • Zwróć uwagę, że drugim parametrem me-
W tym momencie dochodzimy do często tody substring() jest indeks ostatniego Tabela 1. Typy prymitywne i odpowiadające im
spotykanego na egzaminach pytania – na pod- znaku, a nie liczba znaków do pobrania! klasy opakowujące
stawie fragmentu kodu musisz określić, ile • W ramach ćwiczeń dotyczących arytme- Nazwa typu Klasa opakowująca
obiektów typu String zostało w nim utworzo- tyki łańcuchowej uwzględnij intensywne prymitywnego
nych. Odpowiedź na to pytanie dla poprzednie- użycie metod substring() i replace(). int Integer
boolean Boolean
Listing 1. Schemat wyświetlania sformatowanej daty byte Byte
// Wyświetla aktualną datę w najbardziej rozbudowanym formacie obowiązującym w USA char Character
Locale l = new Locale("en","US"); short Short
Calendar c = Calendar.getInstance(l);
long Long
DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, l);
�oat Float
System.out.println(df.format(c.getTime()));
double Double
www.sdjournal.org 17
Programowanie Java
Pytania
Oczywiście każda z klas dokładnie określa, ja- 1. Wybierz instrukcje, które nie spowodują błędu kompilacji przy następującej deklaracji:
kie obiekty można przekazać w konstruktorze. List<Integer> lista = new List<Integer>();
Jednym z najczęściej spotykanych typów zadań a) lista.add(new Integer(3));
egzaminacyjnych jest wybór poprawnych kon- b) lista.add(3);
c) lista.add(new Integer(3).intValue());
struktorów dla danej klasy. W przypadku klasy
d) lista.add(new Integer(3).valueOf(3));
BufferedReader możemy skorzystać jedynie
z klas pochodzących od klasy Reader. 2. Które z poniższych wyrażeń zwróci tekst 1232345?
Same operacje zapisu i odczytu nie są trak- a) String s = "12345";
towane w specjalny sposób. Inaczej ma się sytu- s.substring(1, 4).substring(2,3) + "2345");
b) new StringBuffer("12345").append("45").replace(3, 5, "23");
acja z operacjami na samych plikach, a nie we-
c) new StringBuffer("54321").insert(2,new StringBuffer("2323").reverse().subs
wnątrz nich. Musisz więc wiedzieć, jakie możli- tring(2)).reverse().append("23").delete(4, 6)
wości oferuje klasa File. Standardowo zalecam
więc zwracanie uwagi na nazwy metod, przyj- 3. Wybierz wywołania, które skompilują się poprawnie:
mowane przez nie parametry i typy zwraca- a) BufferedReader br = new BufferedReader(new File("plik.txt"));
b) FileReader file = new FileReader(new InputStreamReader("plik.txt"));
nych obiektów.
c) PrintStream ps = new PrintStream("plik.txt");
d) PrintWriter pw = new PrintWriter(new File("plik.txt"));
Wyświetlanie danych
Gdy dysponujesz już danymi pobranymi z pli- 4. Wybierz poprawny(-e) schemat(y) prowadzący do wyświetlenia sformatowanej daty:
ku, musisz je w jakiś sposób wyświetlić. Twór- a) utworzenie obiektu klasy Locale -> utworzenie obiektu typu Date -> utworzenie obiektu
cy pytań egzaminacyjnych o tym nie zapo- formatującego NumberFormat -> pobranie daty z kalendarza -> wyświetlenie daty
b) utworzenie obiektu typu Date -> utworzenie obiektu formatującego DateFormat -> wy-
mnieli, dzięki czemu ten dość specyficzny te- świetlenie daty
mat jest traktowany na egzaminie stosunkowo c) pobranie obiektu typu Calendar -> utworzenie obiektu formatującego DateFormat ->
poważnie. pobranie daty -> wyświetlenie daty
Aby proces formatowania tekstu nie wydał
się zbyt prosty, musisz w nim uwzględnić usta- 5. Wybierz prawidłowe odpowiedzi:
a) Poniższy kod wyświetli tekst 0 abaabc:
wienia regionalne, specyficzne dla danego kra- Pattern p = Pattern.compile("[abc]+");
ju (a nawet regionu) – za co odpowiada osobna Matcher m = p.matcher("abaabc");
klasa o nazwie Locale. To właśnie ona, w połą- while (m.find())
System.out.println(m.start()+" "+m.group());
czeniu z klasą DateFormat (w przypadku dat)
b) Poniższy kod wyświetli tekst 0 abaabc:
i NumberFormat (w przypadku liczb i walut), Pattern p = Pattern.compile("[abc]+");
pozwala na pełną kontrolę sposobu wyświetla- Matcher m = new Matcher(p).matcher("abaabc");
while (m.find())
nia danych. Do kompletu przyda się odrobina System.out.println(m.start()+" "+m.group());
wiedzy na temat klas Calendar i Date; czasa- c) Poniższy kod wyświetli tekst 0 0 1 1 2 2 3 3
mi trzeba przecież wykonywać operacje zwią- Pattern p = Pattern.compile("\d+\s");
zane z datami. Matcher m = p.matcher("0 1 2 3 ");
while (m.find())
Zagadnienie samo w sobie jest dość cie- System.out.println(m.start()+" "+m.group());
kawe, jednak nam przyświeca konkretny cel
18 03/2010
Certyfikat SCJP
• getCurrencyInstance() – zwraca obiekt ustawień regionalnych z określonym sty- Klasa Pattern reprezentuje pojedyncze wyra-
formatujący z uwzględnieniem konwencji lem daty. żenie regularne. Aby uzyskać obiekt tej klasy, mu-
zapisu walut. • getDateInstance() i getInstance() sisz skorzystać ze statycznej metody compile():
– pobierają formater dostosowany do do-
Powyższe wersje metod zwracają obiekty do- myślnych ustawień regionalnych ze sty- Pattern p = Pattern.compile("\s[a-z]+\s");
stosowane do domyślnych ustawień regional- lem DEFAULT – w przypadku metody
nych – istnieją też warianty tych metod, przyj- getDateInstance() i ze stylem SHORT – Powyższe wyrażenie regularne dopasowuje
mujące obiekt klasy Locale. Po utworzeniu w przypadku metody getInstance(). ciąg słów (pisanych małych literami), bez pol-
obiektu nie pozostaje Ci nic innego, jak wy- skich znaków, przedzielonych białymi znaka-
wołać metodę format(), aby wyświetlić liczbę Styl daty określa sposób wyświetlania daty i cza- mi. Po utworzeniu obiektu musisz skorzystać
w żądany sposób: su – do dyspozycji masz zbiór kilku stałych, za- z metody matcher(), aby dopasować podane
deklarowanych w klasie DateFormat: (DEFAULT, wyrażenie regularne do danych wejściowych:
System.out.println(numberFormatter.format(3 SHORT, FULL, MEDIUM , LONG). Ich dokładne warto-
000000)); ści zależą od ustawień regionalnych. Warto za- Matcher m = p.matcher("test");
uważyć, że obecnie domyślny styl daty przecho-
Nieco bardziej skomplikowany schemat obo- wuje tę samą wartość, co styl MEDIUM . Jeśli chcesz Teraz możesz zacząć przeszukiwać dane wej-
wiązuje w przypadku formatowania daty. Po sformatować także czas, skorzystaj z metod za- ściowe, pobierając informacje na temat kolej-
pierwsze, musisz najpierw pobrać datę, a po wierających dodatkowo słowo Time w nazwie. nych pasujących do wyrażenia regularne pod-
drugie – utworzenie obiektu formatujące- Po uzyskaniu obiektu musisz wywołać meto- ciągów:
go dla dat jest bardziej złożone. Zacznijmy od dę parse(), podając jako argument obiekt daty.
pierwszego etapu. Cały kod (dla wariantu z datą) jest przedstawio- while (m.find()) {
Uzyskanie obiektu klasy Date, który można ny na Listingu 1. System.out.println(m.start() + " " +
sformatować za pomocą klasy DateFormat, jest Cały schemat wyświetlania danych przedsta- m.group());
możliwe na dwa sposoby. Po pierwsze, możesz wiłem dość drobiazgowo, ponieważ równie dro- }
po prostu utworzyć obiekt: biazgowe pytania mogą pojawić się na egzami-
nie. Jeśli jakiś element pojawił się w moim omó- Metoda start() zwraca indeks początkowy
Date d = new Date(); wieniu, oznacza to, że ma on znaczenie. podciągu, który pasuje do wyrażenia, a meto-
da group() – cały podciąg. Metoda find() wy-
Obiekt d zawiera datę i czas jego utworzenia. Wyrażenia regularne (nie)?fajne szukuje kolejne podciągi pasujące do wyraże-
Możesz skorzystać z metod klasy Date; jest jed- są\? nia. Dopóki wyszukiwanie będzie przynosiło
nak jedno małe „ale”. Metody te zostały uzna- Obsługa wyrażeń regularnych stanowi istotne wyniki – będzie zwracana wartość true.
ne za przestarzałe już w JDK 1.1. Znamieni- zagadnienie w chyba każdym szanującym się ję- Powyższy schemat jest jednym z najczęściej
ta funkcjonalność tej klasy została zastąpiona zyku programowania, dlatego nie mogło jej za- sprawdzanych mechanizmów na egzaminie.
przez klasę Calendar. Uzyskanie obiektu kla- braknąć w Javie, jak również na egzaminie. Wie- Warto wiedzieć, że do sprawdzenia pojedyn-
sy Date w przypadku tej klasy wymaga wyko- dza niezbędna na egzaminie składa się z dwóch czego dopasowania możesz skorzystać z meto-
nania dwóch kroków: podzagadnień: znajomości wybranych wyrażeń dy matches() obiektu klasy Matcher (utwo-
regularnych, jak również sprawnego poruszania rzonego w taki sam sposób, jak w poprzednim
• pobrania obiektu klasy Calendar – za po- się wśród klas je obsługujących. Samo omówie- przykładzie):
mocą metody getInstance() dla domyśl- nie wyrażeń regularnych (z uwagi na ograniczo-
nych ustawień regionalnych lub z parame- ny rozmiar artykułu) sprowadzę jedynie do ich boolean pasuje = m.matches();
trem klasy Locale; wypisania (za java.sun.com):
• wywołania metody getTime(). Zagadnienie serializacji i obsługa metody
. (kropka), * (gwiazdka), +, ?, \d, \s, \w, [], (). printf(), które w pewnych zestawach ćwi-
Gdy dysponujesz obiektem do sformatowania, czeniowych pojawia się w ramach tego dzia-
musisz jeszcze utworzyć obiekt formatujący Nawiasy są wykorzystywane jedynie do grupo- łu, zostanie omówione w jednym z kolejnych
klasy DateFormat. W tym przypadku również wania (bez obsługi przechwytywania). Kwan- artykułów.
możesz skorzystać z metod statycznych: tyfikatory *, + i ? występują jedynie w wersji za- W tym momencie nie pozostało Ci nic inne-
chłannej. Informacje na temat powyższych in- go, jak rozwiązać zadania załączone do tego ar-
• getDateInstance(int styl, Locale lokale) formacji w Internecie znajdziesz bez liku. Gdy tykułu. Powodzenia!
– pobiera formater dostosowany do ustawień wyrażenia regularne staną się dla Ciebie banal-
regionalnych z określonym stylem daty. ne, możesz zacząć z nich korzystać z Javie, ko-
• getDateInstance(int styl) – pobie- rzystając z wielu klas. Zaczniemy od najbar-
Bibliogra�a:
ra formater dostosowany do domyślnych dziej standardowych – Pattern i Matcher. • Sierra K., Bates B. – Sun Certi�ed Pro-
grammer for Java 5 Study Guide
otrzymasz tekst 0 0 2 1 4 2 6 3.
że metoda start() będzie zwracać kolejne indeksy zliczane wraz ze spacjami, więc na standardowym wyjściu
5. a – b nie, ponieważ klasa Matcher nie zawiera konstruktora. Przykład c jest prawie dobry – problem w tym,
jest też dwukrotne pobieranie daty, chociaż nie jest to formalnie rzecz biorąc błąd.
4. b, c – a nie, ponieważ do formatowania daty nie korzystamy z obiektu typu NumberFormat. Niepotrzebne
KRZYSZTOF RYCHLICKI KICIOR
3. a, c, d – b nie, ponieważ konstruktor klasy FileReader nie przyjmuje jako argumentu obiektu klasy Reader. Autor programuje w Javie i .NET. Pisze książki i ar-
potwierdzić wyniki). tykuły na różne tematy związane z programowa-
niem. Jest posiadaczem certy�katu SCJP i SCWCD;
2. b – pozostałe warianty generują inne wartości (sprawdź jakie, a następnie skompiluj podane wyrażenia, aby
metr przyjmuje łańcuch znaków.
1. a, b, c. Odpowiedź d jest nieprawidłowa, ponieważ metoda valueOf() jest statyczna, a dodatkowo jako para- od kwietnia 2007 do kwietnia 2008 legitymował
się tytułem Microsoft MVP w kategorii Visual C#.
Odpowiedzi
Kontakt z autorem: kitikatpl@gmail.com
www.sdjournal.org 19
Sztuczna inteligencja
Paradygmat
programowania CLP
Metody rozwiązywania trudnych problemów
kombinatorycznych.
Wysoka efektywność metod CLP jest rezultatem wykorzystania procedur
propagacji ograniczeń oraz dystrybucji zmiennych, w celu poszukiwania
rozwiązań spełniających wszystkie przyjęte ograniczenia. Procesy te
realizowane są w sposób klasyczny, jak i rozproszony, dając bardzo dobre
rezultaty obliczeniowe.
blem) oraz wersję dynamiczną DynCSP
Dowiesz się: Powinieneś wiedzieć: (Dynamic CSP - składa się ona ze skończo-
• O deklaratywnym podejściu do zapisu/ • O zagadnieniach optymalizacji oraz wybranych nej sekwencji klasycznych problemów CSP
rozwiązywania trudnych problemów decy- aspektach z obszaru badań operacyjnych; (np.: csp(0), csp(1),…, csp(n)), w której każdy
zyjnych; • Podstawowe informacje na temat paradyg- podproblem jest inny – np. poprzez zmia-
• Informacji o różnych wariantach reprezentacji matów programowania oraz algorytmiki; nę ograniczeń w kolejnych krokach). Sku-
wiedzy dla problemu spełnienia ograniczeń; • Obszary sztucznej inteligencji z zakresu sys- piają się one na odpowiednim zapisie pro-
• Jakie rodzaje narzędzi oraz mechanizmów temów wieloagentowych (MAS). blemu w celu jego rozwiązania przez sys-
są nieodłączną częścią paradygmatu CLP. tem. System taki musi być odpowiednio
wyposażony w mechanizmy oraz algoryt-
my heurystyczne, służące do poszukiwa-
wionych metod programowania zaowoco- nia rozwiązania.
wało stworzeniem narzędzia (podejścia), Kolejnym obszarem silnie badanym są
które w większości zastosowań jest bardziej też poszczególne warianty optymalizacji
Poziom wydajne od zwykłego programowania lo- problemu spełnienia ograniczeń. Warianty
trudności gicznego. Stale przybywa sporo nowej wie- takie dla konkretnej odmiany czy podejścia
dzy na temat rozwiązywania problemów przedstawiają się następująco: CSOP (Con-
z ograniczeniami oraz rozwijane są meto- straint Satisfaction Optymization Problem)
S
ystemy klasy CLP (Constraint Logic dy optymalizacji trudnych do rozwiązania – dla klasycznego problemu oraz DCOP
Programming) są szczególną odmia- problemów. Sama technika nie jest do koń- (Distributed Constraint Optymization Pro-
ną mechanizmów opartą o paradyg- ca zrozumiała przez wielu ludzi i jest przez blem) – dla problemu rozproszonego. Dla-
mat programowania z ograniczeniami. Me- to mało popularna. Zupełnie odwrotnie ma tego celem artykułu jest przegląd obejmu-
toda CLP łączy w sobie dwa paradygma- się to do jej efektywności, która jest wyso- jący przedstawienie reprezentacji wiedzy
ty programowania: programowanie logicz- ka. Jak można zauważyć, systemy takie ma- w wybranych obszarach zapisu problemu
ne (Logic Programming) oraz programowa- ją wiele możliwych oraz naturalnych do im- oraz przedstawienie narzędzi. Aby opisy-
nie z ograniczeniami (Constraint Program- plementacji zastosowań. Z powodzeniem wane zagadnienia były lepiej zrozumiałe,
ming). W przeciwieństwie do imperatyw- można je stosować w rzeczywistych środo- dołączono także przykłady, odnoszące się
nych języków programowania, w których wiskach produkcyjnych, w których są odpo- do wybranego zapisu problemu.
podaje się sekwencje poleceń do wykona- wiednim rozwiązaniem systemowym.
nia, w językach programowania logicznego Rzeczywiste problemy
specyfikuje się zestaw zależności, na pod- Różne warianty modelu CLP Główne obszary zastosowań opisywanych
stawie których system dedukcyjny próbu- W wypracowanych dotychczas wariantach technik obejmują zadania klasy kombina-
je udowodnić zadane twierdzenie. Z ko- istnieje wiele stosowanych odmian tego pa- torycznej oraz optymalizacji dyskretnej.
lei programowanie z ograniczeniami pole- radygmatu. Możemy wyróżnić podejście W szczególności technika ta znajduje zasto-
ga na podaniu pewnych ograniczeń, które klasyczne do rozwiązania problemu: czyli sowanie do sterowania dyskretnymi procesa-
określają właściwości poszukiwanego roz- problem CSP (Constraint Satisfaction Pro- mi produkcyjnymi. W tych obszarach opi-
wiązania. Wyrażają one relacje pomiędzy blem), jego wersję rozproszoną - DisCSP sywane narzędzie obliczeniowe jest bardzo
zmiennymi. Połączenie dwóch przedsta- (Distributed Constraint Satisfaction Pro- przydatne między innymi dla:
20 03/2010
Paradygmat programowania CLP
• wspomagania harmonogramowania; poszukiwania rozwiązań, czynią środowi- ne przy budowie dedykowanych systemów
• szeregowania zadań, a w szczególności ska CLP bardzo atrakcyjnym do szybkiego wspomagania decyzji, które charakteryzują
przydziału zadań i zasobów dla poszcze- modelowania i rozwiązywania problemów się specyficznymi właściwościami, struktu-
gólnych maszyn; decyzyjnych. Jest to szczególnie przydat- rą czy ograniczeniami.
• optymalizacji planu dla projektu.
Klasyczny problem
spełnienia ograniczeń ���
� � �
Programowanie w logice z ograniczeniami
CLP(Constraint Logic Programming) to dzie-
dzina nauki, którą można ulokować pomię- ���
� �
dzy sztuczną inteligencją, badaniami ope-
racyjnymi oraz językami programowania.
Jest paradygmatem (koncepcją czy też tech-
niką) programowania tak jak np. programo- �
wanie zorientowane obiektowo czy progra-
mowanie funkcyjne (które to jest filozofią
programowania będącą odmianą progra-
Rysunek 2. Graf wartości zmiennych oraz relacje ograniczeń pomiędzy nimi
mowania deklaratywnego, w której funkcje
należą do wartości podstawowych, a nacisk
kładzie się na wartościowanie funkcji, a nie
na wykonywanie poleceń). Koncepcja ta
stosowana jest do modelowania, rozwiązy-
wania oraz zapisu problemów, które mogą
być dane za pomocą zbioru zmiennych i ich
dziedzin, oraz relacji pomiędzy nimi wyra-
żonych w postaci ograniczeń. Ograniczenia
takie odzwierciedlają zależności pomiędzy
zmiennymi problemu. Łatwość modelo-
wania problemów decyzyjnych, a w szcze-
gólności tych, które posiadają w swojej na-
turze ograniczenia, brak przepaści seman-
tycznej pomiędzy modelem a metodyką je-
go rozwiązywania oraz efektywne metody Rysunek 3. Przeszukiwanie przestrzeni rozwiązań: a) algorytmy standardowe; b) zawężanie dziedziny
www.sdjournal.org 21
Sztuczna inteligencja
De�nicja CSP
����������������� Podstawowym zagadnieniem reprezentacji wie-
������������������� dzy w programowaniu w logice z ograniczenia-
��� ����������
mi jest tzw. problem spełnienia ograniczeń CSP
(Constraint Satisfaction Problem). Klasyczny pro-
blem spełnienia ograniczeń zapisujemy w po-
� staci trójki zdefiniowanej następująco:
( V, D, C )
�
gdzie:
22 03/2010
Paradygmat programowania CLP
Propagacja i dystrybucja
– jako główne mechanizmy CLP
�
Większość metod rozwiązywania zadania w
środowiskach opisywanych w artykule bazu-
je na naprzemiennym stosowaniu procedur �
propagacji (ograniczania dziedzin zmiennych
decyzyjnych) nazywanych w skrócie propaga- � � � � � � � � � �
torami i dystrybucji (ukonkretniania warto-
ści zmiennych decyzyjnych w celu wyszuka-
�������������������������
nia rozwiązania). ���������������������
Propagacja to operacja, która polega na ��������������
sukcesywnym zawężaniu dziedzin zmien- ��������������������
nych zgodnie z semantyką więzów, w celu
usunięcia elementów, z których nie można
zbudować żadnego rozwiązania. Porządek
kroków propagacji nie ma wpływu na wy-
nik końcowy. Rysunek 7. Przykładowy początek problemu (dziedziny zmiennych są kompletne)
Propagacja nie jest operacją wystarczają-
cą do rozwiązania problemu CSP, zwiększa
ona jednak efektywność procesu (znacząco
przyśpiesza) poszukiwania rozwiązania do- �����������������������
puszczalnego.
Propagatory są implementowane w śro-
dowiskach jako współbieżnie pracujące ������������������
����������������
agenty (w formie osobnych procesów) obli- ������������������
�����������
czeniowe, które starają się zawęzić domeny �����
zmiennych występujących w danym ogra- ������������������
���������������
niczeniu.
Przeważnie implementacja ich wykony-
wana jest za pomocą wątków. Jeśli wszyst- �
kie wartości wszystkich zmiennych speł-
niają dane ograniczenie, propagator prze-
staje istnieć: �
• V = {x, y, z} – (zbiór zmiennych); Rysunek 8. Redukcja dziedzin po wymianie komunikatów i uzgodnieniu wartości zmiennych
www.sdjournal.org 23
Sztuczna inteligencja
24 03/2010
Paradygmat programowania CLP
Jest to działanie wystarczające do rozwią- mi wieloagentowymi MAS (Multi Agents runkuje realizację wspólnych celów agentów,
zania problemu CSP, gdyż dziedzinę każdej Systems), w których zachodzi zjawisko ko- która wymaga współpracy pomiędzy agenta-
zmiennej można stopniowo dzielić na coraz operacji niezależnych jednostek programo- mi i koordynowania ich działań. Zatem ko-
mniejsze podzbiory, aż wszystkie zmienne wych, oddalonych od siebie (również fizycz- operacja w tego typu systemach może być po-
zostaną zdeterminowane do pewnej war- nie), działających we wspólnym środowisku. strzegana jako problem rozproszonego speł-
tości. Podział taki jest niekoniecznie jed- Interakcja pomiędzy poszczególnymi repre- nienia ograniczeń (Distributed CSP). Problem
nakowo efektywny czasowo. Efektywność zentantami takiego systemu zachodzi przy taki przyjmuje więc następującą postać:
może być podnoszona poprzez sterowanie pomocy wymiany komunikatów.
procesem obliczeń, który obejmuje wybór Znalezienie rozwiązania może być zatem • istnieje zbiór agentów: {1, 2, ... , n};
kolejności podstawiania zmiennych decy- postrzegane jako osiągnięcie wewnętrznej • każdy agent posiada jedną albo wie-
zyjnych, wybór kolejnych wartości zmien- spójności w zbiorze agentów. To z kolei wa- le zmiennych (ma przyporządkowaną
nych decyzyjnych czy też liczbę podsta-
wień poszczególnych zmiennych. Sterowa-
nie zatem sprowadza się do określenia efek-
tywnej strategii podstawiania w kontek-
��
ście rozwiązywanego problemu. Jest to bar-
dzo istotny aspekt całego procesu, mający
wpływ na szybkość uzyskania rozwiązania. ��
��������������������������
�� �����������������������������
Dziedziny zmiennych �� ���������
Do modelowania problemów decyzyjnych
istnieje potrzeba określenia rodzaju zmien-
nych, które najlepiej odzwierciedlą zapisywa-
ny problem. Jeżeli problem wymaga do mo-
��
delowania zbyt skomplikowanych struktur, �����������������������
������������������������
należy go sprowadzić do problemu CSP, któ- ��
�
���������
������� �������������
ry można później zapisać w wybranym środo- ����
wisku w celu rozwiązania go.
W zbiorze ograniczeń wyróżnia się pod-
zbiór ograniczeń podstawowych (basic con-
�������������������������
straints),
które explicite określają dziedziny zmien-
nych, np. ograniczenie x::{2..8} mówi, że
wartości, jakie może przyjmować zmienna x,
są liczbami całkowitymi ze zbioru [2..8]. Rysunek 10a. Przykładowa reprezentacja algorytmu działającego w środowisku agentów (iteracyjne
Zmienna o dziedzinie jednoelemento- ulepszanie)
wej nosi nazwę zmiennej zdeterminowanej.
W systemach programowania klasy CLP sto-
suje się (są możliwe do wykorzystania) stan-
dardowe typy dziedzin dla poszczególnych
zmiennych, takie jak: �������������������������������
���������������������
������������
������������
���������������������������������� �������������������� �������������
��������
���������
• FD (finite domain) – skończone zbiory ���������������������� ����������������������
Problem rozproszonego
spełnienia ograniczeń
Reprezentacja wiedzy dla środowisk roz- Rysunek 10b. Przykładowa reprezentacja algorytmu działającego w środowisku agentów (iteracyjne
proszonych jest ściśle związana z systema- ulepszanie)
www.sdjournal.org 25
Sztuczna inteligencja
część zmiennych poszukiwanego roz- • wysyłanie komunikatu możliwe jest dy, gdy istnieje przyporządkowanie przez
wiązania); wtedy, gdy agent zna adres odbiorcy; agenta takiej wartości do swojej zmiennej,
• istnieje inter-agent reprezentujący ogra- • komunikat dociera do odbiorcy po skoń- która będzie spełniać zadane ograniczenia.
niczenia. czonym losowym czasie; Formalna definicja rozproszonego problemu
• dla dowolnej pary agentów porządek od- spełnienia ograniczeń przyjmuje postać po-
De�nicja Distributed CSP bioru jest zgodny z porządkiem wysła- niżej prezentowanej szóstki:
W definicji problemu zakłada się, iż w zbio- nia;
rze agentów możliwa jest komunikacja i speł- • każdy agent ma tylko częściową wiedzę ( A, V, D, C, b, k )
nione są następujące warunki: o problemie.
gdzie:
• agenty komunikują się poprzez wysyła- Zadanie rozproszonego spełnienia ograni-
nie komunikatów; czeń jest rozwiązane w zbiorze agentów wte- • A – zbiór agentów;
• V – skończony zbiór zmiennych, dla któ-
Listing 2a. Przykład problemu kolorowania mapy Australii 3-ma kolorami rych szukamy wartości;
• – związane ze zmiennymi skończone
D
public class LMMapColoring extends Example { dziedziny (gdzie: );
• C – skończony zbiór ograniczeń;
public void modelAustralia() { • b – relacja przynależności zmiennej do
System.out.println("\n \n Program to solve coloring problem: agenta;
modelAustralia() \n \n"); • k – relacja posiadania wiedzy o ograni-
// deklaracja listy zmiennych oraz magazynu czeniu dla zmiennej (agent posiada in-
// przechowującego strukturę całego problemu formację o ograniczeniu nałożonym na
store = new Store(); konkretną zmienną).
vars = new ArrayList<Variable>();
Każdy z agentów próbuje przypisać wartość
//(red, green, blue) swoim zmiennym, przy czym pomiędzy
//( 0, 1, 2 ) agentami występują zależności, które muszą
// przypisanie dziedzin do zmiennych być uwzględnione w proponowanych pod-
FDV WA = new FDV(store, "WA", 0, 2); stawieniach. Zakłada się ponadto, iż każda
FDV NT = new FDV(store, "NT", 0, 2); zmienna jest związana z jednym agentem,
FDV SA = new FDV(store, "SA", 0, 2); gdyż przypadek współdzielenia zmiennych
FDV Q = new FDV(store, "Q", 0, 2); przez wielu agentów może być zastąpiony
FDV NSW = new FDV(store, "NSW", 0, 2); przez wprowadzenie dodatkowych zmien-
FDV V = new FDV(store, "V", 0, 2); nych (lokalnie dla agenta) i ograniczeń na
FDV T = new FDV(store, "T", 0, 2); równość ich wartości.
Przykładowe zadanie reprezentowane
// dodanie zmiennych do listy w omawiany sposób możemy zapisać w na-
// zmienne reprezentują obszary na mapie Australii stępującej formie:
vars.add(WA); vars.add(NT); vars.add(SA);
vars.add(Q); vars.add(NSW); vars.add(V); A = {a1, a2, a3};
vars.add(T); V = {x, y, z};
D = {x::{0..9}, y::{0..9}, z::{0..9}};
// zadanie ograniczeń C = { c1: x < y, c2: z = x + y, c3: x>=3
store.impose(new XneqY(WA,NT)); } ( inter-agent );
store.impose(new XneqY(WA,SA)); b = { belongs(x, a1), belongs(y, a2), .
store.impose(new XneqY(NT,SA)); . . };
store.impose(new XneqY(NT,Q)); k = { known(c1, a1)}, known(c1, a2)},
store.impose(new XneqY(SA,Q)); known(c2, a1)},
store.impose(new XneqY(SA,NSW)); known(c1, a2), .
store.impose(new XneqY(SA,V)); . . }.
store.impose(new XneqY(Q,NSW));
store.impose(new XneqY(NSW,V)); gdzie:
store.impose(new XneqY(V,T)); // Tasmania
26 03/2010
Paradygmat programowania CLP
• b:relacja belongs(xj, i) oznacza, że Łatwość modelowania problemów decy- nią tę koncepcję jako bardzo atrakcyjny spo-
agent i ma określić wartość zmiennej xj, zyjnych, a w szczególności tych, które po- sób szybkiego modelowania i rozwiązywa-
każda zmienna xj należy więc do jedne- siadają w swojej naturze ograniczenia, brak nia problemów decyzyjnych. Jest to szcze-
go i - tego agenta (ta relacja jest reprezen- przepaści semantycznej pomiędzy modelem gólnie ważny aspekt podczas budowy dedy-
towana jako belongs( xj, i)); a metodyką jego rozwiązywania oraz efek- kowanych systemów wspomagania decyzji,
• k: relacja known(pk, j) oznacza, iż agent tywne metody poszukiwania rozwiązań czy- które to charakteryzują się specyficznymi
j zna ograniczenie, czyli predykat pk,
(ograniczenia są więc rozproszone mię- Listing 2b. Przykład budowy struktury searcha dla rozważanego problemu
dzy agentów).
. . .
Przyjmuje się, że zadanie DisCSP jest roz- public boolean searchAllAtOnce() {
wiązane w zbiorze agentów, wtedy i tyl- // zmienne potrzebne do obliczenia czasu przeszukiwania
ko wtedy, gdy: w odniesieniu do każdej long T1, T2;
pary: (agent, zmienna), spełniającej rela- T1 = System.currentTimeMillis();
cję belongs(), dokonano podstawienia za // wskazanie heurystyki wyboru zmiennej i wartości
zmienną takiej wartości, że w dowolnej pa- SelectChoicePoint select = new SimpleSelect(vars.toArray(new Variable[1]),
rze: (predykat, agent) spełniającej relację new MostConstrainedStatic(), new IndomainMin());
known(), predykat przy tym podstawieniu // wywołanie procedury przeszukiwania w głąb
jest prawdziwy, czyli wartość zmiennej speł- search = new DepthFirstSearch();
nia ograniczenia. search.getSolutionListener().searchAll(true);
Na Rysunku 8 (graficzna reprezentacja za- search.getSolutionListener().recordSolutions(true);
dania wcześniej zdefiniowanego) została za- search.setAssignSolution(true);
prezentowana propagacja ograniczeń, wy- boolean result = search.labeling(store, select);
stępująca po rozesłaniu komunikatów po- T2 = System.currentTimeMillis();
między agentami, która zawężała dziedziny if (result) {
zmiennych: System.out.println("Number of solutions " + search.getSolutionListener().
Możliwość rozwiązywania w taki spo- solutionsNo());
sób problemu ma duże znaczenie prak- search.printAllSolutions();
tyczne ze względu na powszechne wystę- }
powanie rozproszonych systemów pro- else
dukcyjnych w gospodarce. Istotne jest System.out.println("Failed to find any solution");
zatem prawidłowe i formalne wyspecyfi- System.out.println("\n\t*** Execution time = " + (T2 - T1) + " ms");
kowanie systemu – jego opis matematycz- return result;
ny, uwzględnienie warunków kolejnościo- }
wych, właściwe odzwierciedlenie ograni- ...
czeń zmiennych.
W wyniku opisu zazwyczaj zostaje zde- Listing 2c. Funkcja main() wykonująca program
finiowane trudne zadanie programowa-
nia matematycznego, o dużym rozmia- ...
rze, wymagające zastosowania specyficz- //--------------------------------------
nych technik programowania, z koniecz- public static void main(String args[]) {
ności pozostawiających duży margines dla
heurystyk. LMMapColoring problem = new LMMapColoring();
problem.modelAustralia();
Model dynamicznego
spełnienia ograniczeń DynCSP // uruchomienie przeszukiwania (wszystkie rozwiązania)
Przedstawiony w dalszej części artykułu mo- if ( problem.searchAllAtOnce() )
del zapisu wiedzy jest składnikiem (jednym System.out.println("Solution(s) found");
z wielu konwencji) paradygmatu CLP. Pro- }//!main()
gramowanie w logice z ograniczeniami jest }
dziedziną nauki, która zawiera się pomię-
dzy sztuczną inteligencją, badaniami opera-
cyjnymi oraz językami programowania. Jest
paradygmatem programowania tak jak pro-
gramowanie obiektowe czy też programo-
wanie funkcyjne. Podejście takiej reprezen-
tacji wiedzy stosowane jest do modelowania
oraz zapisu problemów, jakie mogą być da-
ne za pomocą zbioru zmiennych: V, ich dzie-
dzin: D, oraz relacji pomiędzy nimi, wyra- ����� ����������������������������������� �����������������������������������
żonych w postaci ograniczeń: C. Ogranicze-
nia te odzwierciedlają zależności pomiędzy
zmiennymi. Rysunek 12. Gra�czna reprezentacja dynamicznego CSP
www.sdjournal.org 27
Sztuczna inteligencja
właściwościami, swoistą strukturą czy rów- miczne. Wedle tego podziału w proble- ściowania zmiennych, aby spełniło zadane
nież charakterystycznymi dla siebie ograni- mach dynamicznych poszukiwana jest ograniczenia.
czeniami. funkcja rzeczywista, a w statycznych wek- Jako dynamiczną odmianę problemu
tor będący rozwiązaniem. Można by się od- można przyjąć DynCSP (co dalej zosta-
De�nicja Dynamic CSP nieść w tym stwierdzeniu, iż problemem ło szerzej opisane), który to jest sekwencją
W teorii optymalizacji przyjmuje się po- statycznym jest jedna instancja problemu statycznych problemów występujących ko-
dział problemów na statyczne oraz dyna- CSP, w której poszukujemy takiego warto- lejno po sobie. W modelu takim kolejne in-
stancje różnią się od siebie zestawem ograni-
czeń lub rozmiarem dziedzin dla konkret-
nych zmiennych.
Problemy numeryczne, występujące w za-
daniach koordynacji, badaniach operacyj-
nych, sterowaniu produkcją czy też innych
pokrewnych gałęziach przemysłu, mogą
być transformowane do problemów (mo-
delu) CSP oraz do problemów optymaliza-
cji COP (Constraint Optimization Problem).
W wielu praktycznych aplikacjach softwa-
rowych nie istnieje jeden statyczny problem
CSP. W rzeczywistości problemy, które ma-
my do rozwiązania, często zmieniają się
w czasie. Zmiany mogą wydarzyć się w dwo-
jaki sposób:
28 03/2010
Paradygmat programowania CLP
problemu oraz DynCOP dla sekwencji pro- na część tego rozwiązania (lokalnie) zostaje zaletą jest także jago równoległość, co czy-
blemu optymalizacji (Dyynamic Constraint modyfikowana, zachowując aktualne przy- ni bardzo atrakcyjną ofertę do możliwości
Optimization Problem). pisanie wartości tej zmiennej, aż do uzyska- implementacji systemu jako wariantu roz-
Przypominając wcześniej opisywane aspek- nia spójności (czyli do przywrócenia stanu, proszonego.
ty paradygmatu, podstawowym zagadnie- w którym ograniczenia są spełnione). Jeśli Poniżej został przedstawiony podział waż-
niem reprezentacji wiedzy w programowa- jest to niemożliwe, podstawiane są inne war- niejszych środowisk wspierających omawia-
niu w logice z ograniczeniami jest tzw. pro- tości dla rozpatrywanej zmiennej w danej in- ną metodykę:
blem spełnienia ograniczeń CSP. Dynamicz- stancji problemu.
ne środowisko jest przedstawiane (widziane) Generalną zasadą tego podejścia jest cią- • Środowiska oparte na językach PRO-
jako sekwencja statycznych problemów klasy głe rozwiązywanie zadania (klasycznego LOG – CLP:
CSP (Rysunek 12): CSP) na podstawie zmian założeń, które • Constraint Handling in Prolog —
Model matematyczny dla dynamicznego pojawiają się w trakcie życia systemu. Isto- CHIP.
CSP jest więc skończoną sekwencją takich tą pamiętania poprzedniego rozwiązania • Język OZ ze środowiskiem MO-
(klasycznych) problemów CSP, przedstawia- (czyli wszystkich przypisań wartości do ZART rozwijane m.in. przez na-
jących się w sposób: zmiennych) jest fakt mniejszego nakładu ukowców z DFKI (Niemieckiego
obliczeń na poprawę niespójnego zadania Centrum Badań nad Sztuczną Inte-
<csp(0), csp(1),…, csp(n)> w kroku następnym. ligencją) oraz SICS (Szwedzki Insty-
tut Informatyki).
Każdy z podproblemów csp(i) jest instan- Przegląd narzędzi • Środowiska oparte na językach niższego
cją problemu DynCSP, gdzie różni się od – środowisk CP/CLP rzędu jak np. C++:
poprzedniej (lub następnej) poprzez do- Efektywność metod CP/CLP jest rezulta- • ILOG Solver – firmy Ilog Inc., to śro-
danie lub usunięcie niektórych ograni- tem wykorzystania procedur propagacji, dowisko, w którym problemy zapisy-
czeń. Wszystkie możliwe zmiany w danej które pozwalają na wzajemne ograniczanie wane są w zbliżonym do języka C++
instancji problemu DynCSP mogą być wy- dziedzin zmiennych decyzyjnych, oraz dys- języku OPL (Optimization Program-
rażone tylko jako usunięcie lub dodanie trybucji zmiennych do zawężonych prze- ming Language). Wspiera ono roz-
ograniczenia w kolejnym punkcie czaso- strzeni dziedzin w celu wyselekcjonowania wiązywanie klasycznych problemów
wym. Rozwiązanie całego dynamicznego rozwiązań spełniających wszystkie przyjęte oraz ich optymalizację.(przykład za-
CSP implikuje rozwiązanie każdej jego in- ograniczenia. Zawężanie dziedzin zmien- pisu prostego problemu produkcyj-
stancji (z osobna), występującej w sekwen- nych decyzyjnych prowadzi do ogranicze- nego w ILOG OPL, przedstawiony
cji całego problemu. nia potencjalnej przestrzeni rozwiązań, co został na Listingach: 1a, 1b, 1c).
Pierwsza składowa problemu csp(0) w efekcie pozwala znacząco skrócić czas • Gecode – biblioteka/środowisko do
jest rozwiązana od początku (na podsta- potrzebny na obliczenia. Efektem naprze- rozwoju systemów opartych o tech-
wie zadanych warunków początkowych). miennego stosowania tych dwóch proce- nologię ograniczeń.
Dopuszczalnym jest rozwiązywanie każ- dur jest szybki sposób wyszukiwania roz- • Minion – Solver C++ do rozwiązy-
dego elementarnego problemu od warun- wiązań dopuszczalnych bądź wykazanie je- wania problemu CSP.
ków początkowych i zastosowanie się tak go braku. • Platformy programistyczne dostępne ja-
do wszystkich późniejszych instancji całe- W podejściach programowania mate- ko narzędzia komercyjne:
go problemu. Jednak takie podejście jest matycznego ograniczenia np. wynikają- • SICStus Prolog: (Szwedzki Instytut
nieefektywne i może być przyczyną niesta- ce z problemu przydziału modelowane są Informatyki);
bilności pomiędzy kolejno po sobie nastę- sztucznie, przy użyciu binarnych zmien- • ECLiPSe: początkowo ECRC, IC-
pującymi rozwiązaniami. Z tego powodu nych decyzyjnych o wartościach zerojedyn- Parc, obecnie rozwijany przez CI-
podczas rozwiązywania dynamicznego pro- kowych. Dlatego ważne jest zastosowanie SCO;
blemu CSP istnieje potrzeba wykorzystania środowisk, w których modelowanie ograni- • CHIP: ECRC, obecnie rozwijany
w możliwie największym stopniu rozwią- czeń jest naturalne. Środowiskami takimi przez COSYTEC;
zań z poprzednich instancji. są niewątpliwie środowiska umożliwiające • również ILOG Solver (darmowa
Istnieje kilka podejść (metod) do rozwią- formułowanie programu w sposób dekla- wersja odnosi się do zastosowań wy-
zywania dynamicznego problemu CSP. Naj- ratywny. Programowanie w logice z ogra- łącznie naukowo/badawczych).
efektywniejsze z nich skupiają się na algo- niczeniami (Constraint Logic Programming) • Platformy służące do symulacji proble-
rytmie lokalnych zmian LC (local changes), jest paradygmatem programowania, który mu jako podejścia rozproszonego:
który próbuje naprawić poprzednie rozwią- niewątpliwie wspiera to podejście, oferu- • DisChoco – platforma rozproszone-
zanie. Kiedy przypisana wartość do zmien- jąc szereg strategii poszukiwania rozwią- go programowania, oparta na języku
nej staje się niezgodna (niespójna) z roz- zania oraz metod optymalizacji. Naturalną Java;
wiązaniem poprzedzającym, wtedy niespój-
Literatura
W Sieci
• Eisenberg C.: Distributed Constraint Satisfaction For Coordinating and Integrating a large-
• http://www.ilog.com/; scale, Heterogeneous Enterprise.
• http://www.gecode.org/; • Meseguer P., Gonzalez S.: Open, Interactive and Dynamic CSP.
• http://jacop.osolpro.com; • Rossi F., Van Beek P., Walsh T.: Handbook of Constraint Programming.
• http://minion.sourceforge.net/; • Russell N.: Constraint Satisfaction Problems.
• http://www.emn.fr/x-info/choco-solver; • Yokoo M., Durfee E. H., Ishida T., Kuwabara K.: The distributed constraint satisfaction pro-
• http://www.sics.se/isl/sicstuswww/site/. blem: formalization and algorithms.
www.sdjournal.org 29
Sztuczna inteligencja
• Frodo – framework do symulacji al- Przedstawiany proces jest prezentowany ce w przepustowości procesów (np. na po-
gorytmów rozproszonego rozwiązy- w formie wizualnej za pomocą grafów dla ko- szczególnych maszynach na wydziale), to
wania. lejnych kroków propagacji ograniczeń, w któ- część z nich jest w pewnym stopniu niewy-
• Platformy typu OpenSource: rych następuje redukcja dziedzin zmiennych korzystana. Pociąga to za sobą dodatkowe
• Choco – solver w postaci bibliote- (czyli wstępne poszukiwanie właściwej war- koszty. Posługiwanie się techniką opartą
ki Java, który może być używany tości). (lub wspieraną) o mechanizmy CLP (np.:
do nauki, badań, jak również za- W przykładowych appletach Javy moż- zastosowaną do planowania potrzeb mate-
stosowany w aplikacjach komercyj- na uzyskać wizualizację sprawdzania spój- riałowych MRP) może w znacznym stop-
nych; ności łuków (AC) (wcześniej opisywanej) niu ograniczyć koszty przedsiębiorstwa
• JaCoP – efektywna obliczeniowo bi- dla testowo zdefiniowanych problemów oraz pozwolić uniknąć kłopotów spowodo-
blioteka programistyczna Javy, im- (dostarczonych wraz z programem, np.: wanych brakiem jakichś zasobów na okre-
plementująca paradygmat progra- Rysunek 14) lub dla problemów utwo- ślony czas.
mowania z ograniczeniami. rzonych od początku przez siebie (Rysu- Rozwinięciem rozważań poruszanych
nek 13). w artykule jest przedstawienie rozproszo-
(przykład zapisu problemu kolorowania Należy mieć na uwadze także to, iż formu- nej wersji problemu spełnienia ograniczeń
w JaCoP: przedstawiono na Listingu 2a, 2b, łując własny problem, wynik wygenerowany (DisCSP), która jest implementacją podej-
2c). przez mechanizm (w trakcie rozwiązywania ścia działającego w środowisku (systemie)
Wiele opracowanych systemów na tych problemu) musi spełniać wszystkie zadane kooperujących ze sobą agentów, wymienia-
platformach wykorzystuje heurystyczne ograniczenia, o ile jest to możliwe, może wy- jących informacje za pomocą komunikatów
algorytmy programowania całkowitolicz- stąpić jednak sytuacja nadmiernego związa- (wiadomości).
bowego z ograniczeniami. Rozwiązywane nia problemu, co implikuje brak jakiegokol- Metoda ta ma proste i naturalne zastoso-
przez nie problemy są zazwyczaj wysoce wiek rozwiązania. wanie w rzeczywistości, w której wiele pro-
złożone już w przypadku niewielkiej licz- cesów posiada rozproszone zasoby. Wystę-
by argumentów problemu (liczba zadań, Podsumowanie puje wtedy potrzeba komunikacji ze sobą
maszyn, pełnionych funkcji itp.). Dzieje W artykule autor przedstawił przegląd oraz oddalonych jednostek wykonawczych w ce-
się to głównie ze względu na konieczność możliwości reprezentacji wiedzy dla wybra- lu wymiany wiedzy o wspólnie rozwiązy-
uwzględnienia licznych ograniczeń zmien- nych metodyk klasy CP/CLP. Przedstawio- wanym problemie.
nych stanu, licznych zmiennych decyzyj- no zapis definiowania problemu wraz z kon- Zawarto także zarys przykładowych moż-
nych oraz warunków odnoszących się do kretnym celem jego zastosowania. Wyszcze- liwości wykorzystania omawianych technik
porządku i czasu wystąpienia zdarzeń dys- gólniono reprezentację wiedzy dla klasycz- w środowiskach produkcyjnych, gdzie bar-
kretnych (czyli w odpowiednich chwilach nego problemu spełnienia ograniczeń, jak dzo dobrze radzi sobie podejście dynamicz-
czasowych), zachodzących w sformułowa- też jego wariantu rozproszonego oraz dy- ne (DynCSP) (czyli sekwencja kolejno wy-
nym zadaniu. namicznego. Realizacja przedstawionych stępujących po sobie klasycznych proble-
W istniejących środowiskach CLP sam etapów dotyczących mechanizmów wyko- mów CSP).
model jest już programem. Dostępne są do rzystywanych w metodykach CP/CLP pro- Myślę, iż taka forma przedstawiania wie-
użycia (zaproponowania przez użytkowni- wadzi do budowy narzędzi w postaci syste- dzy na temat paradygmatu CLP, który sku-
ka środowiska) również odpowiednie wa- mów do wspomagania decyzji, które pozwa- pia się na rozwiązaniu problemu CSP, mo-
rianty metod poszukiwania rozwiązania, lają poszukiwać rozwiązań dla zadań proble- że w znaczny sposób przybliżyć czytelnikowi
będące integralną częścią środowiska CLP, mów decyzyjnych o charakterze kombinato- korzyści płynące z odpowiedniej formy zapi-
do których należą między innymi: propa- rycznym. su zadania podczas podjęcia się próby imple-
gacja ograniczeń, dystrybucja zmiennych W praktyce programowanie z ogranicze- mentacji w systemie.
oraz kombinacje szereg algorytmów poszu- niami jest wysoce deklaratywne, co pozwa- Przedstawiane techniki reprezentowa-
kiwania rozwiązania jak backtracking (na- la wiele rzeczywistych problemów opisy- nia wiedzy można wykorzystać na etapie
wracanie) czy foward checking (sprawdza- wać, używając ograniczeń, które odzwiercie- formułowania (zapisu) problemu w spo-
nie do przodu) z możliwością wyboru heu- dlają zależności pomiędzy zmiennymi pro- sób najlepiej oddający rzeczywistość (na-
rystyki kolejności przeszukiwania zmien- blemu. Taki sposób specyfikacji problemu turę zadania). Korzystając z systemów kla-
nych oraz ich wartości. może być wprowadzony w wielu tradycyj- sy: CP/CLP (umożliwiających rozwiązywa-
nych środowiskach programowania, ale naj- nie tej klasy zadań), jesteśmy w stanie tak
Przydatne oprogramowanie lepszy rezultat jest osiągany, kiedy wykorzy- sformułowane zadanie rozwiązywać bar-
Proces rozwiązania problemu przy użyciu stujemy paradygmat programowania w logi- dzo efektywnie czasowo.
metody CLP składa się z określenia ograni- ce, który również opiera się na deklaratyw-
czeń, a następnie poszukiwania rozwiąza- ności i relacjach.
nia za pomocą szeregu heurystycznych al- Opisywany paradygmat może być wy-
gorytmów poszukiwania, propagacji ogra- korzystany w teorii ograniczeń, która jest
niczeń oraz dystrybucji zmiennych. Jest to metodyką usprawniania systemów. Zakła-
często słabo dostrzegalne przez użytkow- da się, iż w każdym systemie zbudowa- ŁUKASZ MAZUR
nika tej technologii (można powiedzieć, nym z wielu powiązanych ze sobą dzia- Doktorant AGH Kraków, obecnie zajmuje się
iż cała mechanika ukryta jest pod ma- łań znajduje się jedno działanie ograni- analizą danych oraz rozwojem hurtowni da-
ską), dlatego aby ułatwić naukę o technolo- czające skuteczność całego systemu. Ce- nych, prowadzi także prace badawcze nad al-
gii CLP, można wstępnie posłużyć się pro- lem systemu może być maksymalizacja zy- gorytmami optymalizacji w konwencji para-
gramami, które w sposób wizualny przed- sku. W przedsiębiorstwie może funkcjono- dygmatu programowania w logice z ograni-
stawią krokowo przebieg rozwiązywanego wać wiele procesów, z których jeden limi- czeniami.
problemu. tuje jego zysk. Jeżeli występują duże różni- Kontakt z autorem: lukash.mazur@gmail.com
30 03/2010
Bezpieczeństwo
Niezawodność systemów
informatycznych
Nieustanny postęp technologiczny, zwłaszcza ten dotyczący świata
IT, sprawia, że mamy do czynienia z globalną komputeryzacją oraz
informatyzacją, która z dnia na dzień zatacza coraz to szersze kręgi. Postęp
służyć powinien globalnemu dobru, jednak wraz postępem pojawiają
się coraz to nowe problemy oraz pułapki, których nie sposób traktować
z przymrużeniem oka.
systemu monitorowania komponentów siecio-
Dowiesz się: Powinieneś wiedzieć: wych celem agentów będzie dostarczanie in-
• Jak może wyglądać podstawowa struktura • Co to jest usługa sieciowa; formacji na temat poszczególnych komponen-
wieloagentowego systemu monitoringu sieci; • Podstawowe informacje na temat systemów tów, potrzebnych do określenia aktualnego sta-
• Podstawowe zagadnienia związane z bez- informatycznych świadczących usługi; nu, w jakim się one znajdują.
pieczeństwem oraz niezawodnością usług. • Podstawowe informacje na temat popular- Zacząć należy jednak od zdefiniowania
sieciowych nych narzędzi monitorujących sieć. struktury sieci, w której działać będą oba syste-
my: monitorowany system informatyczny oraz
system monitorujący. Do naszego celu doskona-
funkcjonalności - które dostarczane są czę- le pasuje struktura trójwarstwowa, w której wy-
sto przez zewnętrzne oprogramowanie (np. różniamy poszczególne warstwy (Rysunek 1):
Poziom typowe usługi sieciowe: HTTP, FTP, SMTP,
trudności ostatnio popularny VoD i wiele, wiele in- • najniższa – warstwa odpowiedzialna za
nych) – musimy zadbać o jak największą dostarczanie potrzebnych informacji;
ich niezawodność (tudzież dostępność) • środkowa – warstwa odpowiedzialna za
Z
jawisko to dotyczy niemalże wszyst- oraz bezpieczeństwo. Pod uwagę bierzemy analizę danych oraz podejmowanie de-
kich płaszczyzn funkcjonowania spo- aspekty związane z serwerami back-up, re- cyzji – np. adaptacyjnych, zmiany kon-
łeczeństwa (począwszy od instytucji plikacjami baz danych, jak również samych figuracji etc;
naukowych, poprzez przemysł, biznes, komu- aplikacji odpowiedzialnych za dostarczanie • najwyższa – odpowiedzialna za zobrazo-
nikacje, urzędy) dzięki czemu spotykane jest konkretnych już funkcjonalności. wanie aktualnego stanu całej struktury
podczas wykonywania nawet najprostszych Budując „niezawodny system informatycz- systemu monitorowanego – np. konsola
czynności w naszym codziennym życiu. ny” z uwzględnieniem wszystkich założonych administratora.
Powszechnie znanym oraz na co dzień sto- w projekcie aspektów bezpieczeństwa i nieza-
sowanym słowem jest: usługa (ang. service), wodności, nie sposób pominąć kwestię mo- Taka struktura sieci nie jest oczywiście wy-
dziś również w świecie IT – np. usługa siecio- nitorowania jego poszczególnych komponen- mogiem. System wieloagentowy jest na tyle
wa. Ostatnio popularny model dostarczania tów w celu zobrazowania aktualnego stanu elastycznym tworem, że daje zastosować się
usług – Cloud Computing, obejmujący modele systemu oraz podejmowania właściwych de- do wielu rodzajów struktur sieci.
usług takich jak SaaS, PaaS czy IaaS, oferuje po- cyzji. Niniejszy artykuł pokrótce opisuje ar- W naszym przypadku (staramy się stworzyć
nadto całkowicie przezroczystą warstwę dostę- chitekturę wieloagentowego systemu moni- system monitorujący komponenty dostarczają-
pu do usługi z punktu widzenia usługobiorcy. torowania komponentów sieciowych, wcho- ce usługi sieciowe), projektując strukturę sieci,
Użytkownik (usługobiorca) nie musi wiedzieć, dzących w skład systemu informatycznego należy zadbać o to, aby znalazło się w niej miej-
gdzie fizycznie znajduje się dana usługa ani znać zorientowanego na usługi. sce przynajmniej dla dwóch najniższych warstw
szczegółów jej implementacji. W jego zaintere- – warstwa monitorująca oraz warstwa analizu-
sowaniu leży przede wszystkim funkcjonalność Architektura wieloagentowego jąca i podejmująca decyzje.
oraz rezultat dostarczany przez wybraną usłu- systemu monitorowania sieci W artykule tym skupimy się na najniższej
gę. Oczywistym jest fakt, że bez względu na Pojęcie systemu wieloagentowego jest obec- warstwie struktury, tj. warstwie odpowiedzial-
typ usługi powinna być w pełni świadczona jej nie dobrze znane przez ludzi ze środowiska nej za dostarczanie informacji dotyczących kom-
funkcjonalność i jednocześnie w sposób jak naj- IT. Jak wskazuje typ takiego systemu, składa ponentów świadczących dane usługi sieciowe.
bardziej niezawodny oraz bezpieczny. się on z komunikujących się ze sobą niezależ- Ponadto opisana zostanie warstwa środkowa,
Projektując system informatyczny, udo- nych bytów – Agentów (ang. Agents), reali- analizująca zebrane dane oraz podejmująca pew-
stępniający wiele różnorakich usług, oprócz zujących jednak ten sam cel. W przypadku ne decyzje oparte o rezultaty analizy. Warstwa ta
32 03/2010
Niezawodność systemów informatycznych
zostanie potraktowana bardzo ogólnie i jedynie informatycznego oraz jaką rolę odgrywa środ- sieciowe takie jak router czy zarządzalne switch-
w kontekście warstwy najniższej (analiza oraz kowa warstwa systemu monitorującego. Jest e mają wbudowane oprogramowanie umoż-
podejmowanie decyzji warstwy środkowej są to oczywiście bardzo ogólny zarys, bez żadnych liwiające przesyłanie logów w formacje np. sy-
zagadnieniami, które mogłyby stanowić temat konkretnych informacji na temat samej techni- slog-a w miejsce ich przeznaczenia. Agent, mają-
na co najmniej jeszcze jeden artykuł), gdyż obie ki kolekcjonowania i analizowania danych oraz cy możliwość „nasłuchiwania” na plikach logów
warstwy stanowią nieodzowną całość w opisy- podejmowania decyzji na podstawie rezultatów lub portach TCP, do których wysyłane są logi
wanym modelu systemu monitoringu. dostarczonych przez algorytmy analizy danych. z poszczególnych serwisów, przechwytuje oraz
Jak widać na Rysunku 1, cała sieć (system in- Opis ten pozwala nam jednak na sporządzenie przekazuje je poprzez sieć (np. przy pomocy pro-
formatyczny dostarczający usługi sieciowe) zo- oraz zaprojektowanie ogólnych założeń syste- tokołu UDP lub innego, w zależności od polityki
stała podzielona na swego rodzaju komórki. mu monitoringu. Na Rysunku 2 przedstawio- bezpieczeństwa) do agenta decyzyjnego.
Każda z nich zawiera kolekcję agentów dostar- ny został ogólny zarys systemu monitorowa- Jednak logi dostarczane przez serwisy świad-
czających informacje na temat monitorowanych nia wraz z przepływem danych między jego po- czące usługi na danym hoście są tylko jednym ro-
komponentów sieciowych oraz jednego Agenta szczególnymi komponentami. Wyraźnie widać dzajem (z wielu) informacji, jakie będą nam po-
Decyzyjnego (ang. DecisionAgent), kolekcjonu- trójwarstwową strukturę (podobnie jak struk- trzebne do uzyskania rzeczywistego obrazu sta-
jącego (zapisującego, np. do bazy danych) oraz turę sieci, którą chcemy monitorować), w skład nu maszyny (hosta). Innym rodzajem informa-
analizującego informacje, a następnie podejmu- której wchodzą (kolejno od warstwy najniższej): cji, które są niemniej istotne, to dane dotyczące
jącego odpowiednie decyzje w oparciu o rezul- monitorowane hosty (lub urządzenia sieciowe), aktualnego zużycia procesora, pamięci czy nawet
taty wykonanej analizy. Agent Decyzyjny jest agent decyzyjny wraz z bazą danych (najczęściej obciążenia na karcie sieciowej. Dzięki tym infor-
szczególnym przypadkiem zwykłego agenta, w postaci osobnego hosta lub wielu hostów, na macjom możemy monitorować aktualną dostęp-
którego funkcjonalność rozszerzona jest o me- których zainstalowany jest cały system bazoda- ność poszczególnych usług oraz czas odpowiedzi
tody analizy i podejmowania decyzji. Innymi nowy) oraz konsola, mająca na celu zobrazowa- na żądanie od klienta. Aktualnie jest wiele narzę-
słowy, jest to centralny komponent każdej z po- nie aktualnego stanu monitorowanego systemu dzi potrafiących dostarczyć tego typu informacje,
szczególnych komórek. Zbiór omawianych ko- wraz z jego poszczególnymi podzespołami. np.: SNORT, Statgrab, SNTP czy WMI, jednak są
mórek, wraz z agentami decyzyjnymi, w cało- Zajmijmy się teraz najniższą warstwą, czy- to tylko przykłady. Tak więc nie zależy nam na
ści składają się na środkową warstwę systemu li monitorowanym hostem. Jak wspomniane wymyślaniu koła raz jeszcze, a jedynie wykorzy-
monitoringu. W fizycznym projekcie sieci każ- było na początku niniejszego artykułu, usługi staniu dostępnych dla ogółu narzędzi. Agent re-
da komórka mogłaby stanowić osobną podsieć, dostarczane są zazwyczaj poprzez zewnętrzne zydujący na hoście powinien być zaprojektowany
a agenci znajdować się w różnych przestrzeniach aplikacje/systemy instalowane na hostach we- w taki sposób, aby dać możliwość pozyskiwania
adresowych. Oczywiście jest to tylko propozycja, wnątrz naszej sieci. Przykładem takich usług danych z dowolnych systemów zewnętrznych.
podział na komórki może być czysto abst rakcyj- mogą być: WebServer, DNS, FTP i wiele innych. Cel ten można osiągnąć poprzez założoną z góry
ny, a o podziale stanowić będzie jedynie infor- Każda z tych usług posiada możliwość logowa- modularyzację Agenta, co zresztą przedstawione
macja o tym, z którymi agentami decyzyjnymi nia zdarzeń. Logi zapisywane są w różnych for- jest na Rysunku 2 (dodatkowe wtyczki w posta-
komunikują się agenci dostarczający informa- matach oraz w różnych postaciach (np. do pli- ci bibliotek – tzw. „sensory” dostarczające lub po-
cje o monitorowanych podzespołach. Po opisie ków na dysku lub w formacie Syslog-a), które zyskujące informacje o hoście).
tym można wywnioskować, że nie jest to stan- w prosty sposób możemy pozyskać oraz przeka- Drugą – przedstawioną na Rysunku 2, ro-
dardowy model systemu wieloagentowego. Po- zać do dalszej analizy. To właśnie jest główną ro- lą agenta, jest umożliwienie zmiany konfigu-
szczególni agenci pozyskujący i dostarczający in- lą agenta monitorującego dany host. Czym więc racji hosta. Przykładowo, otrzymując infor-
formacje o monitorowanych komponentach nie jest Agent? W najczęstszej postaci będzie to apli- macje o niepoprawnym działaniu danej usłu-
muszą mieć możliwości komunikowania się ze kacja rezydująca na monitorowanej maszynie gi, możemy nakazać agentowi na reakcję, np.
sobą nawzajem. W zasadzie nie muszą nawet lub urządzeniu. Najczęściej, gdyż urządzenia zrestartowanie wadliwie działającej usługi.
wiedzieć o swoim istnieniu. Ich zadaniem jest
przede wszystkim zdobycie potrzebnych infor-
������������
macji oraz przesłanie ich do agenta centralnego
����������������
– agenta decyzyjnego, który musi już znać loka- �������
lizację poszczególnych agentów oraz mieć moż-
liwość komunikacji z każdym z nich w ramach
komórki, do której należy. Ponadto agent decy-
������������
zyjny powinien komunikować się ze wszystkimi
������� �������
innymi agentami decyzyjnymi stanowiącymi
agentów centralnych pozostałych komórek.
���������������� ����������������
Z tego miejsca wiem już, jak zorganizowana
może być struktura monitorowanego systemu
���������
Projekt Armazd
Armazd, jest to projekt oparty na licencji
opensource (GNU GPL v2). Podstawowym
założeniem, jest stworzenie systemu moni-
torującego oraz podejmującego decyzje re- ������� ����� ������� ������� ����� �������
kon�guracyjne, w oparciu o analizę zebra-
nych danych, na temat monitorowanej sie-
ci komputerowej. Jeśli jesteś zainteresowany
tą tematyką, polecam stronę projektu: http:/
/hardtechnology.org/armazd.
Rysunek 1. Przykładowa struktura sieci – systemu informatycznego świadczącego usługi sieciowe
www.sdjournal.org 33
Bezpieczeństwo
Moduł ten jest oczywiście mocno ograniczo- Już na tym etapie widać, jak złożona może być zawodność systemu informatycznego, którego
ny restrykcjami narzuconymi z góry poprzez jednostka agenta centralnego oraz jak szeroki podstawowymi cechami są:
przyjętą politykę bezpieczeństwa, gdyż wy- wachlarz możliwości daje się zastosować, aby
magałoby to nadania odpowiednich upraw- zadbać o jak największą dostępność oraz bez- • monitorowanie komponentów siecio-
nień agentowi w systemie (wielu administra- pieczeństwo usług systemu informatycznego. wych;
torów nie zgadza się na tego typu czynności • gromadzenie oraz analiza zebranych da-
w sieciach zostawionych pod ich opiekę). Co Przykład nych;
do samej implementacji agenta powinna być implementacji oraz zastosowanie • podejmowanie decyzji rekonfiguracyj-
ona przeprowadzona w taki sposób, aby sam Opisywane powyżej zagadnienia, nie są tyl- nych poszczególnych jak również całych
agent miał jak najmniejszy wpływ na obcią- ko kawałkiem – oderwanej od rzeczywisto- grup komponentów sieciowych;
żenie hosta, na którym rezyduje. Oznacza to ści – teorii. Problem niezawodności usług sie-
implementację na relatywnie niskim pozio- ciowych jest również jak najbardziej realny. Po- Jest to jednak tylko przykład implementa-
me (np. C/C++) oraz ewentualne uwzględ- woduje to pojawianie się różnorodnych narzę- cji rozwiązań problemów z rodziny bezpie-
nienie obciążenia powodowanego przez dzi mających na celu zmaksymalizowanie bez- czeństwa oraz niezawodności.
agenta w algorytmach analizy danych. pieczeństwa i niezawodności systemów infor- Nietrudno natomiast wyobrazić sobie przy-
W ogólności, przepływ danych w systemie matycznych. Mogą być to na przykład rozpro- kład zastosowania tego typu systemu monito-
monitorującym może wyglądać w następują- szone systemy backup-owe, tworzące oraz za- ringu. Przykładem może być firma świadczą-
cy sposób: rządzające kopiami zapasowych, jak również ca popularne ostatnio usługi VoD. Stale mo-
narzędzia monitorujące oraz diagnozujące ca- nitorując np. zużycie procesora, pamięci czy
• wysyłanie logów przez serwisy do agentów łą strukturę sieci komputerowej. Przykładem obciążenie na łączu, jesteśmy w stanie szybko
lub pozyskiwanie danych przez agentów; takiego narzędzia, może być ogólnie dostępny i niemalże automatycznie reagować na sytu-
• wysyłanie danych przez agentów do agen- system Armazd (ramka: Projekt Armazd). Sys- acje, gdy którykolwiek z wymienionych współ-
ta decyzyjnego; tem ten, został zaprojektowany oraz zaimple- czynników jest zbyt wysoki. Jeśli jest duże ob-
• odbieranie danych przez agenta decyzyj- mentowany zgodnie z zagadnieniami opisany- ciążenie na łączu, automatycznie spada dostęp-
nego oraz ich analiza i ewentualne zapisa- mi w poprzednim rozdziale. Dzięki temu, po- ność świadczonych usług, łatwo możemy to wy-
nie w bazie danych; zwala gromadzić dane z wszystkich komponen- kryć i zmienić konfigurację routera. W sytuacji,
• podejmowanie odpowiednich decyzji tów sieciowych (takich jak router, switch, hosty gdy zużycie procesora znacznie podnosi się po-
w reakcji na dane zdarzenie (jeśli taka jest świadczące usługi sieciowe czy nawet stacje ro- nad normę, również najczęściej mamy do czy-
wymagana); bocze). Implementacja przeprowadzona została nienia z drastycznym spadkiem świadczonych
• wysyłanie informacji o reakcji przez agen- na względnie niskim poziome (języki C/C++). usług. W przypadku braku wystarczającej ilo-
ta decyzyjnego do jednego (bądź wielu) Funkcjonalność systemu, w obecnej fazie roz- ści pamięci, narażeni jesteśmy przykładowo na
agentów rezydujących na monitoro- woju, sprowadza się do monitorowania kom- błędne działanie aplikacji odgrywających klu-
wanych maszynach; ponentów sieciowych, pozyskiwanie interesują- czową rolę w procesie świadczenia usługi. Tego
• wykonanie polecenia (np. zmieniającego cych nas danych oraz przekazywanie ich w zde- typu parametrów może jest wiele. Natomiast,
konfigurację usługi) przez agenta rezydu- finiowane miejsce przeznaczenia. Projekt doty- wszystkie wymienione sytuacje powodują spad-
jącego. czy jednak całego procesu podnoszącego nie- kiem bezpieczeństwa oraz niezawodności syste-
mów informatycznych.
���������������� Podsumowanie
������� ������������������� Bezpieczeństwo, niezawodność czy dostęp-
���������������� ność usług sieciowych to bez wątpienia niezwy-
kle ważne zagadnienia dzisiejszego świata IT.
Ilość i rodzaj usług oraz liczba usługodawców
����������������������
�������� IT różnego typu wzrasta z dnia na dzień. Wraz
�����������������
������ z tym postępem technologicznym obserwuje-
my wzrost odpowiedzialności, jakie biorą na sie-
��
������������� bie jednostki świadczące dane usługi (od banko-
���������������
wości po instytucje publiczne takie jak np. urzę-
dy czy organy prawa). Dlatego wdrażając syste-
my informatyczne zorientowane na usługi, nie
�������������� sposób pominąć wyżej wymienione zagadnie-
nia bezpieczeństwa, na które kładziony jest na-
����� cisk, nieraz równoważny z zapewnieniem funk-
cjonalności świadczonych usług.
��������������
������
��������������
������������
ANDRZEJ OLCHAWA
Autor niniejszego artykułu pracownikiem �rmy Po-
wer Media S.A., na stanowisku Software Developer.
���������������������
Interesuje się bezpieczeństwem oraz niezawodno-
����������
ścią w kontekście systemów informatycznych. Wię-
cej informacji na temat autora czytelnik może zna-
leźć, odwiedzając stronę: http://hardtechnology.org.
Rysunek 2. Architektura wieloagentowego systemu monitoringu z podziałem na warstwy Kontakt z autorem: andrzejolchawa@gmail.com
34 03/2010
Warsztaty
M
echanizm wyszukiwania stanowi opiera się na wyborze zestawu słów charak- Etap ten pozornie wydawać się może rzeczą
podstawową funkcjonalność nie- terystycznych dla danego dokumentu, ich banalną, lecz stanowi serce całego mechani-
mal wszystkich aplikacji bazoda- optymalnym przechowaniu (np. w posta- zmu. To właśnie Analyzer zapewnia wyszu-
nowych. Zwyczajowo, jego realizacja opiera ci odwróconego indeksu) oraz efektywnym kiwanie po synonimach czy też akceptację
się na udostępnieniu prostego formularza przeszukiwaniu uwzględniającym na przy- błędów związanych z zamianą kolejności li-
reprezentującego dopuszczalne kryteria za- kład synonimy, aproksymację oraz oceniają- ter. Diagram 1 przedstawia przykładowe
pytania. Na podstawie wypełnionych przez cym trafność poszczególnych rekordów wy- działanie prostego Analyzer’a.
użytkownika pól generowane jest zapytanie nikowych. Z pewnością, Czytelnicy posia- Drugą fazą operacji indeksowania do-
SQL, którego wyniki zostają przedstawione dający umysł ścisły lepiej zrozumieją dzia- kumentu jest jego zapisanie w strukturze
w formie tabelki. Wyszukiwanie danych tek- łanie wyszukiwarek pełnotekstowych po umożliwiającej późniejsze, łatwe przeszuki-
stowych bywa udoskonalone o ignorowanie lekturze kolejnych części artykułu przed- wanie. Apache Lucene wykorzystuje algo-
wielkości znaków (funkcja UPPER) i przeszu- stawiających techniczne aspekty realizacji rytm invert indexing. Algorytm ten porów-
kiwanie fragmentów tekstu (klauzula LIKE owego mechanizmu na przykładzie Hiber- nać można do tradycyjnego spisu treści. To-
oraz słowo kluczowe %). Wciąż jednak użyt- nate Search i Apache Lucene. ken’y zwrócone przez Analyzer gromadzo-
kownik nie posiada możliwości wyszukiwa- ne są w swego rodzaju tablicy. Każda komór-
nia po synonimach, aproksymacji ewentu- Architektura Hibernate ka przechowuje pojedynczy wyraz oraz wska-
alnych błędów literowych czy też porządko- Search oraz Apache Lucene zuje na dokumenty go zawierające. Wspo-
wania otrzymanych wyników innego niż al- Idea wyszukiwania pełnotekstowego skła- mniana struktura danych przetrzymywa-
fabetyczne sortowanie. Z pomocą w mini- da się z trzech, ściśle zależnych od siebie na być może w pamięci operacyjnej, jak i fi-
malizacji owych ograniczeń przychodzi me- operacji. Pierwsza z nich zajmuje się eks- zycznie na dysku twardym w postaci zbio-
chanizm przeszukiwania pełnotekstowego, trakcją tekstu oraz wydobyciem charak- ru plików. Za przechowywanie indeksu od-
36 03/2010
Hibernate Search API
powiedzialne są klasy DirectoryProvider. dy opracowany zostanie mechanizm inter- obiektowe Hibernate Core z wyszukiwar-
Hibernate Search oferuje dwie wbudowa- pretujący w pełni nieustrukturalizowane, ką pełnotekstową Apache Lucene. Narzę-
ne implementacje: FSDirectoryProvider potoczne zapytania. dzie to zapewnia przezroczysty dla pro-
oraz RAMDirectoryProvider. Istnieje po- Uważni Czytelnicy zastanawiają się pew- gramisty system indeksowania wyspecyfi-
nadto możliwość wskazania własnej imple- nie, jaką rolę odgrywa Hibernate w całym kowanych (przy pomocy adnotacji) atry-
mentacji zapisującej indeks np. bezpośred- opisanym wyżej mechaniźmie. Hiberna- butów danej encji. Programista, chcąc za-
nio w bazie danych. Celowo wskazałem tutaj te Search integruje mapowanie relacyjno- pisać nowy rekord lub zmodyfikować ist-
przykład bazy danych, gdyż z pewnością wie-
lu z Was uważać go będzie za bardzo atrakcyj-
ny. Emmanuel Bernard (deweloper Hiberna-
te Search oraz autor książki Hibernate Search
In Action) wskazuje następujące wady owego
rozwiązania:
www.sdjournal.org 37
Warsztaty
38 03/2010
Hibernate Search API
www.sdjournal.org 39
Warsztaty
Fakt, iż Apache Lucene przechowuje da- authors.firstName). Aby indeksowanie 91 do 94). Należy ponadto zwrócić uwagę,
ne wyłącznie w formie tekstowej, impli- relacji działało poprawnie, relacja powin- iż indeksowanie relacji znacznie zwiększa
kuje konieczność denormalizacji wszel- na być dwukierunkowa, a druga jej strona rozmiar indeksu.
kich indeksowanych relacji. W przypad- opatrzona adnotacją @ContainedIn. Dzię- Ostatnim elementem konfiguracyjnym
ku konieczności udostępnienia zapytań ki temu Hibernate powtórnie indeksu- wykorzystywanym w fazie zapisywania in-
o własności enkapsulowane w innej encji, je dokument encji nadrzędnej po modyfi- deksu jest wybór domyślnego Analyzer’a
atrybut relacji należy opatrzyć adnotacją kacji (operacji UPDATE, INSERT lub DELETE) dla danej klasy, lub w szczególności dla
@IndexedEmbedded. Pozwala ona określić powiązanego obiektu podrzędnego. Uwa- konkretnego atrybutu. Listing 2 przedsta-
stopień zagłębienia dalszego rekursywnego ga implementacyjna: mechanizm powtór- wia definicję standardowego Analyzer’a,
indeksowania podrzędnych relacji. Jako wy- nego indeksowania działa poprawnie tyl- którego działanie zostało opisane na po-
nik owego działania dokument BookEntity ko w przypadku modyfikacji obiektu posia- czątku poprzedniej sekcji artykułu. Hiber-
zawierać będzie wszystkie informacje na te- dającego aktualną referencję do encji nad- nate Search udostępnia jednak bardziej zło-
mat każdego z powiązanych autorów (np. rzędnej (patrz plik TestRunnable.java, linie żone filtry (wykorzystywane przy defini-
cji analizatora) obsługujące wyszukiwanie
Listing 5. Stronicowanie zwracanych wyników po synonimach (SynonymFilterFactory),
podobieństwie fonetycznym (Phonetic-
public Object[] getAuthorsByNamePaginating(String name, int pageNumber, int window) { FilterFactory), rodzinie danego wyrazu
Session session = getSession(); (SnowballPorterFilterFactory) czy też
FullTextSession fullTextSession = Search.getFullTextSession(session); akceptujące błędy literowe (NGramFilter-
FullTextQuery fullTextQuery = null; Factory). Konfiguracja Analyzer’a wpły-
List<AuthorEntity> list = null; wa na wielkość indeksu, szybkość jego za-
int resultSize = -1; pisu oraz Analyzer konieczny do genera-
try { cji poprawnego zapytania. Dla przykładu,
Analyzer analyzer = SynonymFilterFactory, na podstawie pła-
fullTextSession.getSearchFactory().getAnalyzer(AuthorEntity.class); skiego pliku definiującego synonimy, ge-
Query query = MultiFieldQueryParser.parse(new String[] {name, name}, neruje wszystkie możliwe wyrazy blisko-
new String[] { "firstName", "lastName" }, analyzer); znaczne danego słowa, a następnie zapisu-
fullTextQuery = je je do pliku indeksu, znacznie zwiększa-
fullTextSession.createFullTextQuery(query, AuthorEntity.class); jąc jego objętość. Filtr ten stanowi ponadto
list = fullTextQuery.setFirstResult((pageNumber - 1) * window). wyjątek reguły nakazującej stosowanie tego
setMaxResults(window).list(); samego Analyzer’a podczas zapisywania in-
resultSize = fullTextQuery.getResultSize(); deksu oraz generacji zapytania. Ze względu
} catch (ParseException e) { na złożoność działania niektórych filtrów,
log.error("Parse exception: " + e); odsyłam zainteresowanych Czytelników
} finally { do lektury ich dokumentacji oraz książki
releaseSession(session); Hibernate Search In Action. W żadnym wy-
} padku nie powinno się stosować wszyst-
return new Object[] {resultSize, list}; kich wymienionych wcześniej filtrów jed-
} nocześnie ze względu na czas indeksowania
oraz potencjalnie niewielką trafność zwra-
canych później wyników. Testowa aplika-
Tabela 2. Pomiar czasów procesu indeksowania dla FSDirectoryProvider cja zawiera przykładowe definicje każdego
Liczba słów do Liczba zindek- Czas indekso- Czas indeksowa- Zajętość miej- z wyżej omówionych filtrów. Do dyspozy-
zindeksowania sowanych termi- wania BookEnti- nia AuthorEnti- sca [KB] cji Czytelnika pozostawiam zamianę uży-
nów ty [ms] ty [ms] wanego Analyzer’a przez klasę BookEntity,
1453788 10700 48071 835 320 uruchomienie aplikacji oraz obserwację
3261806 15012 100878 1616 588 różnic w plikach indeksu przeglądanych
dzięki Luke.
4585970 18435 142773 2415 820
6916213 21539 179535 3236 980 Implementacja
9301547 26067 226505 4672 1380 metod pełnotekstowego
przeszukiwania danych
Posiadając skonfigurowaną fabrykę sesji
Tabela 3. Pomiar czasów procesu indeksowania dla RAMDirectoryProvider
oraz poszczególne encje, możemy przystą-
Liczba słów do Liczba zindek- Czas indekso- Czas indeksowa- Zajętość miej- pić do implementacji mechanizmu wyszu-
zindeksowania sowanych termi- wania BookEnti- nia AuthorEnti- sca [KB]
nów ty [ms] ty [ms]
kiwania. Hibernate Search oferuje kilka ro-
dzajów zapytań oraz samego sposobu zwra-
1453788 10700 47341 122 320
cania wyników. Do najczęściej stosowanych
3261806 15012 98727 167 588 zapytań należą TermQuery (wyszukiwanie
4585970 18435 140013 220 820 po pojedynczym atrybucie, umożliwia sto-
6916213 21539 178325 253 980 sowanie meta znaków takich jak ? czy *)
oraz MutiFieldQueryParser (analogiczne do
9301547 26067 218019 365 1380
TermQuery, lecz pozwalające wyszukiwać po
40 03/2010
Hibernate Search API
zbiorze atrybutów). Jedno z ciekawszych ro- kordów (tzw. okna). Stronicowanie minima- 2 Duo T9300 2,5 GHz, 3 GB RAM, HDD
dzajów zapytań to FuzzyQuery. Mechanizm lizuje nakład pracy bazy danych oraz redu- 7200 RPM, Windows XP Professional), na
ten wymaga określenia oczekiwanego podo- kuje wykorzystanie procesora i liczbę odczy- zbiorze pięćdziesięciu książek elektronicz-
bieństwa między dwoma wyrazami. W przy- tów z dysku przeprowadzanych przez Apa- nych zapisanych w formacie PDF. W sumie
padku różnej skali podobieństwa między ter- che Lucene. Ponadto zmniejszona zostaje zindeksowano 26 tysięcy terminów spośród
mami, lista zwracanych wyników może oka- liczba danych przesyłanych przez sieć, zuży- niespełna 10 milionów wyrazów, co zaję-
zać się zupełnie inna. Dla podobieństwa rów- cie procesora oraz pamięci aplikacji po stro- ło niecałe cztery minuty oraz 1,4 MB prze-
nego 0,1, po wpisaniu wymaganego zwrotu nie klienta, a w rezultacie czas odpowiedzi strzeni dyskowej. Do ekstrakcji tekstu z ksią-
eihrbnate, otrzymamy wyniki zawierające wy- programu. Użytkownicy przeglądają zazwy- żek PDF użyłem biblioteki PDFBox. Pomiar
raz Hibernate. Zwiększając wymagane podo- czaj jedynie pierwsze sto wyników spośród czasu wykonania poszczególnych metod war-
bieństwo do domyślnego 0,5, nie otrzymamy np. 100000 zwracanych, a dzięki dynamicz- stwy dostępu do danych zrealizowałem za po-
tak rozbieżnych rezultatów, lecz pojedyncza nej wielkości okna liczba ta może zostać mocą framework’u Java Execution Time Me-
przypadkowa zamiana kolejności liter zwró- dopasowana do indywidualnych potrzeb. asurement prezentującego zmierzone wyniki
ci oczekiwane pozycje. W wykonywaniu za- Przykładową implementację stronicowania w formie przejrzystej tabeli dostępnej pod ad-
pytań złożonych z całej frazy bardzo dobrze przedstawia Listing 5. resem http://localhost:40000. JETM wymaga
sprawdza się PhraseQuery. Implementacja ta Podsumowując, każdy programista powi- konfiguracji jedynie w pliku spring-config.xml,
potrafi dopasowywać wyniki ze zmienioną nien dopasować stosowany model zapytań dzięki czemu nie pogarsza przejrzystości ko-
kolejnością wyrazów. Parametr slop definiu- oraz zwracania ich wyników do wymogów du źródłowego. Obciążenie procesora oraz
je odległość między wyrazami (domyślnie 0 biznesowych oraz wydajnościowych konkret- pamięci śledzić można, uruchamiając na-
– wyrazy występujące w pierwotnie wprowa- nego projektu. rzędzie JConsole dostarczone wraz z maszy-
dzonej kolejności). Zaawansowani użytkow- ną wirtualną firmy Sun Microsystems. Uzy-
nicy wymagać mogą udostępnienia mecha- Testy wydajnościowe skane wykresy obciążenia sprzętu oraz czasy
nizmu wyszukiwania wykorzystującego wy- oraz optymalizacja wstawiania danych do indeksu dla różnych
rażenia regularne. Funkcjonalność tą oferuje Testy wydajnościowe przeprowadzone zo- implementacji DirectoryProvider’a przed-
biblioteka Apache Lucene Regex, której pro- stały na domowym komputerze (Intel Core stawiają Tabele 2, 3 oraz Wykresy 2 i 3.
ste użycie przedstawia Listing 3.
Przykłady stosowania omówionych rodza-
jów zapytań znajdują się w kodzie źródło-
wym testowej aplikacji dołączonej do czaso-
pisma na płycie CD.
Zwracane wyniki zapytań można ponad-
to zawężać, stosując bardzo wydajne filtry.
Filtry zawierają dodatkowe, predefiniowa-
ne dla danej klasy lub atrybutu kryteria wy-
szukiwania. Mechanizm ten działa analogicz-
nie do znanego tag’u filter-def oraz meto-
dy enableFilter ,wchodzących w skład Hi-
bernate Core (patrz Listing 4). Testy wydaj-
nościowe poszczególnych rodzajów zapytań
zaprezentowane zostaną w kolejnej sekcji ar-
tykułu.
Istotnym aspektem ze względów wydaj-
nościowych staje się sposób zwracania wy-
ników danego zapytania. Hibernate Se- Rysunek 2. Wykres obciążenia procesora podczas indeksowania 10 milionów wyrazów
arch dostarcza (standardowych dla narzę-
dzi rodziny Hibernate) metod list(), Listing 6. Kon�guracja asynchronicznego wątku Worker'a Hibernate Search
uniqueResult(), iterate() oraz scroll().
Funkcja list() to najprostszy i jednocze- hibernate.search.worker.execution = async
śnie najmniej wydajny sposób zwracania du- hibernate.search.worker.thread_pool.size = 2
żej liczby wyników, gdyż wszystkie obiek- hibernate.search.worker.buffer_queue.max = 50
ty zaciągane są od razu przy wykonywaniu
kwerendy. Problem ten częściowo rozwiązu- Listing 7. Kon�guracja automatycznej optymalizacji indeksu
je metoda scrollable(). Oferuje ona łatwe hibernate.search.default.optimizer.transaction_limit.max=50
w nawigowaniu API oraz ładowanie kon- hibernate.search.default.optimizer.operation_limit.max=100
kretnych pełnych obiektów wraz z doku-
mentami Apache Lucene dopiero w przy- Listing 8. Ręczna optymalizacja indeksu encji BookEntity
padku chęci z nich skorzystania, zmniejsza- public void optimize() {
jąc przy tym zużycie pamięci i czas ocze- Session session = getSession();
kiwania. Najbardziej wydajnym mechani- FullTextSession fullTextSession = Search.getFullTextSession(session);
zmem zwracania rezultatów okazuje się jed- fullTextSession.getSearchFactory().optimize(BookEntity.class);
nak stronicowanie. Algorytm ten polega na releaseSession(session);
wyspecyfikowaniu pozycji pierwszego ele- }
mentu oraz liczby kolejnych pożądanych re-
www.sdjournal.org 41
Warsztaty
Wyniki przeprowadzonych testów Większość programistów, skończywszy ne wąskim gardłem staje się czas wsta-
świadczą o niewielkiej różnicy w cza- implementacje określonej funkcjonalno- wiania danych do pliku indeksu. Przypo-
sie indeksowania dużych encji między ści systemu, zadaje sobie pytanie, czy nie minam, iż Apache Lucene wymaga cał-
dwoma popularnymi implementacjami istnieje możliwość przyspieszenia stworzo- kowitej blokady modyfikowanego indek-
DictionaryProvider'ów (kolumna doty- nego oprogramowania. W przypadku me- su oraz nie posiada metody modyfikacji
cząca BookEntity). Ponadto, czasy indekso- chanizmów wyszukiwania pełnoteksto- wcześniej wprowadzonych danych. Każ-
wania tak dużego zbioru danych wydają się wego optymalizacji podlegać może proces da zmiana (nawet pojedynczego atrybu-
w pełni akceptowalne. W przypadku testów wstawiania oraz wyszukiwania informa- tu) danego rekordu powoduje więc usu-
wydajnościowych poszczególnych rodzajów cji. Pierwsze pytanie, jakie powinien po- nięcie starego, powiązanego z nim doku-
zapytań bardzo duże znaczenie odgrywa sa- stawić przed sobą architekt aplikacji, doty- mentu, a następnie wstawienie nowego.
ma ich konfiguracja. Dla przykładu, im więk- czy konieczności indeksowania wszystkich Domyślnie, indeksowanie danych odbywa
sza wartość parametru similarity zapytań wskazanych pierwotnie danych. W apre- się synchronicznie podczas wykonywania
FuzzyQuery, tym szybciej wykonuje się dana zentowanym przykładzie należałoby in- metody commit(), co wymaga oczekiwania
kwerenda. Czasy mogą wahać się nawet od deksować jedynie krótkie streszczenie na uzyskanie pełnego dostępu do indek-
30 do 140 ms. Analogicznemu zachowaniu danej książki, a nie całą jej treść. Wymaga- su w przypadku uruchomienia wielu pro-
podlega PhraseQuery i parametr slop. Pod- nie to zależy jednak wyłącznie od warun- cesów współbieżnie modyfikujących da-
czas testów najszybciej wypadły zapytania ków logiki biznesowej i nie będę poświęcał ne. Istnieje jednak możliwość wykonywa-
TermQuery, dla których nie udało mi się prze- mu więcej czasu. nia operacji indeksowania asynchronicz-
kroczyć 0 ms. Czasy wykonania kwerend nie. Dodatkowo programista okręcić mo-
RegexQuery zależał silnie od samego wyraże- Optymalizacja indeksowania danych że maksymalną liczbę wątków współbież-
nia regularnego, lecz nawet przy użyciu tzw. Dla aplikacji wykonujących wiele współ- nie modyfikujących indeks oraz maksy-
wildcard'ów oscylował w granicach 70 ms. bieżnych operacji modyfikujących da- malną wielkość kolejki. Przykładową kon-
figurację obiektu SessionFactory przed-
stawia Listing 6.
Podczas wielokrotnego wstawiania i usu-
wania danych plik indeksu podlega frag-
mentacji. Pozostają w nim nieaktualne do-
kumenty, niepotrzebnie zajmujące prze-
strzeń dyskową oraz spowalniające wsta-
wianie oraz wyszukiwanie danych. De-
fragmentacją plików indeksu zajmuje się
proces optymalizacji. Proces ten urucho-
mić można automatycznie po wykonaniu
określonej liczby transakcji, pojedynczych
operacji lub też ręcznie dzięki metodzie
optimize() (Listing 7 i 8).
Większość tworzonych współcześnie
aplikacji posiada trójwarstwową architek-
turę klient-serwer. Warstwy dostępu do
danych, logiki biznesowej oraz prezenta-
cji uruchamiane są na osobnych maszy-
nach – komputerze klienckim, serwerze
Rysunek 3. Wykres zużycia pamięci podczas indeksowania 10 milionów wyrazów aplikacyjnym oraz serwerze bazy danych.
42 03/2010
Hibernate Search API
Hibernate Search umożliwia oddelegowa- wym. Komputery klienckie pobierają regu- nych atrybutów wchodzących w skład skom-
nie procesu indeksowania do dedykowa- larnie zmodyfikowane pliki indeksu (np. co plikowanych encji. Hibernate Search udo-
nego serwera. Diagram 5 przedstawia mo- godzinę). Jedyną wadą owego rozwiązania stępnia metodę setProjection() pozwa-
del owej architektury. Komputery klienc- wydaje się opóźnienie w propagacji zmo- lającą na wyspecyfikowanie pól zwracanych
kie posiadają lokalne kopie plików indek- dyfikowanych danych. W przypadku chęci przez zapytanie (Listing 9). Wartości atry-
su, na których wykonują operacje wyszuki- zapoznania się ze szczegółami konfiguracji butów tych muszą być jednak przechowy-
wania. Chęć modyfikacji danych zgłaszana master’a oraz slave’ów odsyłam zaintereso- wane zarówno w bazie danych, jak i w pli-
jest przez umieszczenie odpowiedniej wia- wanego Czytelnika do książki Hibernate Se- kach indeksu (opcja store=Store.YES ad-
domości w kolejce JMS serwera. Proces ten arch in Action. notacji @Field). Dzięki projekcjom progra-
odbywa się asynchronicznie, co nie wstrzy- mista unika przesyłania przez sieć nadmia-
muje pracy komputerów klienckich. Ser- Optymalizacja wyszukiwani danych rowych danych, przechowywania ich w pa-
wer odpowiedzialny za indeksowanie da- Optymalizacja procesu wyszukiwania da- mięci oraz ewentualną niepotrzebną ob-
nych (master) przetwarza żądania klien- nych w dużym stopniu przypomina opty- róbkę na terminalu klienckim. Znaczący
tów (slave) oraz umieszcza wynikowe pliki malizację zapytań SQL. Należy zwrócić wzrost wydajności systemu obserwuje się
indeksu w udostępnionym folderze siecio- uwagę na pobieranie wyłącznie wymaga- podczas stosowania algorytmu stronicowa-
nia w celu zwracania wyników zapytań. Hi-
bernate nie pobiera wówczas ogromnej ilo-
ści danych, większości których użytkownik
i tak nie przejrzy.
Podsumowanie
Artykuł ten zaprezentował podstawy me-
chanizmu wyszukiwania pełnotekstowe-
go opartego na Hibernate Search. Dzięki
�������� bardzo przystępnemu oraz w dużej mie-
����
��������
rze przezroczystemu dla programisty API,
���� system ten wprowadzić można do działają-
cych już aplikacji bez konieczności grun-
townej zmiany implementacji warstwy
dostępu do danych. Hibernate Search
������ ������ ������ ������ ������
������ ������
udostępnia ponadto szeroką gamę para-
������ ������ ������
������� ������� ������� ������� �������� metrów, umożliwiając dopasowanie dzia-
łania owego narzędzia do własnych po-
trzeb. Podstawową sprawą wydaje się jed-
nak dobór indeksowanych danych, Analy-
zer’a oraz rodzaju wykonywanego zapyta-
nia, gdyż właśnie te czynniki wpływają na
jakość zwracanych rekordów, które powin-
ny zadowalać użytkownika końcowego. Hi-
�����
�����
����� ����� ����� bernate Search to ciekawa alternatywa dla
����� ����� �����
���� ���� ���� ������������ usługi Full-Text Search dostępnej w Mi-
����
crosoft SQL Server 2005/2008 (opisanej
����������� w Software Developer’s Journal 7/2009).
���������
Przewagę omawianego narzędzia stanowi
niezależność od implementacji konkret-
nego RDBMS, bezpłatny, powszechny do-
stęp oraz możliwość większego rozprosze-
nia aplikacji – rozłożenia mocy oblicze-
niowej. W celu dalszego zgłębiania swo-
���������������������������������
������������������
jej wiedzy na temat Hibernate Search po-
������������ lecam Czytelnikom książkę Hibernate Se-
arch in Action.
ŁUKASZ ANTONIAK
Rysunek 5. Architektura z wykorzystaniem asynchronicznego klastra (źródło: Emmanuel Bernard – Łukasz Antoniak pracuje w �rmie Oracle Polska
„Hibernate Search in Action”)
na stanowisku programisty Java EE/SE. Na co
dzień zajmuje się tworzeniem aplikacji bazoda-
nowych z wykorzystaniem produktów rodziny
W Sieci Oracle Fusion Middleware. Od niedawna stosu-
• Strona domowa projektu Hibernate Search: https://www.hibernate.org/410.html; je także popularne rozwiązania open-source: Hi-
• Dzone Refcardz: http://refcardz.dzone.com/refcardz/getting-started-with-hibernate. bernate oraz Spring Framework.
Kontakt z autorem: lukasz.antoniak@oracle.com
www.sdjournal.org 43
Warsztaty
Spring.NET
– uniwersalny spinacz
Wprowadzenie do konfiguracji fabryki obiektów
S
pring Framework powstał domyślnie na mistów .NET lub tych, którzy jeszcze nie tów, co można również definiować za pomo-
platformę Java ponad 5 lat temu. Szybko mieli okazji zetknąć się ze Springiem. Za- cą pliku XML. Domyślnie wszystkie obiek-
zdobył dużą popularność ze względu na pewniam, że naprawdę warto się tym na- ty pobierane z fabryki są singletonami, czyli
bardzo interesujący model działania. Osiowym rzędziem zainteresować, ponieważ znacz- możemy mieć pewność, że raz zdefiniowany
elementem szkieletu był tak zwany kontener nie ułatwia ono tworzenie, testowanie oraz i skonfigurowany obiekt jest dostępny przez
IoC, czyli Inversion of Control (szczegóły w ram- późniejszy rozwój i utrzymanie aplikacji. cały czas działania aplikacji w postaci jednej
ce Inversion of Control – odwrócenie kontro- A więc zacznijmy. instancji. W zależności jednak od potrzeb
li) oraz Dependency Injection (szczegóły w ram- można obiekt tworzyć na nowo za każdym
ce Dependency Injection – wstrzykiwanie zależ- Jak działa Spring razem, kiedy zaistnieje potrzeba jego użycia
ności). Wspomniany kontener w łatwy sposób Spring, jak już zostało to wspomniane lub, w przypadku aplikacji sieciowej, ograni-
umożliwiał konfigurowanie aplikacji. W toku w Ramkach, jest lekkim kontenerem obiek- czać czas życia obiektów do charakterystycz-
swojego rozwoju Spring otrzymywał kolejne
możliwości integracji kontenera z innymi popu- Inversion of Control – odwrócenie kontroli
larnymi platformami wspomagającymi tworze- Termin ten opisuje ogólną zasadę działania wzorca projektowego fabryki, lokalizatora usług
nie aplikacji we wszystkich jej warstwach. Licz- lub innych wymienionych w ramce Dependency Injection – wstrzykiwanie zależności. Zwy-
ne zalety platformy sprawiły, że Spring szybko czajowo obiekty aplikacji są tworzone w kodzie poprzez użycie operatora new. Odwróce-
zyskał ogromną popularność i w równie krót- nie kontroli polega zatem na pobieraniu obiektów poprzez wywołanie odpowiedniej me-
tody z obiektu fabrykującego. Wzorzec ten wielokrotnie udowodnił swoją przydatność i jest
kim czasie stał się podstawowym narzędziem
jednym z najpowszechniej wykorzystywanych szablonów projektowych. Niewątpliwą zale-
tworzenia średnich i dużych aplikacji. Począt- tą jest brak zależności w kodzie aplikacji od faktycznej implementacji wykorzystywanej usłu-
kowo rozwijany tylko na platformie Java, znalazł gi. Kod aplikacji jest skupiony na wykonywaniu swojego zadania, czyli delegowaniu wyko-
również zainteresowanie w środowisku .NET. nania pewnych działań do obiektów usług, nie dbając o to, jak te działania są wykonywa-
I tak narodził się osobno rozwijany projekt w ra- ne. Efektem tego jest większa swoboda mody�kacji aplikacji, jako że kod nie jest uzależnio-
mach Spring Framework – Spring.NET. ny od konkretnych , a zatem nie ma potrzeby kontrolowania kodu w wielu miejscach w razie
zmiany wykorzystywanej implementacji. Kontener IoC Springa to scentralizowane miejsce,
Jako że platforma .NET nie jest tak popu- skąd są pobierane wszystkie de�nicje obiektów, dodatkowo jest on kon�gurowany za pomo-
larna w naszym kraju jak Java, to mam na- cą plików XML, co w konsekwencji prowadzi do całkowitego braku potrzeby mody�kowania
dzieję, że ten artykuł znajdzie zaintereso- kodu w razie zmiany implementacji usług.
wanie i zachęci czytelników do korzystania
44 03/2010
Wprowadzenie do Spring.NET
nych dla protokołu HTTP zasięgów request, ciu operatora new w kodzie aplikacji. Poda- cją). Nazwy te będą uważane za aliasy te-
session czy application. ne id musi być unikatowe i przestrzegać ob- go obiektu.
Spring, jakkolwiek, nie jest typem rozwią- ostrzeń nałożonych na element id w for- Specyfikując typ inicjowanego obiektu, nale-
zania, które wymusza użycia całego zestawu macie XML. Można jednak podać dowol- ży pamiętać o podaniu pełnej ścieżki przestrze-
swoich funkcji, można bowiem wykorzystać ną ilość nazw w elemencie name (rozdzie- ni nazw, jak i nazwy assembly, w którym skom-
tylko niewielki zakres jego możliwości dopa- lonych przecinkiem, średnikiem lub spa- pilowany jest dany typ. Spring zawsze użyje naj-
sowany do aktualnych potrzeb. Spring Frame-
work jest podzielony na szereg modułów, każ- Listing 1. Przykład kon�guracji aplikacji za pomocą pliku App.con�g
dy z nich to osobna biblioteka, nie ma zatem
również potrzeby importowania niepotrzeb- <configuration>
nych przestrzeni nazw, z których w ogóle by <configSections>
się nie korzystało. Dodatkowo Spring umoż- <sectionGroup name="spring">
liwia rozbudowę każdego swojego elemen- <section name="context" type="Spring.Context.Support.ContextHandler,
tu. Wszystkie oferowane możliwości są opar- Spring.Core"/>
te na interfejsach, które w zależności od po- </sectionGroup>
trzeb można zaimplementować, dostarczając <sectionGroup name="common">
własnych rozwiązań. <section name="logging" type="Common.Logging.ConfigurationSectionHandler,
Common.Logging" />
Kontener IoC </sectionGroup>
– podstawy konfiguracji </configSections>
Teraz, mając już stworzony nowy projekt i za-
importowane biblioteki oraz skonfigurowa- <common>
ny kontekst Springa (patrz ramka Konfigura- <logging>
cja), możemy napisać pierwszy przykład. Plik <factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter,
konfiguracyjny app-config.xml powinien wy- Common.Logging">
glądać ępująco – Listing 2. <arg key="level" value="OFF" />
Głównym elementem pliku konfiguracyj- </factoryAdapter>
nego jest element objects, który będzie za- </logging>
wierał w sobie kolejne elementy definiujące </common>
poszczególne obiekty. Aby nasz plik XML
mógł być walidowany przez środowisko pro- <spring>
gramistyczne, zostały do elementu objects <context>
dodane dodatkowe atrybuty definiujące loka- <resource uri="assembly://SpringExample1/SpringExample1.config/app-config.xml"
lizację pliku typu XML Schema, który odpo- />
wiada za poprawność struktury dokumentu. </context>
Warto już w tej chwili wspomnieć, że </spring>
Spring umożliwia logiczne rozbicie konfigu- </configuration>
racji XML na kilka plików. Aby definicje z in-
nych plików były widoczne przez kontener, Listing 2. Przykład podstawowej de�nicji pliku kon�guracyjnego app-con�g.xml
należy zaimportować je za pomocą elemen- <objects xmlns="http://www.springframework.net"
tu import. Na przykład: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.net
<import resource="services.xml"/> http://www.springframework.net/xsd/spring-objects.xsd">
www.sdjournal.org 45
Warsztaty
W ten sposób mamy skon�gurowany projekt i możemy przystąpić do napisania pierwszego Z powodu ograniczeń nałożonych na składnię
przykładu. XML, znak mniejszości musi być zapisany za
pomocą tak zwanego bytu HTML – <
46 03/2010
Wprowadzenie do Spring.NET
www.sdjournal.org 47
Warsztaty
Description oraz Value i ustawia je na war- wej konwersji typu z postaci tekstowej. Potrafi Wstrzykiwanie
tość „Opis” oraz wartość 25. on przekonwertować każdy typ wbudowany. zależności za pomocą konstruktora
Zależność deklaruje się, wskazując najpierw Jeśli obiekt nie definiuje żadnej właściwości lub Wstrzykiwanie zależności za pomocą kon-
nazwę właściwości, która jest definiowana, a na- po prostu żadnej ze zdefiniowanych nie chcemy struktora odbywa się poprzez wywołanie
stępnie podaje się jej wartość. Spring potrafi na ustawić, wówczas element object pozostaje pu- konstruktora, którego parametry stano-
podstawie typu właściwości dokonać prawidło- sty, jak we wcześniejszych przykładach. wią zależności. Definiowanie konstruktora
oraz metody fabrykującej wygląda w zasa-
Listing 13. Deklarowanie elementów kolekcji typu nazwa-wartość dzie identycznie, jako że stosuje się w obu
przypadkach te same elementy definiujące
<object id="Collections3" type="SpringExample1.CollectionsDependantClass"> argumenty.
<property name="nameValueCollection"> Argumenty konstruktora definiuje się
<name-values> podobnie jak właściwości typu set, jed-
<add key="text" value="NVC text"/> nak zamiast elementu property używamy
<add key="object" value="It can only be string"/> constructor-arg. Należy pamiętać, że cza-
</name-values> sem typ parametru może być niejednoznacz-
</property> ny i Spring nie poradzi sobie z jego rozwikła-
</object> niem. Możemy wówczas użyć trzech metod
dopasowywania typu.
Listing 14. Deklarowanie elementów słownika
Dopasowywanie
<object id="Collections4" type="SpringExample1.CollectionsDependantClass"> po indeksie argumentu
<property name="dictionary"> Jest to domyślne zachowanie. Spring postara
<dictionary> się dokonać konwersji typu według typów za-
<entry> deklarowanych w konstruktorze w takiej ko-
<key> lejności, w jakiej zdefiniowane zostały w pli-
<value>key</value> ku XML, czyli:
</key>
<ref local="MyClass2"/> <object id="MyClass1"
</entry> type="SpringExample1.MyClass">
<entry key="textKey" value="textValue"/> <constructor-arg value="Opis1"/>
<entry key-ref="MyClass2" value-ref="MyClass3"/> <constructor-arg value="1"/>
</dictionary> </object>
</property>
</object> Jeśli kolejność argumentów zostałaby za-
mieniona, wówczas Spring zgłosiłby wyją-
Listing 15. a będąca kontenerem kolekcji generycznych tek w momencie inicjalizowania obiektu,
twierdząc, że wartość „Opis” nie ma wła-
public class GenericCollectionsDependantClass ściwego formatu, by przekonwertować ją
{ na ę Int32. Można jednak jawnie zadeklaro-
public IList<Container<MyClass>> List { get; set; } wać kolejność użycia argumentów. Służy do
public IDictionary<string, int> Dictionary { get; set; } tego atrybut index, który powie Springowi,
} do którego argumentu dopasować deklaro-
waną wartość.
Listing 16. Deklarowanie kolekcji generycznych
<object id="MyClass2"
<object id="GenericCollections" type="SpringExample1.GenericCollectionsDependantC type="SpringExample1.MyClass">
lass"> <constructor-arg index="1" value="2"/>
<property name="list"> <constructor-arg index="0"
<list element-type="int"> value="Opis2"/>
<value>1</value> </object>
<value>2</value>
<value>3</value> Należy pamiętać, że indeksowanie zaczyna
</list> się od zera.
</property>
<property name="dictionary"> Dopasowywanie według
<dictionary key-type="string" value-type="int"> jawnie zadeklarowanego typu
<entry key="value1" value="5"/> Jak zostało wspomniane w poprzedniej sek-
<entry key="value2" value="10"/> cji, zamiana kolejności spowoduje błąd, moż-
<entry key="value3" value="15"/> na jednak podpowiedzieć Springowi, jakie-
</dictionary> go typu jest dany argument tak, by był w sta-
</property> nie dokonać prawidłowej konwersji niezależ-
</object> nie od kolejności argumentów. Służy do tego
atrybut type.
48 03/2010
Wprowadzenie do Spring.NET
<object id="MyClass3" • <ref parent="MyClass2"/> – dzia- W ten sposób nie wstrzykujemy referencji
type="SpringExample1.MyClass"> ła podobnie jak atrybut object, z tą do obiektu, a jedynie wartość id zdefiniowa-
<constructor-arg type="int" value="3"/> różnicą, iż wskazuje na poszukiwa- ną w pliku konfiguracyjnym. Użyteczne, je-
<constructor-arg type="string" nie obiektu w kontenerze fabryki nad- śli kiedyś któryś ze zdefiniowanych obiektów
value="Opis3"/> rzędnej. Bardzo rzadko stosowany potrzebowałby bezpośrednio odwołać się do
</object> w praktyce. fabryki, by wydobyć konkretny obiekt.
Element ten również jest rzadko stosowa-
Dopasowywanie po nazwie argumentu Możliwe jest również stworzenie dowiąza- ny w praktyce.
To dopasowanie odbywa się na podstawie za- nia do wartości id innego obiektu za pomocą Istnieje również skrócona notacja wstrzyki-
deklarowanej w klasie nazwy argumentu, którą elementu idref. Na przykład: wania referencji do właściwości:
wskazuje się w pliku XML za pomocą atrybutu
name. Działa to podobnie jak indeksowanie argu- <idref local="MyClass2"/> <property name="content" ref="MyClass2"/>
mentów, z tą różnicą, że jest bardziej czytelne.
Listing 17. Scalanie kolekcji
<object id="MyClass4"
type="SpringExample1.MyClass"> <object id="Parent" type="SpringExample1.CollectionsDependantClass"
<constructor-arg name="value" abstract="true">
value="4"/> <property name="nameValueCollection">
<constructor-arg name="description" <name-values>
value="Opis4"/> <add key="key1" value="value1"/>
</object> <add key="key2" value="value2"/>
</name-values>
Wstrzykiwanie zależności za pomocą właści- </property>
wości, jak i konstruktora można ze sobą łą- </object>
czyć. Nic nie stoi na przeszkodzie, by pew-
ne zależności zdefiniować w konstruktorze, <object id="Child" parent="Parent">
a inne za pomocą właściwości. Kiedy uży- <property name="nameValueCollection">
wać którego podejścia? Ogólnie, za pomocą <name-values merge="true">
konstruktora powinno się ustawiać zależno- <add key="key3" value="value3"/> <!-- Dodana zostanie nowa wartość pod
ści wymagane oraz tylko do odczytu, zaś za kluczem 'key3' -->
pomocą właściwości te opcjonalne oraz te, <add key="key2" value="new value"/> <!-- Stara wartość pod kluczem 'key2'
które mogą być swobodnie modyfikowane. zostanie zastąpiona nową -->
</name-values>
Szczegółowe omówienie </property>
konfiguracji zależności </object>
Do tej pory we wszystkich przykładach ope-
rowaliśmy na typach prostych, takich jak Listing 18. Przykład klasy deklarującej zależność od zagnieżdżonej listy list, tablicy asocjacyjnej
oraz tablicy wielowymiarowej.
string czy int. Możliwe jest jednak również
deklarowanie typów referencyjnych czy ko-
lekcji, i na tym skupią się kolejne sekcje. public class IndexedClass
{
Wstrzykiwanie zależności od obiektów public IList List { get; set; }
referencyjnych za pomocą elementu ref. public IDictionary Dictionary { get; set; }
Element ref służy do definiowania zależ- public int[,] Table { get; set; }
ności od innych zdefiniowanych wcześniej
obiektów referencyjnych. Używa się go w na- public IList this[int index]
stępujący sposób – Listing 8. {
Może on przyjmować ępujące postaci: get { return this.List[index] as IList; }
set { this.List[index] = value as IList; }
• <ref object="MyClass2"/> – odwołuje }
się do innego zdefiniowanego wcześniej public object this[string key]
obiektu w fabryce. Wartość atrybutu ob- {
ject może wskazywać zarówno na id in- get { return this.Dictionary[key]; }
nego obiektu, jak i na dowolną wartość set { this.Dictionary[key] = value; }
atrybutu name. }
• <ref local="MyClass2"/> – odwołuje się public int this[int dim1Index, int dim2Index]
do innego zdefiniowanego obiektu w obrę- {
bie tego samego dokumentu XML. War- get { return this.Table[dim1Index, dim2Index]; }
tość atrybutu local musi wskazywać na set { this.Table[dim1Index, dim2Index] = value; }
id obiektu zdefiniowanego w edytowa- }
nym pliku. Umożliwia to sprawdzenie po- }
prawności użytej nazwy już na etapie wali-
dacji dokumentu XML.
www.sdjournal.org 49
Warsztaty
W ten jednak sposób domyślnie używamy by jednego obiektu. Nie ma zatem potrzeby ne. Obiekt zagnieżdżony definiujemy zatem
zakresu object. definiować go jako niezależnego bytu z wła- ępująco – Listing 9.
snym id. Wystarczy zadeklarować go jako
Zagnieżdżone obiekty anonimowe obiekt zagnieżdżony. Nie będzie go jednak Deklarowanie wartości kolekcji
Nieraz zdarza się, że definicja danego obiek- można już wówczas bezpośrednio pobrać Częstym przypadkiem jest zależność obiek-
tu jest używana tylko jednokrotnie na potrze- z fabryki, ale przecież nie będzie to potrzeb- tów od kolekcji. Spring udostępnia cztery ty-
py elementów: list, set, name-values i dic-
Listing 19. De�niowanie niegenerycznych kolekcji klasy za pomocą indekserów tionary, które służą do deklarowania zależ-
ności w kolekcjach typów (odpowiednio):
<object id="IndexedClass" type="SpringExample1.IndexedClass"> IList, ISet, NameValueCollection i IDic-
<property name="list"><!-- Inicjujemy listę do której elementów będziemy się tionary. Przykłady użycia znajdują się poni-
odwoływać za pomocą indeksu --> żej, zdefiniujmy jednak najpierw ę, której bę-
<list> dziemy używać jako kontenera naszych ko-
<list> lekcji (Listing 10).
<value>0</value>
</list> Lista
</list> Listę deklarujemy za pomocą elementu list.
</property> Następnie znajdują się elementy listy. Ponie-
<property name="dictionary"><!-- Inicjujemy instancję słowika --> waż lista nie jest generyczna, można jej przy-
<dictionary/> pisać dowolny typ wartości, co też widać w
</property> przykładzie. Możliwe jest dalsze zagnież-
<property name="table" expression="new int[1,1]"/> <!-- Inicjumemy instancję dżanie kolekcji lub utworzenie obiektu we-
tablicy --> wnętrznego – wszystkie elementy definiują-
ce zależności są dozwolone.
<property name="[0][0]"><!-- Ustawiamy pierwszy element listy będący pierwszym
elementem listy 'list' za pomocą indeksu --> Zbiór
<value>-5</value> Deklaracja zbioru wygląda prawie identycz-
</property> nie. Jedyna różnica wynika z definicji zbioru,
który uniemożliwia przechowywanie iden-
<property name="['keyOne']" value="10"/><!-- Ustawiamy element słownika pod tycznych elementów. Proszę się zatem nie
kluczem 'keyOne' w tym wypadku dodajemy nową wartość do zdziwić, jeśli po zadeklarowaniu zbioru we-
pustej tablicy asocjacyjnej --> dług powyższego przykładu, zawierającego
z pozoru dwa elementy, po wyświetleniu za-
<property name="[0,0]"><!-- Ustawiamy pierwszy i jedyny element tablicy wartości okaże się, że zdefiniowany zbiór za-
dwuwymiarowej za pomocą indeksu --> wiera tylko jeden wpis.
<value type="int">-24</value>
</property> Kolekcja nazwa-wartość
</object> Jest to specyficzny typ kolekcji, który zawie-
ra elementy składające się z dwóch wartości
Listing 20. Generyczna klasa z indekserami tekstowych, z których pierwsza jest kluczem,
public class GenericIndexedClass<T> a druga wartością.
{ Kolekcję nazwa-wartość deklaruje się za po-
public IList<IList<T>> List { get; set; } mocą elementu name-values, zaś poszczegól-
public IDictionary<string, T> Dictionary { get; set; } ne wpisy za pomocą elementu add, wewnątrz
public T[,] Table { get; set; } którego za pomocą atrybutów key oraz value
definiujemy faktyczną zawartość danego wpi-
public IList<T> this[int index] su kolekcji.
{
get { return this.List[index]; } Słownik
set { this.List[index] = value; } Słownik jest tablicą asocjacyjną, podobnie jak
} kolekcja nazwa-wartość, z tą różnicą, że klucz
public T this[string key] oraz wartość mogą być dowolnymi obiekta-
{ mi. Słownik definiuje się za pomocą elemen-
get { return this.Dictionary[key]; } tu dictionary. Poszczególne wpisy w słow-
set { this.Dictionary[key] = value; } niku dodaje się za pomocą elementu entry.
} Wewnątrz niego umieszcza się element key,
public T this[int dim1Index, int dim2Index] w którym zawierać się mogą dowolne ele-
{ menty, takie jak value, ref, idref i inne, po-
get { return this.Table[dim1Index, dim2Index]; } dobnie jak w przypadku listy czy zbioru. ęp-
set { this.Table[dim1Index, dim2Index] = value; } ny element wewnątrz entry definiuje war-
} tość i może znowu być dowolnym dozwolo-
} nym elementem definiującym. Istnieje rów-
nież notacja skrócona, jak w przykładzie,
50 03/2010
Wprowadzenie do Spring.NET
umożliwiająca w jednaj linijce zdefiniować w fabryce obiektu, który posiada zależność od oraz nadpisanie już istniejących. Funkcjonal-
wpis za pomocą atrybutów elementu entry. kolekcji, może zdefiniować tę kolekcję na nowo. ność ta szczególnie się przydaje w sytuacji, gdy
Atrybutami tymi są: Efektem będzie dodanie elementów nowych mamy jeden wspólny obiekt rodzicielski z li-
• key – klucz będący tekstem; Listing 21. De�niowanie generycznych kolekcji klasy za pomocą indekserów
• – klucz będący referencją do
key-ref
wcześniej zdefiniowanego obiektu; <object id="GenericIndexedClass" type="SpringExample1.GenericIndexedClass<double>
• value – wartość będąca tekstem; ">
• value-ref – wartość będąca referencją. <property name="list">
<list element-type="System.Collections.Generic.IList<double>">
Oczywiście wszystkie cztery kombinacje <list element-type="double">
użycia są dozwolone. <value>0</value>
</list>
Deklarowanie </list>
wartości kolekcji generycznych </property>
Deklarowanie kolekcji generycznych wyglą-
da podobnie, z tą różnicą, że nie można mie- <property name="dictionary">
szać typów elementów w kolekcji, jak miało <dictionary key-type="string" value-type="double"/>
to miejsce w przykładach z poprzedniej sek- </property>
cji. W tym wypadku odpadają nam również
kolekcje typu nazwa-wartość oraz zbiór, po- <property name="table" expression="new double[1,1]"/>
nieważ nie są generyczne.
Zdefiniujmy najpierw ę zawierającą kolek- <property name="[0][0]">
cje generyczne (Listing 15). <value type="double">-18.6</value>
Deklarowanie kolekcji generycznych wy- </property>
gląda ępująco – Listing 16.
Jak widać w przykładzie, elementy list <property name="['keyTwo']">
oraz dictionary mają specjalne atrybuty, za <value type="double">30.4</value>
pomocą których deklarujemy typ elementów </property>
kolekcji. Należy jednak pamiętać o zgodności
typów. Jeśli spróbujemy utworzyć niegene- <property name="[0,0]">
ryczną deklarację kolekcji generycznej (i vi- <value type="double">6.23e+2</value>
ce versa), wówczas podczas tworzenia fabry- </property>
ki Spring zgłosi wyjątek, mówiąc, że nie mo- </object>
że utworzyć kolekcji, ponieważ zaistniała nie-
zgodność typów. Wyjątek ten może wyglądać Listing 22. Przykład klasy de�niującej zdarzenia
ępująco:
public class Processor<T>
Core.TypeMismatchException: Cannot convert {
property value of public event ProcessorEventHandler<T> ProcessingComplete;
type [System.Collec public event ProcessorEventHandler<T> ProcessingStarted;
tions.ArrayList] to
required type [Sys public void ProcessData(T data, Func<T, T> action)
tem.Collections.Ge {
neric.IList`1] for processingStarted(data);
property 'list'. new Thread(() => { processingComplete(action(data)); }).Start();
}
Taka postać zgłoszonego wyjątku wynika private void processingComplete(T processedData)
z faktu, że z powodu braku generycznego ty- {
pu w deklaracji listy Spring próbuje do gene- if (ProcessingComplete != null)
rycznego interfejsu przypisać niegeneryczną {
implementację, co jest błędem. ProcessingComplete(this, new ProcessorEventArgs<T>(processedData));
}
Scalanie kolekcji }
Spring umożliwia (od wersji 1.3) scalanie private void processingStarted(T dataToBeProcessed)
kolekcji zdefiniowanej w obiekcie rodziciel- {
skim z kolekcją w obiekcie dziedziczącym. if(ProcessingStarted != null)
Na temat dziedziczenia obiektów w fabry- {
ce Springa użytkownik będzie mógł prze- ProcessingStarted(this, new ProcessorEventArgs<T>(dataToBeProcessed));
czytać później w sekcji Dziedziczenie defini- }
cji obiektów. }
Zasada scalania kolekcji polega na tym, że }
obiekt dziedziczący z innego zdefiniowanego
www.sdjournal.org 51
Warsztaty
stą, która powinna być zdefiniowana podobnie Ustawianie stać specjalny moduł Springa, jakim jest ję-
dla każdego dziecka. Użytkownik, chcąc dodać wartości list za pomocą indekserów zyk wyrażeń. Atrybut expression występu-
nowe lub zmienić niektóre z elementów w jed- Bardzo ciekawą własnością języka C# jest prze- je w każdym elemencie definiującym wartość
nym z dziedziczonych obiektów bez potrzeby ciążanie operatora indeksującego. Można za jego i jest alternatywą dla atrybutu value, w prze-
definiowania kolekcji od nowa, może skorzystać pomocą odwoływać się do elementów klasy, jak ciwieństwie do którego umożliwia obliczenie
z mechanizmu scalania kolekcji, który właśnie do kolekcji (najczęściej do wewnętrznej kolekcji wartości na podstawie podanego wyrażenia.
to umożliwia. Proszę prześledzić poniższy przy- klasy). Spring umożliwia zatem konfigurowanie W tym wypadku zainicjowania nowej jedno-
kład – Listing 17. wartości pól klasy za pomocą indeksów. elementowej tablicy dwuwymiarowej.
W powyższym przykładzie zadeklarowany zo- Zdefiniujmy przykładową klasę IndexedClass Język wyrażeń (SpEL) dostarczany przez
stał obiekt rodzicielski parent, stanowiący sza- zawierającą trzy najczęściej używane typy kolek- Springa jest potężnym i wygodnym narzę-
blon dla obiektu potomnego child. Dokładny cji: zagnieżdżoną listę list, tablicę asocjacyjną oraz dziem, którego dokładny opis wykracza poza
mechanizm dziedziczenia zostanie wyjaśniony tablicę wielowymiarową. Banalny przypadek ta- ramy tego artykułu. Zainteresowanych odsy-
później, w tej chwili istotne jest, że obiekt dzie- blicy jednowymiarowej został pominięty. łam do dokumentacji Springa.
dziczący definiuje atrybut merge="true" dla ko- Teraz zdefiniujemy zawartość kolekcji tej Dodatkową rzeczą, na którą chciałbym zwró-
lekcji, którą scala. W przypadku braku tego atry- klasy za pomocą jej indekserów – Listing 19. cić uwagę czytelnika, jest deklaracja typu ele-
butu kolekcja zostałaby nadpisana całkowicie. Proszę zwrócić uwagę na nowy atrybut, ja- mentu w przypadku dostępu za pomocą in-
Dzięki niemu zaś kolekcja wynikowa ma trzy ele- ki pojawił się w elemencie property inicjują- deksera wielowymiarowego. Z niewiadomych
menty (nie dwa) jako efekt scalenia. Dodatkowo cym tablicę dwuwymiarową – expression. przyczyn brak tej deklaracji powoduje zgłosze-
wartość elementu key2 została nadpisana nową. Za pomocą tego atrybutu możemy wykorzy- nie wyjątku o nieprawidłowym typie indeksu.
Jest to o tyle dziwne, że występuje tylko w przy-
Listing 23. Typ delegujący de�niujący rodzaj funkcji obsługujących zdarzenia padku indeksera wielowymiarowego.
To jednak nie wszystko – skoro możliwe jest
public delegate void ProcessorEventHandler<T>(object source, ProcessorEventArgs<T> definiowanie typów generycznych oraz kolekcji
args); generycznych, dlaczego nie pokusić się o defini-
cję łączącą oba elementy w jedną całość.
Listing 24. Klasa będąca kontenerem argumentów zdarzeń Rozważmy następującą klasę (Listing 20).
public class ProcessorEventArgs<T> A następnie zdefiniujmy jej zawartość (Li-
{ sting 21).
public T ProcessedData { get; private set; } Tym razem deklaracja typu jest obecna na
każdym elemencie definiującym i nie powin-
public ProcessorEventArgs() { } na już dziwić.
W kilku powyższych sekcjach omówione
public ProcessorEventArgs(T processedData) zostały szczegółowe sposoby definiowania
{ specyficznych typów zależności, takich jak na
this.ProcessedData = processedData; przykład listy. W ępnej sekcji pokażemy, jak
} można deklaratywnie skonfigurować metody
} obsługi zdarzeń.
Listing 25. Klasa będąca kontenerem funkcji obsługi zdarzeń Deklaratywne rejestrowanie
public class ProcessorListener<T> metod obsługi zdarzeń
{ Zdarzenia w języku C# są częścią jego specyfi-
public void ProcessingStartedHandleEvent(object source, ProcessorEventArgs<T> args) kacji. Za pomocą słowa kluczowego event de-
{ finiuje się zdarzenie, do którego podpina się
//operacje wykonywane przed rozpoczęciem przetwarzania jedną lub więcej funkcji, które zostaną wyko-
} nane w momencie aktywowania zdarzenia.
public void ProcessingCompleteHandleEvent(object source, ProcessorEventArgs<T> args) Spring umożliwia deklaratywne podpięcie
{ funkcji obsługujących zdarzenia do obiektów
//operacje wykonywane po zakończeniu przetwarzania je zgłaszających w reakcji na ich aktywację.
} Rozważmy klasę definiującą dwa zdarzenia
} (Listing 22).
Klasa ta jest prostym odpowiednikiem klasy
Listing 26. De�niowanie obsługi zdarzeń za pomocą Springa BackgroundWorker z pakietu .NET. Jedynym jej
<object id="Processor" type="SpringExample1.Processor<string>"/> zadaniem jest uruchomienie funkcji przekaza-
nej jako parametr w osobnym wątku, informu-
<object id="ProcessorListener" type="SpringExample1.ProcessorListener<string>"> jąc poprzez zdarzenia o rozpoczęciu oraz zakoń-
<listener event="ProcessingStarted" method="ProcessingStartedHandleEvent"> czeniu przetwarzania danych.
<ref local="Processor"/> Na potrzeby naszego przykładu potrzeb-
</listener> ny będzie również typ delegacyjny, definiu-
<listener event="ProcessingComplete" method="ProcessingFinishedHandleEvent"> jący rodzaj funkcji obsługujących zdarzenia
<ref local="Processor"/> (Listing 23).
</listener> Klasa ProcessorEventArgs jest kontene-
</object> rem argumentów przekazywanych do funk-
cji obsługi zdarzenia (Listing 24).
52 03/2010
Wprowadzenie do Spring.NET
Ostatnim niezbędnym elementem jest często w sytuacji, w której czas potrzebny na gdy po raz pierwszy fabryka otrzyma żądanie
a będąca kontenerem funkcji obsługi zdarzeń inicjalizację obiektu jest długi lub gdy chce- zwrócenia danego obiektu.
(Listing 25). my już na etapie uruchamiania aplikacji być
Mając zdefiniowane wszystkie niezbędne ele- poinformowani o błędach w procesie two- Autowiązanie zależności
menty, możemy przystąpić do spięcia wszystkie- rzenia obiektów. Czasem jednak obiekty są W tej sekcji zajmiemy się bardzo interesującą
go w całość za pomocą Springa – Listing 26. wykorzystywane bardzo rzadko i nie ma po- funkcjonalnością dostarczaną przez Springa,
W powyższym listingu zdefiniowaliśmy trzeby tworzenia ich podczas startu aplikacji. jaką jest możliwość automatycznego wstrzyk-
obiekt klasy Processor, który następnie zo- Można zatem nakazać fabryce ich inicjaliza- nięcia zależności do obiektów poprzez anali-
staje przekazany jako źródło zdarzeń do me- cję dopiero w momencie ich pierwszego uży- zę struktury zdefiniowanego kontenera. Au-
tod obsługujących zdarzenia. Jak widać w przy- cia. Służy do tego atrybut lazy-init umiesz- towiązanie jest definiowane na poziomie de-
kładzie, zadeklarowany został obiekt klasy czany w elemencie object. Jeśli zostanie on finicji obiektu za pomocą atrybutu autowire.
ProcessorListener, którego dwie metody zo- ustawiony na true, instancja obiektu nie zo- Jest zatem możliwe, aby dla pewnych obiek-
stały podpięte do zdarzeń zgłaszanych przez nasz stanie utworzona w momencie inicjalizacji tów tę funkcjonalność włączyć, podczas gdy
procesor. Teraz wystarczy już jedynie pobrać tak kontenera Springa, ale dopiero w momencie, dla innych dowiązywać zależności ręcznie.
skonfigurowany obiekt procesora z fabryki i wy-
wołać jego metodę ProcessData, by zobaczyć, Listing 27. Przykład klasy implementującej interfejs IObjectFactoryAware
jak nasza konfiguracja sprawuje się w praktyce.
Deklaratywne podpinanie funkcji obsługi public class FactoryAwareContainer<T> : IObjectFactoryAware where T : class
zdarzeń dostarczane przez Springa umożliwia {
także wykorzystywanie wyrażeń regularnych private IObjectFactory factory;
do automatycznego podłączenia większej ilości
funkcji do danego zdarzenia lub kilku naraz. public T Content
Dość częstą praktyką jest nazywanie funk- {
cji obsługi zdarzeń w taki sposób, aby się get
z nim kojarzyła. Można zatem wykorzystać {
wyrażenia regularne, aby łatwo podpiąć funk- return this.factory["Content"] as T;//zależność od API Springa
cje za pomocą jednej deklaracji. Dla naszego }
przykładu będzie to: }
www.sdjournal.org 53
Warsztaty
Autowiązanie umożliwia zredukowanie lub • Autowiązanie wybierane automatycznie W związku z tym, klasa może w swoim ko-
zupełne wyeliminowanie potrzeby definio- (autodetect) – Spring samodzielnie wy- dzie zażądać określonego obiektu bezpośred-
wania argumentów konstruktora lub właści- biera autowiązanie po typie lub do kon- nio z fabryki za każdym razem, gdy będzie te-
wości, prowadząc w konsekwencji do zmniej- struktora w zależności od definicji klasy. go potrzebowała. Implementowanie interfejsu
szenia ilości pisanego kodu. Jeśli klasa posiada konstruktor domyśl- IObjectFactoryAware ma jednak jedną bardzo
Autowiązanie ma pięć trybów, które cha- ny, wówczas zostanie wykorzystane wią- niepożądaną konsekwencję. Uzależnia się nasz
rakteryzują się różnymi sposobami dopaso- zanie po typie. kod aplikacji od API Springa oraz wymusza się
wywania wstrzykiwanych zależności. Są to: konkretną nazwę dla definiowanego w fabryce
Warto podkreślić, że jakiekolwiek ręczne obiektu (w tym wypadku „Content”).
• Autowiązanie wyłączone (no lub default) zdefiniowanie właściwości lub argumentów Drugie rozwiązanie jest zdecydowanie bar-
– jest to tryb domyślny. Konfiguracja za- konstruktora nadpisuje działanie autowią- dziej eleganckie i polega na tytułowym dla tej
leżności musi być wykonywana ręcznie, zania, czyli innymi słowy ustawienia auto- sekcji wstrzykiwaniu metod wyszukujących.
co ma tę zaletę, że wszystkie zależności są wiązania zostają wówczas przez Springa zi- Nasza klasa zależna od kłopotliwej właści-
dobrze udokumentowane. Ten tryb jest gnorowane. wości musi zadeklarować metodę mającą na-
zalecany przy dużych projektach, ponie- stępującą sygnaturę:
waż zbyt duże skomplikowanie zależno- Wstrzykiwanie
ści w przypadku wiązania automatyczne- metod wyszukujących <public|protected> <abstract|virtual>
go może doprowadzić do bardzo nieczy- Jeśli obiekt korzysta z innych obiektów i ich cy- <return-type>
telnej, trudnej w analizie i utrzymaniu kle życiowe są zgodne (na przykład obiekt typu MethodName(no-
konfiguracji. singleton korzysta również z obiektów single- arguments);
• Autowiązanie po nazwie (byName) – tonowych), wówczas wszystkie zależności mo-
Spring analizuje strukturę kontenera ,wy- gą być wstrzyknięte w chwili tworzenia obiek- Na przykład tak jak w przykładziew listin-
szukując obiekty nazwane dokładnie tak, tu nadrzędnego. Problem zaczyna się w mo- gu 28.
jak właściwość obiektu (za pomocą atry- mencie, gdy potrzebujemy wymieszać cykle ży- Naturalnie klasa sama w sobie musi być za-
butu id lub name), który ma włączony ten ciowe obiektów. Jeśli obiekt typu singleton ko- deklarowana jako abstrakcyjna w momencie,
tryb automatycznego wiązania. Jeśli ta- rzysta z obiektu prototypowego, wówczas za- gdy chcemy zadeklarować metodę jako abs-
ki znajdzie, wówczas zostanie on wstrzyk- leżność zostanie wstrzyknięta tylko raz pod- trakcyjną. Natomiast jeśli nie chcemy, aby na-
nięty jako zależność. Ten tryb jest rzadko czas inicjowania kontenera. Może to prowadzić sza klasa była abstrakcyjna, musimy zadekla-
wykorzystywany, ponieważ wymusza do- do nieprzewidzianych konsekwencji (o cyklach rować metodę jako wirtualną.
pasowywanie nazw deklarowanych obiek- życiowych obiektów będziemy jeszcze pisać). Teraz wystarczy powiedzieć Springowi, co
tów do nazw właściwości, co może powo- Bez specjalnej konfiguracji nie ma możliwości, ma robić – Listing 29.
dować niejasności i konflikty, ponieważ aby obiekt singletonowy uzyskał nową instancję W powyższej konfiguracji powiedzieliśmy
różne klasy mogą mieć właściwości o tych obiektu za każdym razem, gdy chce go użyć. Springowi, aby zastąpił zdefiniowaną przez
samych nazwach. Dość częstą sytuacją jest również potrze- nas metodę GetContent swoją implementa-
• Autowiązanie po typie (byType) – Spring ba zdefiniowania w singletonowym obiekcie cją, która jako rezultat zwracać będzie kon-
analizuje strukturę kontenera i wyszuku- serializowanym zależności od obiektu niese- kretny obiekt (tutaj „MyClass”) za każdym
je obiekty o takim samym typie co dowią- rializowanego. W takiej sytuacji niezbędne razem, gdy zostanie wywołana. Nasz będący
zywana właściwość. Jeśli znajdzie zero lub jest ustawienie pola nieserializowanego jako singletonem kontener będzie zatem otrzymy-
więcej niż jeden obiekt danego typu, wów- [NonSerialized], ale wówczas po deserializa- wał nową instancję niesingletonowego obiek-
czas zostanie zgłoszony wyjątek. cji obiektu referencja ta będzie pusta. Pisanie tu „MyClass” za każdym razem, gdy zostanie
• Autowiązanie do konstruktora (construc- zaś własnego mechanizmu serializacji wydaje odczytana jego właściwość Content.
tor) – podobne w działaniu do wiązania się być zadaniem karkołomnym. Spring umożliwia jeszcze zastępowanie
po typie, z tą różnicą, że wstrzyknięcie za- Spring umożliwia zatem rozwiązanie takie- konkretnych istniejących implementacji me-
leżności nie ępuje poprzez właściwość, ale go problemu na przynajmniej dwa sposoby. tod innymi implementacjami napisanymi
poprzez konstruktor. Podobnie jak w przy- Jeden z nich polega na tym, że obiekt imple- przez użytkownika. Jest to jednak funkcjo-
padku wiązania po typie, jeśli w kontene- mentuje interfejs IObjectFactoryAware. Im- nalność rzadko wykorzystywana i nie będę jej
rze nie jest zadeklarowany dokładnie jeden plementacja tego interfejsu wymusza doda- tutaj opisywał. Zainteresowanych odsyłam do
obiekt pasujący do typu argumentu defi- nie do klasy właściwości ObjectFactory, która dokumentacji Springa.
niowanego przez konstruktor, wówczas zo- jest wykorzystywana przez Springa do wstrzyk-
stanie zgłoszony wyjątek. nięcia zależności, jaką jest fabryka obiektów. Zasięg widoczności obiektów
Każda definicja obiektu pojawiająca się w pli-
Listing 30. Dziedziczenie de�nicji obiektów ku konfiguracyjnym Springa jest wzorcem
dla konkretnych obiektów, które zostaną
<object id="parent" type="SpringExample1.MyClass" abstract="true"> utworzone przez fabrykę. Instancji danego
<property name="value" value="5"/> wzorca może być wiele lub może być tylko
<property name="description" value="Opis"/> jedna. Spring umożliwia definiowanie zasię-
</object> gu widoczności obiektów spośród pięciu do-
starczanych przez sam kontener.
<object id="child" type="SpringExample1.YourClass" parent="parent">
<property name="value" value="10"/><!-- Nadpisanie wartości z definicji • Singleton – tylko jedna instancja da-
rodzicielskiej --> nej definicji obiektu będzie istniała w in-
</object> stancji fabryki. Każde odwołanie się do
id takiej definicji zwróci zawsze dokład-
54 03/2010
Wprowadzenie do Spring.NET
nie tę samą instancję obiektu. Typ single- chanizmy, dzięki którym obiekty mogą zostać lass musi deklarować właściwości Value oraz
ton jest domyślnym zakresem widocz- poinformowane przez kontener o zaistnieniu Description, podobnie jak klasa MyClass.
ności obiektów, można go jednak jaw- wspomnianych sytuacji. Mechanizmy te wystę- Dziecko dziedziczy wszystkie elementy od ro-
nie zadeklarować, używając atrybutu pują również w dwóch formach – implementa- dzica, takie jak argumenty konstruktora, wła-
singleton="true" na elemencie object. cji odpowiednich interfejsów lub deklaratywne ściwości, metody inicjujące i inne, oraz mo-
• Prototyp – dokładne przeciwieństwo zdefiniowanie, która metoda powinna zostać że definiować swoje własne. Każda ponowna
singletonu. Każde odwołanie się do id wywołana w momencie zaistnienia opisanych deklaracja tego samego elementu definiujące-
definicji obiektu spowoduje utworzenie wcześniej zdarzeń. go nadpisuje ustawienia rodzicielskie, tak jak
nowej instancji obiektu. Deklaruje się go Wspomniane interfejsy to: w przykładzie. Atrybut abstract znajdują-
za pomocą atrybutu singleton="false" cy się na definicji obiektu parent jest wskaza-
na elemencie object. • IInitializingObject – dostarcza on niem dla fabryki obiektów, że definicja ta jest
• Request – dana instancja obiektu jest wi- metodę AfterPropertiesSet, która zo- jedynie szablonem dla innych i nie powinna
doczna w zakresie HTTP Request. Każdy staje wywołana zaraz po zainicjowaniu zostać zainicjalizowana instancja obiektu na jej
request ma swoją własną instancję obiektu, instancji obiektu. podstawie. Każda próba użycia definicji rodzi-
która jest singletonem podczas jego trwa- • IDisposable – dostarcza on metodę cielskiej jako wartości elementu ref lub próba
nia. Zakończenie danego żądania HTTP Dispose, która zostaje wywołana w momen- wyłuskania definicji z fabryki spowoduje zgło-
kończy również cykl życiowy obiektu cie, gdy cykl życiowy obiektu się skończy. szenie wyjątku. Ma to dość duże znaczenia,
o zasięgu widoczności typu request. Mo- ponieważ szablon rodzicielski nie musi dekla-
że być używany tylko w kontenerze webo- Nie zaleca się jednak stosowania powyższego rować wszystkich elementów, które mogą być
wym. Deklaruje się go za pomocą atrybutu podejścia ze względu na to, że niepotrzebnie niezbędne do prawidłowego funkcjonowania
scope="request" na elemencie object. wiąże to kod klasy z API Springa (w przypad- obiektu, na przykład typu (wówczas atrybut
• Session – działa identycznie jak zakres ku użycia interfejsu IInitializingObject). abstract jest wymagany). Możliwa jest rów-
request, z tą różnicą, że obiekty są wi- Dlatego też istnieje drugie podejście – dekla- nież sytuacja odwrotna, czyli brak deklaracji
doczne w zakresie danej sesji HTTP. ratywne. Można na elemencie definiującym typu obiektu dziedziczącego, w takiej sytuacji
Podobnie jak request może być uży- obiekt umieścić atrybut wskazujący, któ- będzie on tego samego typu, co rodzic, o ile typ
wany tylko w kontenerze webowym. ra metoda z danej klasy zostanie wywołana. został zdefiniowany dla rodzica.
Deklaruje się go za pomocą atrybutu Atrybuty owe to:
scope="session" na elemencie object. Zakończenie
• Application – analogiczny jak dwa po- • init-method="<method-name>" – wska- W ten sposób dotarliśmy do końca tego artyku-
wyższe, z tą różnicą, że widoczność obej- zuje, która metoda zostanie wywołana łu. Zawarte w nim zostały wszystkie najważniej-
muje cykl życiowy aplikacji webowej. zaraz po zainicjowaniu obiektu. Meto- sze i najczęściej używane funkcjonalności defi-
Jest to zatem w zasadzie singleton, jeśli da ta nie może przyjmować żadnego ar- niowania obiektów i zależności oferowanych
nasza konfiguracja nie jest współdzielo- gumentu ani zwracać żadnej wartości. przez Springowy kontener IoC. Nie są to jednak
na przez kilka instancji aplikacji webo- • destroy-method="<method-name>" – wszystkie możliwości przez kontener udostęp-
wej. Deklaruje się go za pomocą atrybu- wskazuje, która metoda zostanie wywo- niane, te jednak, które zostały pominięte, są rza-
tu scope="application" na elemencie łana w momencie niszczenia obiektu. dziej używane lub są zbyt zaawansowane dla po-
object. Podobnie jak w przypadku metody post- czątkującego użytkownika. Informacje zawarte
inicjalizacyjnej także i ta nie może przyj- w niniejszym artykule są niemniej wystarcza-
Wymienione powyżej zakresy widoczności ty- mować żadnego argumentu ani zwracać jące, by stworzyć w pełni funkcjonalną aplika-
pu request, session oraz application mogą żadnych wartości. cję, jakkolwiek jedynie okienkową lub konso-
być używane jedynie w odpowiedniej imple- lową. W kolejnych artykułach przybliżę czy-
mentacji interfejsu IapplicationContext, ja- Dziedziczenie definicji obiektów telnikowi wsparcie Springa dla poszczególnych
ką jest WebApplicationContext, która jest spe- Już wcześniej w tym artykule zostało wspo- warstw aplikacji webowej, a wspiera on każdą
cyficzna dla kontenera webowego. Jeśli któ- mniane, przy okazji omawiania kwestii scala- z nich, od umożliwienia deklaratywnego defi-
ryś z tych zasięgów zostałby użyty w stoso- nia kolekcji, że definicje obiektów mogą być niowania połączenia do bazy danych i obsługi
wanej w naszych przykładach implementacji dziedziczone. Teraz bliżej przyjrzymy się te- transakcji oraz warstwy DAO, poprzez warstwę
XmlApplicationContext, wówczas podczas mu zagadnieniu. logiki biznesowej, której funkcjonalności są wy-
inicjalizacji kontekstu zgłoszony zostałby wy- Definicja obiektu, jak to zostało przedsta- stawiane poprzez usługi sieciowe, a na wsparciu
jątek mówiący, że został użyty nieznany zakres wione wcześniej, może obejmować wiele ele- warstwy prezentacji kończąc. Mam nadzieję, że
widoczności. mentów deklaratywnie formułujących postać ten artykuł zainteresował czytelnika możliwo-
obiektu, który później zostanie zainicjalizo- ściami udostępnianymi przez Springa oraz dał
Informowanie obiektu wany. Definicje dziedziczące, podobnie jak choć lekki wgląd w to, jak potężnym i niezwy-
o jego cyklu życiowym w każdym języku obiektowym, mogą przej- kle pomocnym jest narzędziem. Zapraszam do
W poprzednich sekcjach opisane zostały dość mować deklaracje rodzicielskie, jak również przeczytania kolejnych artykułów, bo prawdzi-
szczegółowo metody konfiguracji obiektów nadpisywać je swoimi (Listing 30). wa zabawa dopiero się zacznie.
oraz ich zależności. Czasem zachodzi dodat- W powyższym przykładzie widzimy defi-
kowo potrzeba przeprowadzenia dodatkowych nicję obiektu rodzicielskiego typu MyClass
operacji po zainicjowaniu obiektu (na przykład oraz dziedziczącego po nim obiektu typu PIOTR WYCZÓŁKOWSKI
sprawdzenia, czy wszystkie zależności zosta- YourClass. Klasy obiektów mogą być iden- Programista zajmujący się na co dzień systemami
ły poprawnie ustawione) lub na chwilę przed tyczne lub zupełnie różne, niezwiązane ze so- typu enterprise opartymi na szkielecie Springa.
zniszczeniem kontenera (na przykład zamknię- bą nawet dziedziczeniem . Jedyne, co musi je Zawodowo związany z Javą, zafascynowany jed-
cie uchwytów do zasobów plikowych lub połą- łączyć, to kompatybilność definicji właściwo- nak możliwościami języka C# 3.0 i technologii LI-
czenia do bazy danych). Spring udostępnia me- ści lub konstruktorów. Dlatego też a YourC- NQ, zajmuje się hobbystycznie platformą .NET.
www.sdjournal.org 55
Aplikacje biznesowe
SOA
Tworzenie serwisów wspomagających proces integracji
S
OA (ang. Service Oriented Architectu- sób właściwy zostaną przetworzone, dając ne kryteria. Pierwsze to fakt, iż część zwią-
re) to pewna koncepcja, rodzaj podej- oczekiwany rezultat (Rysunek 1). zana z przetwarzaniem komunikatów po
ścia w tworzeniu oprogramowania, Nasz proces będzie podzielony na dwie stronie MQ powinna być odseparowana
w której staramy się tworzyć niezależne usłu- części (komponenty), które mogą być do- i niedostępna na zewnątrz , czego konse-
gi, które następnie są udostępniane w celu starczone przez niezależnych dostawców. kwencją było drugie kryterium związane
wykonania określonego zadania lub łączone Pierwsza część procesu związana jest z na- ze stworzeniem niezależnej warstwy po-
w łańcuchy kolejnych wywołań, tworząc tzw. pisaniem aplikacji JEE, a dokładnie serwi- średniej, dostępnej dla zewnętrznych apli-
łańcuchy procesów biznesowych. su odpowiedzialnego za przekazanie odpo- kacji klienckich. Warstwa pośrednia po-
Tak naprawdę trudno w kilku zdaniach wiednio sparsowanej wiadomości do kolej- winna być uniwersalnym pośrednikiem od-
powiedzieć, czym jest SOA. W tym artykule ki MQ (ang. Message Queue) ,wykorzystu- powiadającym za wywołanie pewnego zde-
skupimy się na tworzeniu usług sieciowych, jąc JMS (ang. Java Message Service). Druga finiowanego procesu biznesowego. Opiera-
wykorzystując JAX-WS, które wykorzystamy
jako wygodne narzędzie wspomagające pro-
ces integracji wielu systemów.
Definicja procesu,
analiza problemu
Pracę zaczniemy od zdefiniowania procesu,
na podstawie którego przeprowadzimy ana-
lizę architektoniczną. Naszym celem jest
przygotowanie pewnego procesu bizneso-
wego który udostępnimy zewnętrznym od-
biorcom. Zgodnie z modelem SOA chce-
my oprogramować pewien proces, dla które-
go udostępnimy interfejs dla zewnętrznych
odbiorców. Proces ma być hermetyczny, na-
si klienci nie potrzebują mieć wiedzy na te- Rysunek 1. Schemat procesu biznesowego
56 03/2010
SOA
www.sdjournal.org 57
Aplikacje biznesowe
instalowany na lokalnej maszynie z ustawio- go za odebranie danych od klienta i prze- części procesu biznesowego pozwala dość
nym kontekstem sdjservice. kazanie ich do kolejki. Dzięki podzieleniu łatwo zdywersyfikować dostawców kom-
Na tym etapie dysponujemy poprawnie za- naszego procesu biznesowego na dwa nie- ponentów do naszego systemu, a co za tym
instalowanym serwisem, który wykorzystu- zależne komponenty możemy przeprowa- idzie zmniejszyć ryzyko związane z uzależ-
jąc odpowiednio zdefiniowane obiekty JMS dzić test i ostatecznie dostarczyć w peł- nieniem projektu od jednego konkretnego
prześle komunikat do kolejki zdefiniowanej ni funkcjonalny komponent niezależnie dostawcy.
po stronie MQ. od tego, czy dostawca odpowiedzialny za W celu przeprowadzenia testu nasze-
utworzenie części związanej z przetwa- go komponentu wykorzystamy komunikat
Test usługi sieciowej rzaniem komunikatu po stronie MQ do- SOAP, którym wywołamy nasz serwis (Li-
W tej chwili możemy przeprowadzić pełny starczył już swój komponent, czy nie. Ta- sting 4).
test naszego komponentu odpowiedzialne- kie podejście wyodrębniania niezależnych Po wywołaniu naszego serwisu do MQ zo-
stał przekazany komunikat, który możemy
podejrzeć za pomocą narzędzia MQ Explo-
ler (Rysunek 6) oraz zwrócony komunikat
SOAP (Listing 5).
Tworzenie
i konfiguracja aplikacji
– konsumenta komunikatów MQ
Druga faza naszego procesu jest związana
z przetwarzaniem komunikatu umieszczo-
nego w MQ. Nasz proces biznesowy z zało-
Rysunek 4. Kon�guracja dostawcy zarządzania komunikatami żenia ma być częścią większego systemu,
który w oparciu o pewne kryteria wywoła
nasz proces lub nie. Załóżmy więc, że mo-
że istnieć sytuacja, w której nie będzie co
przetwarzać przez kilka lub kilkanaście go-
dzin. Jak w takiej sytuacji zapewnić wydaj-
ne oraz optymalne przetwarzanie komuni-
katów? Zastosowanie klasycznej aplikacji
wielowątkowej na pewno spełni nasze ocze-
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(namespace=
"http://model.sdj",name="InputData")
@Override
public String toString() {
StringBuilder sb =
new StringBuilder();
sb.append("InputData \n");
sb.append("code="+code + ";");
sb.append("num="+num + ";");
return sb.toString();
}
58 03/2010
SOA
www.sdjournal.org 59
Aplikacje biznesowe
<soapenv:Envelope xmlns:soapenv=
"http://schemas.xmlsoap.org/soap/
envelope/" xmlns:ser="http:/
/service.sdj/">
<soapenv:Header/>
<soapenv:Body>
<ser:sendData>
<arg0>
<code>A1B2C3</code>
Rysunek 7. Kon�guracja QUEUE_SDJ <num>875</num>
</arg0>
</ser:sendData>
</soapenv:Body>
</soapenv:Envelope>
60 03/2010
SOA
Manifest-Version: 1.0
Package: sdj.client
Main-Class: sdj.client.MQClient
Class-Path: com.ibm.mq.jar
com.ibm.mq.headers.jar
com.ibm.mq.pcf.jar
com.ibm.mq.jmqi.jar jta.jar
connector.jar
com.ibm.mq.com
monservices.jar
Rysunek 9. Monitor wyzwalacza
www.sdjournal.org 61
Felieton
Certyfikacja i co dalej?
Obecna sytuacja na rynku pracy oraz otwarcie rynków europejskich
dla polskich pracowników powoduje, że coraz częściej zastanawiamy
się nad sposobem poniesienia własnych kwalifikacji. Szukamy metod,
które są postrzegane jako wartościowe i uznawane nie tylko przez
polskich pracodawców i managerów. Rozwiązaniem coraz częściej
wybieranym przez Programistów zajmujących się Java są certyfikacje
SUNa ze względu na ich uniwersalność.
(SCEA), do której podchodzi każdego roku je-
Dowiesz się: Powinieneś wiedzieć: dynie kilkanaście osób w Polsce i pokrywa on ca-
• Jakie znaczenie na rynku pracy maja certy�katy • Znajomość podstawowych pojęć związa- łe spektrum Java Enterprise Edition.
SUNa nych z programowaniem w Java’ie Faktem jest, że zainteresowanie ścieżkami cer-
• Czy warto inwestować w egzaminy certy�kacyjne • Czym są egzaminy certy�kacyjne SUNa tyfikacyjnymi rośnie z roku na rok w bardzo zna-
• Jak certy�kacja SUNa postrzegana jest przez ludzi, czącym tempie. Polska jest jednym z tych kra-
którzy już certy�katy posiadają jów europejskich, w których certyfikacja sta-
ła się podstawowym elementem oferty Działu
Szkoleń, a tym samym jednym z ważniejszych.
nadzieję, że poniższy artykuł i przedstawione Na tym etapie byłoby ciężko odpowiedzieć na
w nim wyniki badań przeprowadzone w jed- pytanie dlaczego tak się dzieje, co spowodowało
Poziom nym z europejskich krajów pomogą odpowie- w ostatnich latach takie zainteresowanie egzami-
trudności dzieć na zadane pytania. nami. To, co bez wątpienia narzuca się, to fakt, że
Program certyfikacyjny Suna składa się profesjonaliści są bardziej świadomi swoich moż-
z ośmiu egzaminów dotyczących trzech plat- liwości i wartości na dzisiejszym rynku IT nie tyl-
form Javy. Ich tematyka ściśle wiąże się z wyko- ko w obrębie Polski, ale i na rynku europejskim.
O
d samego początku pojawienia się nywanymi przez działy IT zadaniami, ich rolami Aktualnie certyfikacja stała się twardym dowo-
technologii Java zyskuje ona co- i koncentruje się na trzech grupach: Programi- dem kompetencji, ambicji pracownika oraz mo-
raz więcej zwolenników, głównie ze stach, Deweloperach i Architektach. tywacją do dalszego rozwoju. Jest niewątpliwie
względu na możliwości, jakie daje użytkowni- wartością dodaną profesjonalisty dla jego obec-
kom. Certyfikacje Sun Microsystems z zakre- Ścieżka certyfikacyjna Java nego lub przyszłego pracodawcy. Dla kadry za-
su Javy stały się jednymi z najpopularniejszych Najczęściej podejmowanym certyfikatem jest rządzającej certyfikacje Sun są postrzegane jako
na rynku programistów. Statystyki pokazują, że Sun Certified Java Programmer (SCJP) jako zbiór kompetencji, zdobytych umiejętnościach
certyfikację Suna zrealizowało ponad 600 tyś. podstawa do dalszego rozwoju. Zdecydowanie i rozwijania wiedzy technicznej. W swojej wie-
osób na całym świecie. Niewątpliwa większość mniej osób decyduje się na ścieżkę Dewelopera loletniej pracy nie raz spotkałam się z opinią, że
to oczywiście egzaminy z zakresu technologii Ja- wymagającą większego doświadczenia. Obser- każdy zdobyty przez pracowników certyfikat
va, a Europa jest liderem w tej tematyce. wując rynek IT, stosunek procentowy jest w cią- jest poświadczeniem jego wiedzy i praktycznych
Dlaczego tak się dzieje? Co jest powodem za- gu ostatnich trzech lat bardzo elastyczny i zmie- umiejętności. Wzrost zainteresowania egzami-
interesowania programami certyfikacyjnymi nia się na korzyść zaawansowanych certyfikacji. nami jest na tę opinię jedynie żywym dowodem.
w tak dużym stopniu? W jaki sposób certyfika- Najbardziej jednak „ekskluzywną” ścieżką wy- Świadomość tego, że członkowie zespołu mogą
cja może wpłynąć na karierę zawodową? Mam daje się być Sun Certified Enterprise Architect wykazać się wiedzą praktyczną potwierdzoną
dodatkowo certyfikatem, jest zdecy-
dowanie atutem w środowisku infor-
����������������������������������������� matycznym.
�������������� �������������� ��������������� ��������������
Jednocześnie z rozwojem popu-
��������������
������ ��������������� �������������� ������������������� ������������������� ������������������� larności Javy coraz więcej firm za-
������ ��������� ���������� ������������ ��������� częło się na niej koncentrować, co
������� ������� �������� �������
spowodowało duże zapotrzebowa-
nie na specjalistów w tej dziedzinie.
������������ ������������������������������������
Ten moment rozwoju samej techno-
��������� ����������������������������������� logii stał się kluczem do sukcesu cer-
tyfikacji, a jednocześnie zmotywował
��������� ��������� ���������
pracodawców do inwestycji w swo-
Rysunek 1. Ścieżka certy�kacyjna Java ich pracowników. Taka tendencja by-
62 03/2010
63
Felieton
ła widoczna przez kilka lat, jednak ostatnie czte- od lat wspomaga ścieżki certyfikacyjne pakietami dym rokiem popularność bardziej zaawansowa-
ry lata pokazują, że pracownicy coraz częściej sa- ePractice, które są zbiorem próbnych pytań egza- nych certyfikacji wzrasta, jednak wciąż najbar-
mi inwestują w swój rozwój i podejmują się cer- minacyjnych i elementem wspomagającym zdo- dziej wymagającym jest Sun Certified Java Ar-
tyfikacji na własny rachunek. Spowodowane jest bytą wiedzę. Pozwalają na zapoznanie się z samą chitect i to potwierdzają również badania prze-
to niewątpliwie ciągłą fluktuacją pracowników formą egzaminu czy stopniem trudności pytań. prowadzone na rynku belgijskim.
na rynku informatycznym i chęcią podnoszenia Dodatkowo od kilku lat na terenie Euro- W większości ankietowani przyznają, że war-
własnych kwalifikacji. py, w tym również w Polsce, prowadzimy Bo- to było podejść do egzaminu nie tylko dla same-
otcampy z technologii Java. Mają one na celu go „papierka”. Z drugiej jednak strony jednym
Faktyczna wartość przygotować uczestników do zaawansowanych z wniosków narzucających się po analizie an-
Obecnie certyfikacja z technologii Java jest wy- certyfikacji, tj. Sun Certified Java Architect. Se- kiety jest fakt, że w opinii uczestników Java Pro-
soko ceniona nie tylko przez programistów, de- sja taka trwa sześć dni i prowadzona jest przez grammer to zupełna podstawa Javy - sama Javy
weloperów czy architektów, ale również przez najlepszych w tej dziedzinie, sprawdzonych in- Standard Edition i nie wymaga specjalistycznej
pracodawców oraz samego Suna – twórcy tech- struktorów Suna. Uczestnicy takich warszta- wiedzy podpartej praktyką. Czy tak faktycznie
nologii. Dla Suna ważne jest, żeby technologia tów upewniają nas tylko, że zajęcia są potrzebne jest? SCJP to w ścieżce certyfikacyjnej pierwszy
rozwijała się, ważne jest promowanie jakości ko- i przede wszystkim wychodzą z nich z faktycz- krok do kolejnych zaawansowanych egzaminów
dowania w Javie. Z drugiej strony pracodawcom ną wiedzą, a nie tylko książkowym zarysem. wymagających dużo doświadczenia i znajomo-
zależy na zatrudnianiu certyfikowanych specja- Studenci dzielą się posiadaną wiedzą, dyskutu- ści tematu ponad samą Javę SE, w tym Mobile
listów choćby z czysto ekonomicznego punktu jąc o różnych przypadkach zaczerpniętych z ich oraz Enterprise Edition. Podejście do tego egza-
widzenia, co jednocześnie wpływa na wzrost praktyki zawodowej. minu nie wymaga wieloletniej praktyki w tema-
wartości profesjonalistów na rynku IT. W roku 2009 przeprowadziliśmy sesję certy- cie technologii Java, ale niewątpliwie posiadanie
Programowanie w języku Java jest bardzo fikacyjną z zakresu SCJP, która cieszyła się spo- tej certyfikacji jest atutem na rynku pracy.
powszechne na uczelniach wyższych, co czy- rym zainteresowaniem, a jej założeniem było Certyfikat często przybliża tematy, które są
ni technologię bardziej pożądaną i rozwojową. przybliżyć uczestników do samego egzaminu. nam znane, a jednak w codziennej pracy o nich
Nie zawsze jednak wiedza akademicka jest wy- Zajęcia prowadzone w formie dyskusji i oma- zapominamy czy zwyczajnie je pomijamy.
starczająca do podjęcia się certyfikacji szczegól- wiania problematycznych kwestii, jednocze-
nie tych bardziej zaawansowanych, chociażby śnie kontakt z wieloletnim instruktorem Sun Wartość certyfikacji na rynku pracy
tych wymagających znajomości architektury Ja- – a efekt – kilku kolejnych certyfikowanych Tak naprawdę odpowiedzią na powyższe stwier-
vy EE. Zdawanie egzaminów z Javy z zadowala- programistów! Pomysł na warsztat wypłynął dzenie jest przedstawiony wykres – a wyniki
jącym wynikiem wymaga wiedzy praktyczniej, z inicjatyw naszych klientów, ich potrzeb i zain- są bardzo zbliżone do tego, co obserwujemy na
a taką mogą się pochwalić osoby pracujące na ży- teresowania technologią. Okazuje się, że coraz rynku polskim. Około 87% ankietowanych po-
wym organizmie, jakim jest Java. Szkolenia, któ- chętniej specjaliści sięgają po takie formy nauki i twierdza wartość certyfikatów na rynku pracy.
re Sun przygotował również pod kątem ścieżek nie chodzi tu wyłącznie o szkolenia, ale bardziej Tylko 10% nie zgadza się z tym stwierdzeniem.
certyfikacyjnych, są często dla uczestników uzu- o krótkie, jednodniowe sesje. Na tym etapie pojawia się pytanie, na ile certy-
pełnieniem wiedzy nabytej na studiach czy rów- fikaty odzwierciedlają rzeczywistą wiedzę, a na
nież w pracy zawodowej. Jak postrzegają certyfikację sami ile są jedynie zbiorem teoretycznych zagadnień.
W ciągu ostatnich kilku lat cyklicznie wpro- użytkownicy? Okazuje się jednak, że takie wątpliwości doty-
wadzamy program darmowych powtórek egza- W roku 2009 Java Magazine i Sun Microsys- czą jedynie nielicznych uczestników, a znaczą-
minów (tzw. Second Shot) i bez wahania mogę tems w Belgii opublikowały wyniki ankiety ca większość mówi, że certyfikaty są potwier-
potwierdzić, że cieszy się on ogromnym zainte- przeprowadzonej wśród specjalistów z zakresu dzeniem wiedzy i umiejętności. Faktem jest, że
resowaniem na całym świecie. Po pierwszej edy- Javy. Grupą docelową byli deweloperzy z prak- posiadanie certyfikatu z Javy nie czyni dobrym
cji byliśmy zaskoczeni, jak marginalny procent tyką zawodową oraz zdaną certyfikacją. Ce- programistą, jednak jest wartością dodaną dla
uczestników musiał skorzystać z egzaminu po- lem przeprowadzonego badania było uzyska- każdego, kto podejdzie do egzaminu przygoto-
prawkowego w stosunku do liczby uczestni- nie informacji ,jak programy certyfikacyjne Su- wany i zda go z dobrym wynikiem.
ków, i narzuca się jeden wniosek, że osoby pod- na wpływają na rozwój osób podejmujących się Z szeregu ankiet przeprowadzonych na po-
chodzące do certyfikacji są świetnie przygotowa- tego wyzwania i czy faktycznie mają one wpływ trzeby Suna oraz z bezpośrednich opinii spe-
ne. Dzieje się tak dlatego, że w dzisiejszych cza- na karierę zawodową. W ankiecie wzięło udział cjalistów i ich managerów wynika jednoznacz-
sach nie mamy czasu na poprawki i dodatkowe około 300 osób, a najciekawsze fragmenty zosta- nie, że certyfikacje są na rynku bardzo warto-
przygotowywanie się do egzaminów. Ten przy- ły przedstawione poniżej. ściowym elementem. Są uzupełnieniem wiedzy
kład w dużej mierze świadczy również o warto- i umiejętności oraz wartością dodaną dla każde-
ści certyfikacji – są cenione i traktowane profe- Każdy może zdać egzamin go, kto ma choćby jeden z certyfikatów.
sjonalnie na ryku użytkowników Javy. Z opinii ankietowanych wynika, że około 240 Aktualnie certyfikacja postrzegana jest jako
osób potwierdziło duże znaczenie certyfikacji duża szansa na rozwój i wyzwanie nie tylko dla
Jak się przygotować? w ich karierze zawodowej. Zdecydowanie więk- programistów, deweloperów czy architektów,
Sposobów na dobre przygotowanie się do certy- sza część uczestników (80%) przyznała, że ma ale również pracodawców, którzy na rynku po-
fikacji jest wiele i każdy bazuje w tej dziedzinie certyfikację lub planuje podejście do egzaminu szukują specjalistów najwyższej klasy. Ma to zna-
na własnym doświadczeniu, może nawet z cza- w najbliższej przyszłości. W tym przypadku zna- czenia dla firm, ponieważ świadczy o pewnym
sów szkoły? Najczęściej wybieranym sposobem czącą popularnością cieszy się Sun Certified Java usystematyzowaniu i ugruntowaniu wiedzy
nauki jest douczanie się we własnym zakresie na Programmer jako podstawowy egzamin w ścież- przez członków zespołów Javowych.
podstawie sieci czy książek dostępnych na rynku. ce Javy. Kolejnym krokiem podejmowanym Niezbędne informacje o certyfikacjach znaj-
Ale czy to wystarczy? W niektórych przypadkach przez specjalistów jest Web Component Develo- dują się na stronie www.sun.com.pl/training
pewnie tak, zwłaszcza jeżeli wiedza teoretycz- per – w przypadku rynku polskiego zdecydowa-
na podparta jest praktyką zawodową, ale dlacze- nie częściej podejmowanym jest Java Developer OLIWIA ŁĄCZYŃSKA
go nie spróbować sprawdzonych rozwiązań? Sun i to ten egzamin zajmuje drugie miejsce. Z każ- Business Development Manager Sun Learning Services
64 03/2010
65
Praca w zespole
Audyt techniczny
Czyli jak sprawdzić jakość prac dostawcy IT?
J
ak jednak klient może sprawdzić, czy pra- dzi w pracach projektowych; rzenia i zarządzania dokumentacją to
ce projektowe i ich poszczególne produkty • kod źródłowy zgodny ze standardami (np. te, które były deklarowane w umowie/
odpowiadają jego oczekiwaniom i wyma- zgodny z wytycznymi kodowania w Java). uzgodnieniach;
ganiom? Nierzadko instytucja zlecająca realiza- • czy format dokumentów jest zgodny z za-
cję usług IT nie posiada odpowiednich zasobów, W jakim celu wykonuje się audyt? Powody łożeniami;
by móc zweryfikować jakość np. procesu wy- mogą być następujące: • czy jakość rozumiana jako kompletność,
twórczego czy zgodności architektury z ustale- jednoznaczność, spójność, przejrzystość
niami kontraktowymi. Może nie mieć persone- • by upewnić się, że rzeczywiste prace re- jest zachowana;
lu o odpowiednich kompetencjach lub możli- alizowane w ramach projektu odpo- • czy obieg dokumentacji jest spójny z wy-
wości technicznych sprawdzenia pewnych kwe- wiadają zadeklarowanym w kontrakcie, maganiami etc.
stii – może też pragnąć (z różnych względów, a ich jakość spełnia wymagania klienta;
w tym tzw. politycznych), by kontrola taka wy- • by sprawdzić, czy jakość poszczególnych Pytania te muszą zostać zadane – niekoniecz-
konywana była przez zespół całkowicie nieza- produktów odpowiada zapewnieniom nie dosłownie: większość tzw. dowodów zbie-
leżny i obiektywny. Rozwiązaniem tego proble- dostawcy i oczekiwaniom klienta; ra się podczas wywiadów i obserwacji – a od-
mu jest audyt techniczny. Umożliwi on nieza- • by ujawnić problemy występujące w róż- powiedzi zanotowane celem dalszej analizy.
leżną ocenę procesów, produktów i innych ob- nych obszarach projektu i móc je wyeli- Nieraz obserwacja dostarcza więcej informa-
szarów projektu realizowanego przez dostaw- minować. cji, niż słowa – ponieważ umożliwia obserwa-
cę IT – weryfikację zgodności z wymagania-
mi, identyfikację błędów i usterek oraz dostar- Audyt
czy rekomendacji czy zaleceń, które – wdrożo- Audyt – ocena danej osoby, organizacji, systemu, procesu, projektu lub produktu. Audyt jest
ne przez dostawcę – ulepszą jakość prac. przeprowadzany w celu upewnienia się co do prawdziwości i rzetelności informacji, a także
oceny systemu kontroli wewnętrznej. Celem audytu jest wyrażenie opinii na temat osoby/
organizacji/systemu itd. w ramach oceny w oparciu o przeprowadzone testy.
Audyt – ale co to jest? Audyt polega na ocenie przez kompetentny i niezależny zespół audytujący, czy dany przedmiot
Zgodnie z definicją audyt jest oceną i weryfika- audytu spełnia wymagania. Zespół audytujący składa się z jednego lub więcej audytorów.
cją pewnych hipotez. W kontekście projektu IT Celem audytu może być wery�kacja, czy cel wyznaczony przez organizację audytowaną został
hipotezą taką może być: osiągnięty lub czy jej działania są zgodne z zaakceptowanymi standardami, statusem czy prak-
tykami. Audyt ocenia także procedury kontrolne celem stwierdzenia, czy przedmiot audytu tak-
• zarządzanie projektem zgodnie z określo- że w przyszłości będzie odpowiadał uzgodnionym do stosowania wymaganiom. Oprócz oceny
wskazuje także zalecenia zmian w procedurach, w tym sprawdzających oraz w politykach.
nym standardem;
66 03/2010
Audyt techniczny
cję rzeczywistych zachowań, wyników i prak- • Określenie celu i zakresu audytu. Zlecający audyt dokonuje wyboru jednostki au-
tyk, a nie teorii czy pobożnych życzeń. dytującej. Audytorzy powinni pochodzić z fir-
Postawione powyżej przykładowe pytania Czynność ta należy do organizacji zlecającej my specjalizującej się w danym typie audytu –
kontrolne nie wydają się szczególnie skompli- audyt i polega na określeniu, co ma być przed- lub posiadający odpowiednie kompetencje, by
kowane. Czy zatem rzeczywiście konieczne jest miotem oceny oraz na podstawie jakich kryte- taką ocenę wykonać. Zdarza się, że audyt nie jest
zlecanie audytu instytucji zewnętrznej? Czy or- riów będzie ona wykonywana. Wskazane jest realizowany przez firmę konsultingową, zajmu-
ganizacja klienta nie jest w stanie samodzielnie też sprecyzowanie produktów prac (np. ra- jącą się tylko i wyłącznie wykonywaniem audy-
wykonać oceny prac dostawcy? portów). tów. W przypadku np. opisywanego tu audytu
Odpowiedź brzmi – może i nie może. De- technicznego projektu IT, klient może zlecić au-
cyzja zależy w dużym stopniu od celu posta- • Wybór jednostki audytującej. dyt innemu dostawcy IT – przy założeniu, że:
wionego przed audytem, zależności pomię-
dzy klientem a dostawcą, zasad obowiązują-
cych w instytucji klienta. W przypadku gdy Audytów jest wiele...
klient ma uzasadnione wątpliwości co do ja- Oto wybrane rodzaje audytów związane z branżą IT.
kości prac dostawcy i przestrzegania przez
• Audyt bezpieczeństwa danych (Technicznej infrastruktury) – ma za zadanie zde�niowanie
niego ustaleń umowy, wskazane jest zlece- istniejących zagrożeń i słabych punktów systemu zarządzania bezpieczeństwem infor-
nie audytu zewnętrznego. Dlaczego? Ponie- macji �rmy oraz oszacowanie ryzyka operacyjnego, na jakie narażona jest organizacja
waż wyniki takiego audytu będą obiektyw- klienta. W wyniku audytu powinny zostać też przedstawione rekomendacje w zakresie
ne i klient uniknie posądzeń o próbę mani- bezpieczeństwa informacji oraz propozycje możliwych rozwiązań, które mogą się przy-
pulacji. czynić do podniesienia bezpieczeństwa informacji �rmy oraz do zagwarantowania płyn-
ności procesów biznesowych. Podstawą audytu jest zwykle norma PN-I-07799-2:2004.
Wspomnieliśmy o audycie zewnętrznym • Audyt informatyczny – proces zbierania i oceniania dowodów w celu określenia, czy sys-
– jest i wewnętrzny, czyli audyt przeprowa- tem informatyczny i związane z nim zasoby właściwie chronią majątek, utrzymują integral-
dzany przez ludzi z organizacji klienta. Au- ność danych i dostarczają odpowiednich i rzetelnych informacji, osiągają efektywnie cele or-
dyt taki ma sens, jeżeli zespół audytujący po- ganizacji, oszczędnie wykorzystują zasoby i stosują mechanizmy kontroli wewnętrznej, tak
siada kwalifikacje odpowiednie do postawio- aby dostarczyć rozsądnego zapewnienia, że osiągane są cele operacyjne i kontrolne, oraz że
chroni się przed niepożądanymi zdarzeniami lub są one na czas wykrywane, a ich skutki na
nego celu i jest w stanie rzetelnie ocenić dany
czas korygowane. Normami często stosowanymi w audytach informatycznych są:
przedmiot. Często audyt wewnętrzny jest je- • ISO 9001;
dynie pierwszą fazą całościowej procedury au- • ITIL;
dytu, mającą na celu zidentyfikowanie podsta- • COBIT.
wowych zagrożeń, braków i usterek występu- Normą wyspecjalizowaną w zakresie bezpieczeństwa informatycznego, według której czę-
jących w określonych procesach, infrastruk- sto prowadzi się audyty, jest ISO/IEC 27001. Towarzyszącą normą służącą do budowania sys-
temów zarządzania bezpieczeństwem informacji jest ISO/IEC 27002.
turze, produktach etc. Zazwyczaj zakończe-
nie procedury audytu wewnętrznego wiąże się • Audyt techniczny – wery�kacja realizacji projektu zgodnie z umową (warunkami wskaza-
z podjęciem decyzji o zamówieniu całościowe- nymi przez zlecających projekt lub innych udziałowców); może być wykonywany w każ-
go audytu informatycznego u zewnętrznej wy- dym czasie podczas trwania projektu.
specjalizowanej firmy. • Audyt technologiczny – ocena rzeczywistych możliwości wykorzystania technologii w �r-
mie. Audyt technologiczny to rodzaj kontroli planów wdrożeniowych, kontroli niezależ-
Audyt zewnętrzny przeprowadzany jest nej, udokumentowanej, opartej o określone kryteria. Audyt ten wiąże się z pytaniami:
znacznie sprawniej niż wewnętrzny, jako że or- • jakie są inne technologie w danej dziedzinie?;
ganizacje zajmujące się tym zawodowo mają • jaki jest poziom rozwoju ocenianych technologii?;
doświadczenie i metodologię pozwalającą na • jaki stopień innowacyjności posiada technologia?.
znaczne skrócenie procedury audytu. Bardzo Audyt technologiczny może być: opiniujący, oceniający lub kontrolny.
istotną cechą audytu zewnętrznego jest brak
• Audyt oprogramowania – polega na analizie stanu oprogramowania zainstalowanego
ryzyka stronniczości – gdyż dokonywany jest w �rmie, uporządkowaniu i uzupełnieniu brakujących licencji oraz wdrożeniu procedur
przez niezależną instytucję – dzięki czemu wy- usprawniających zarządzanie oprogramowaniem.
niki oceny lepiej i pełniej oddają stan rzeczywi-
sty. Rekomendacje audytorów zewnętrznych są
też z reguły trafniejsze (co wynika głównie z do-
świadczenia) i umożliwiają realne usprawnie- Na czym się opierać...
nie wadliwych obszarów. • COBIT (Control Objectives for Information and related Technology) – standard opracowa-
Rodzaje audytów to nie tylko wewnętrzny ny przez ISACA oraz IT Governance Institute, zbiór dobrych praktyk z zakresu IT Governan-
i zewnętrzny – audytów w IT jest wiele (ram- ce, które mogą być wykorzystywane w szczególności przez audytorów systemów infor-
ka), w zależności od postawionego celu i tego, matycznych. COBIT 4.1 opisuje 34 wysokopoziomowe procesy, które obejmują 210 celów
co zlecający ocenę chce osiągnąć. kontrolnych pogrupowanych w czterech domenach:
• planowanie i organizacja (Planning and Organization);
Wiemy już, czym jest audyt, przejdźmy teraz • nabywanie i wdrażanie (Acquisition and Implementation);
do tego, jak go przygotować i wykonać. • dostarczanie i wsparcie (Delivery and Support);
• monitorowanie i ocena (Monitoring and Evaluation).
Procedura audytu • ITIL (Information Technology Infrastructure Library) –- kodeks postępowania dla działów infor-
matyki. Zbiór zaleceń, jak efektywnie i skutecznie oferować usługi informatyczne. Podstawą
koncepcji ITIL jest zde�niowanie procesów, które powinny funkcjonować w ramach organi-
Przygotowanie i zakres audytu zacji świadczącej usługi IT. ITIL pozwala na modelowanie procesów zarówno w organizacjach
Audyt, podobnie jak każde przedsięwzięcie, komercyjnych (np. �rmy komputerowe, programistyczne), jak i niekomercyjnych (agencje rzą-
musi zostać odpowiednio zaplanowany i przy- dowe itp.), niezależnie od wielkości �rmy, typu organizacji czy też posiadanych narzędzi. Każ-
gotowany. Etapy realizacji audytu można okre- dy proces powinien posiadać zde�niowane role i odpowiedzialności.
ślić poprzez następujące punkty:
www.sdjournal.org 67
Praca w zespole
• dostawca ów nie jest powiązany z do- nie ma przymusu angażowania wy- cele audytu. Zespół audytujący musi skła-
stawcą poddawanym audytowi; specjalizowanej firmy audytującej. dać się z ludzi będących w stanie ocenić da-
• pracownicy firmy, która będzie reali- • Dobór zespołu audytującego ny przedmiot – dlatego też zwykle audyt re-
zować audyt, posiadają kwalifikacje i alizowany jest przez kilku audytorów, przy
niezbędne umiejętności w zakresie Na audytorach spoczywa odpowiedzialność czym każdy zajmuje się inną specjalnością.
prowadzenia audytu; za proces obiektywny, niezależny i wiary-
• sam dostawca dysponuje zasobami godny. Zgromadzenie dowodów obiektyw- • Analiza informacji wejściowych
i mechanizmami umożliwiającymi nych, pomoc w wykryciu przyczyn źródło-
poprawne wykonanie oceny; wych, informacja zwrotna, sugestie doty- Polega na zebraniu przez zespół audytujący
• klientowi nie zależy na uzyskaniu czące doskonalenia procesów, zasugerowa- danych stanowiących podstawę do wykony-
certyfikatu z wykonanego audytu i nie działań korygujących to podstawowe wania oceny (kryteriów audytu) i opracowa-
niu ich w takiej postaci, by mogły służyć ja-
Standardy audytu systemów informatycznych (IS Auditing Standards) ko mechanizmy przeprowadzania audytu.
Czyli – jeżeli audyt dotyczy oceny procesu
• 010 Prawa i powinności audytu testowania wewnętrznego (funkcjonalnego)
Obowiązki, uprawnienia i odpowiedzialność obszaru działania realizującego funkcję audytu dostawcy, danymi wejściowymi będą np.:
systemów informatycznych mają być odpowiednio udokumentowane w dokumencie regu-
• plan projektu – z uwzględnieniem
lującym prawa i powinności audytu lub w umowie na jego przeprowadzenie.
czasu przeznaczonego na testy, by
• 020 Niezależność skonfrontować go następnie z rze-
We wszystkich sprawach związanych z audytowaniem audytor systemów informatycznych musi czywistym czasem trwania testów
być niezależny od poddawanych audytowi, zarówno co do stanowiska, jak i postępowania. oraz zapisami planu testów;
• 020.020 Powiązania organizacyjne
• plan testów (wraz z wybranym po-
Funkcja audytu systemów informatycznych musi być wystarczająco niezależna od audyto- dejściem do testów np. black box,
wanego obszaru, aby umożliwić obiektywne prowadzenie audytu. podejście oparte na wymaganiach;
harmonogramem testów, składem
• 030 Standardy i etyka zawodowa zespołu testującego, kryteriami
Audytor systemów informatycznych jest zobowiązany do stosowania się do Kodeksu Etyki
wejścia/wyjścia testów);
Zawodowej Stowarzyszenia do spraw audytu i kontroli systemów informatycznych (ISACA –
Information Systems Audit and Control Association). • projekt testów (czyli zbiór przypad-
ków i scenariuszy testowych – ana-
• 030.020 Należyta staranność zawodowa lizowany celem identyfikacji pokry-
Wobec wszelkich aspektów pracy Audytora Systemów Informatycznych obowiązuje należy- cia funkcjonalności testami);
ta zawodowa staranność i przestrzeganie odpowiednich standardów audytu.
• wykaz narzędzi stosowanych do za-
• 040 Kompetencje rządzania testami i wspierania rapor-
Audytor systemów informatycznych ma być kompetentny w zagadnieniach technicznych, towania (by określić, czy narzędzia
posiadając umiejętności i wiedzę niezbędną do wykonywania pracy audytorskiej. owe są rzeczywiście wykorzystywane
w procesie testowym i w jakim stop-
• 040.020 Ustawiczne szkolenie zawodowe
niu);
Audytor systemów informatycznych ma utrzymywać kompetencje dotyczące zagadnień
technicznych poprzez właściwe i ustawiczne szkolenie zawodowe. • dokumentacja procedur – np. obsłu-
gi zgłoszeń błędów, żądań zmian etc.
• 050 Planowanie
Audytor Systemów Informatycznych powinien planować prace związane z audytem sys- Informacje zawarte w danych wejściowych
temów informatycznych pod kątem realizacji celów audytu oraz zgodnie z odpowiednimi
należy przetworzyć celem ustalenia punk-
standardami przeprowadzania audytów.
tów kontroli (tzn. istotnych elementów pro-
• 060 Wykonywanie prac audytowych cesu, które będą poddawane audytowi), któ-
re w następnej kolejności umożliwią opraco-
Personel zajmujący się audytem systemów informatycznych ma być odpowiednio nadzorowany, aby wanie formularzy, list kontrolnych przezna-
zapewnić, że cele audytu są spełnione oraz że są spełnione stosowne, zawodowe standardy audytu.
czonych do dalszego wykorzystania już pod-
• 060.020 Dowody czas przeprowadzania audytu.
Zadaniem Audytora Systemów Informatycznych podczas przeprowadzania audytu jest zgro-
madzenie wystarczających, wiarygodnych, odpowiednich (relewantnych) i użytecznych do- • Opracowanie harmonogramu audytu
wodów, tak by efektywnie zrealizować zadania audytu. Wyniki audytu oraz wnioski powinny
być poparte odpowiednią analizą i interpretacją tychże dowodów.
Audyt nie może odbywać się ad hoc, bez ła-
• 070 Raportowanie du i składu, audytorzy nie mogą biegać bez-
Zadaniem Audytora Systemów Informatycznych jest dostarczenie określonym odbiorcom ładnie po całej placówce, odpytując raz jedną
odpowiednio sformowanego raportu dotyczącego wykonanych prac audytowych. Raport z osobę, raz drugą. Plan przeprowadzania po-
audytu ma przedstawiać obszar, cele, okres oraz rodzaj i zakres wykonanych prac audyto- szczególnych działań audytowych powinien
wych. Raport ma wskazywać organizację, planowanych odbiorców raportu oraz wszelkie za-
być jasno określony i zakomunikowany au-
strzeżenia co do jego obiegu. Raport ma przedstawiać wyniki, wnioski i rekomendacje oraz
wszelkie zastrzeżenia lub uwarunkowania audytora wobec audytu. dytowanym przed rozpoczęciem oceny.
Harmonogram uwzględnia wykonanie
• 080 Dalszy tok działań wszystkich zaplanowanych działań audytowych,
Audytor systemów informatycznych ma domagać się i oceniać stosowne informacje o wcześniej- przez wszystkie osoby wykonujące ocenę i dla
szych wynikach, wnioskach i rekomendacjach, aby określić, czy zostały podjęte na czas właściwe
wszystkich obszarów/przedmiotów oceny. Każ-
działania.
dy dzień audytu powinien rozpoczynać się spo-
68 03/2010
Audyt techniczny
www.sdjournal.org 69
Praca w zespole
Wery�kacja efektywności zarządzania systemem w kontekście je- Audytor ds. 12:15 – 13:00
go architektury. architektury
Przerwa 13:00 – 14:00
Wery�kacja zapewnienia spójności przetwarzania danych w ra- Audytor ds. 14:00 – 14:30
mach zastosowanej architektury. architektury
Identy�kacja zagrożeń związanych z poszczególnymi komponen- Audytor ds. 14:30 – 15:00
tami rozwiązania i z powiązaniami pomiędzy tymi komponentami. architektury
Wery�kacja mechanizmów logowania zdarzeń. Audytor ds. 15:00 – 15:25
architektury
Zarządzanie zabezpieczeniami (w tym zarządzanie mechanizmami Audytor ds. 15:25 – 16:00
kryptogra�cznymi). architektury
Wery�kacja komponentów sprzętowych wchodzących w skład sys- Audytor ds. 16:00 – 16:30
temu i ich kon�guracja. architektury
Proces wy- Identy�kacja etapów procesu wytwórczego Plan projektu Audytor ds. 09:45 – 10:15
twórczy DIP zarządzania
dostawcy procesem
Identy�kacja mechanizmów kontroli jakości w poszczególnych Plan projektu Audytor ds. 10:15 – 11:00
etapach procesu wytwórczego Plan zarządza- zarządzania
nia jakością procesem
Wery�kacja podejścia do planowania prac przez dostawcę Plan projektu Audytor ds. 11:00 – 11:45
DIP zarządzania
procesem
Analiza procesu dokumentacji realizacji prac przez dostawcę Plan projektu Audytor ds. 11:45– 12:30
DIP zarządzania
procesem
Wery�kacja kompetencji osób realizujących prace rozwojowe Plan projektu Audytor ds. 12:30 – 13:00
Plan zarządza- zarządzania
nia zasobami procesem
Przerwa 13:00 – 14:00 Project Manager
Test Manager
Analityk ze stro-
ny dostawcy
Określenie wymagań jakościowych i sposoby wery�kowania ich re- Plan zarządza- Audytor ds. 14:00 – 15:00
alizacji nia jakością zarządzania
procesem
Analiza procesu testowania aplikacji Plan projektu Audytor ds. 15:00 -
Plan testów zarządzania 16:00
procesem
Wery�kacja planu reagowania na zgłoszone problemy z funkcjo- Plan zarządza- Audytor ds. 16:00 – 16:30
nowaniem oprogramowania nia jakością zarządzania
procesem
Spotka- Potwierdzenie wykonanego planu audytu, opis wykonywanych Audytor ds. 16:30 – 17:00
nie zamy- działań audytowych. architektury
kające ko- Ustalenie spostrzeżeń z przeprowadzonego audytu. Opracowanie Audytor ds.
niec audy- rekomendacji. zarządzania
tu dnia 1 procesem
70 03/2010
Audyt techniczny
sugeruje odpowiedź. Audytor powinien sa- przyjętym dla oceny. Przykładowo, jeśli kry- nie. Usunięcie niezgodności jest komuniko-
modzielnie ocenić zgodność stanu rzeczy na terium oceny dla testów funkcjonalnych jest wane klientowi i może być potwierdzone ko-
podstawie udzielonych, pośrednich odpowie- używanie narzędzia JIRA do zarządzania błę- lejnym audytem (np. jeżeli wykryto znaczną
dzi i własnych obserwacji. Nie wystarcza więc dami, a w wyniku wywiadu okazało się, iż sto- liczbę niezgodności krytycznych).
tylko pytać – ustne deklaracje należy zwery- sowane jest inne narzędzie, należy wykazać to Analiza wyników audytu to nie tylko wy-
fikować np. w przypadku pytania: jakie na- jako niezgodność i umieścić w raporcie koń- kazanie zgodności i niezgodności – to rów-
rzędzia służą do zarządzania testami, należy cowym z audytu. Zalecenia dotyczące usta- nież określenie zaleceń i rekomendacji służą-
sprawdzić, czy rzeczywiście takie narzędzie leń z audytu opisane są szczegółowo w punk- cych udoskonaleniu wadliwych procesów czy
jest wykorzystywane. Jak? Po prostu prosząc cie 6.5.5 normy ISO/DIS 19011 Opracowanie produktów. Rekomendacje nie są przymu-
audytowanego o pokazanie owego narzędzia ustaleń z audytu. Ustalenia z audytu dotyczą- sem, a ich wdrożenie obligatoryjne dla orga-
na stacji roboczej i wglądzie w jego zawartość cego zgodności i niezgodności oraz wspierają- nizacji zlecającej audyt – mogą jednak w zna-
(repozytorium testów). ce je dowody powinny być zapisywane; każde czącym stopniu usprawnić działanie instytu-
spostrzeżenie, informacje zdobyte w oparciu cji czy wybranego obszaru.
• Przeprowadzenie audytu i zbieranie danych o obserwację czy uzyskane w rozmowie z au-
dytowanym powinny być zanotowane. Powód • Spotkanie zamykające i raport dla klienta
Przeprowadzenie audytu musi opierać się na jest prosty – pamięć ludzka jest zawodna, i na-
konkretnych podstawach, by uzyskane od- wet jeżeli audytor doskonale pamięta przebieg Spotkanie zamykające to ostatni punkt au-
powiedzi pozwalały jednoznacznie i rzetel- wywiadu dziś, może nie być w stanie przypo- dytu. Może odbyć się dopiero po wykonaniu
nie ocenić dany problem. Audytor przepro- mnieć go sobie jutro. A informacje z wywia- wszystkich zaplanowanych działań audyto-
wadza wywiady i dokonuje obserwacji, po- dów czy obserwacji są podstawą do opracowa- wych, przeanalizowaniu wyników i opraco-
sługując się opracowanymi przez siebie for- nia raportu końcowego z wyników. waniu raportu końcowego.
mularzami i listami kontrolnymi. Doku- W przypadku wykrytych niezgodności au- Niezgodności wykryte podczas audytu są
menty te zawierają pytania kontrolne doty- dytor powinien określić ich priorytet, czy- komunikowane osobom odpowiedzialnym
czące każdego elementu istotnego dla doko- li stopień, w jakim wpływają na jakość da- za audytowany obszar oraz zapisywane przez
nania oceny – audytor przeprowadza wy- nych prac. Priorytety mogą być określane na- audytora wiodącego (na podstawie informacji
wiad, opierając się na owych pytaniach, w ra- stępująco: uzyskanych od pozostałych audytorów) w od-
zie konieczności już w trakcie dyskusji z au- powiednim dokumencie np. Protokole nie-
dytowanym, dodając nowe pytania i uwa- • niski – niezgodność mająca znikomy zgodności.
gi oraz odnotowując uzyskane odpowiedzi. wpływ na jakość procesu/produktu; Spotkanie zamykające prowadzone jest przez
Wypełnione listy kontrolne służą następnie • normalny – niezgodność wpływająca ne- audytora wiodącego. Podczas tego spotkania
do opracowania wyników – czyli stwierdze- gatywnie na jakość procesu/produktu, omawiane są ustalenia, wnioski z audytu oraz
nia, które z elementów przedmiotu audytu lecz nie krytyczna; mocne i słabe strony przedmiotu oceny.
są zgodne z założeniami, a gdzie wystąpiły • krytyczny – krytyczne uchybienie w zało- Problemem, który może wystąpić w trakcie
niezgodności. żeniach polityki jakości, rażący błąd etc. spotkania zamykającego, jest tzw. czynnik ludz-
ki i reakcje na krytykę. Podczas wywiadów i ob-
• Analiza i opracowanie wyników Niezgodności o priorytecie niskim nieko- serwacji audytorzy są neutralni, skupiają się na
niecznie muszą być usuwane, lub przynajm- zadawaniu pytań i wysłuchiwaniu odpowie-
Zebrane w trakcie audytu informacje nale- niej nie w pierwszej kolejności. Niezgodno- dzi bez oceniania czy wyrażania własnej opinii
ży poddać analizie celem określenia, czy stan ści krytyczne powinny być wyeliminowane bądź krytycznych uwag – spotkanie zamykają-
rzeczy odpowiada wymaganiom i założeniom jak najszybciej – w ściśle określonym termi- ce zmienia ten stan rzeczy: polega na jasnym,
www.sdjournal.org 71
Praca w zespole
dosłownym i popartym dowodami wykazaniu nie kontrola, a proces z założenia mający na • Weryfikacja skuteczności działań kory-
braków, niezgodności i usterek. Nie wszyscy po- celu doskonalenie organizacji. Tu nie szu- gujących
trafią przyjąć krytykę bez emocji i prób udo- ka się odpowiedzialnych, winnych i nie oce-
wadniania swoich racji. Zdarza się, iż audytowa- nia – celem jest wskazanie miejsc, które wy- Spotkanie zamykające audyt skutkowało usta-
ny reaguje na wytknięte błędy agresją – dlatego magają ulepszenia i dostarczenie obiektyw- leniem pewnych dalszych działań, które pole-
szczególnie ważne jest zebranie i przedstawie- nej informacji zwrotnej o skali i rodzaju nie- gają na usunięciu zaistniałych niezgodności.
nie niepodważalnych dowodów, faktów wystą- zgodności. Za wykonanie tych działań w ściśle określo-
pienia niezgodności. Audytor nie stawia wnio- Spotkanie zamykające to również ustalenie nym terminie odpowiedzialni są wyznacze-
sków na podstawie swoich przeczuć czy insynu- koniecznych działań korygujących i określe- ni pracownicy (w tym przypadku dostawcy
acji – lecz na postawie faktów, których audyto- nie terminów ich wykonania. Niezgodności IT). Wyniki prac korygujących powinny być
wany nie podważy. zidentyfikowane jako krytyczne lub ważne dla zakomunikowane zespołowi audytującemu
Audytor nie może obawiać się przekaza- jakości procesu powinny zostać usunięte i pod- i klientowi – a ich poprawność i kompletność
nia swojej informacji zwrotnej – audyt to dane kontroli zespołu audytowego. zweryfikowana.
Audyt może być uważany za zakończony
po usunięciu i potwierdzeniu poprawności
Trochę psychologii... wszystkich niezgodności, które zostały prze-
Perspektywa audytu może budzić w pracownikach dostawcy obawy i poczucie zagrożenia.
Audyt nie jest kontrolą, nie polega na doszukiwaniu się błędów i niedociągnięć ze strony au- kazane do korekty.
dytowanego – jednak uczestnicy audytu mogą odczuwać presję i stres, wynikające z poczu-
cia, iż są oceniani. Często audyt odbierany jest jako próba podważenia kompetencji osób au- Podsumowanie
dytowanych lub brak zaufania do rzetelności audytowanego. Audyt to nie kontrola, a audytorzy nie stawia-
To, czy ten problem zostanie rozwiązany, a audytowany nabierze zaufania do oceniających ją sobie za cel numer jeden pognębienie od-
i poczuje się w miarę komfortowo, w dużej mierze zależy od samego zespołu audytorów. Od
ich umiejętności i doświadczenia będzie zależało, czy uda im się nawiązać odpowiednie rela-
pytywanego i udowodnienie mu, że źle wy-
cje i zbudować dobry model współpracy z audytowanymi. Profesjonalny audytor nie stosu- konuje swoją pracę. Dobrze rozumiany au-
je technik, które polegają na przysłowiowym zapędzaniu przesłuchiwanego w kozi róg i łapaniu dyt, z wyraźnie postawionym celem i profe-
za słówka. Zadaniem audytora jest ocena stanu rzeczywistego, nie udowadnianie audytowa- sjonalnym przygotowaniem, pomoże udosko-
nemu, że się myli. Wytyczne odnoszące się do kompetencji personelu przeprowadzającego nalić organizację i wyeliminować błędy, któ-
audyt są przedmiotem punktu 7 normy ISO/DIS 19011 – Kompeten cje audytorów.
rych być może ktoś z wewnątrz danej orga-
Punkt ów mówi, że do prowadzenia audytów jakości należy zatrudniać personel umiejący
je realizować nie tylko z merytorycznego punktu widzenia – tzn. posiadający odpowiednie nizacji nigdy by nie odkrył. Zaangażowanie
kompetencje, znajomość branży, technik oceny dotyczących badania, sporządzania rapor- zewnętrznej firmy audytowej daje pewność,
tów, kierowania, planowania i organizowania. Równie istotne są cechy osobiste charaktery- że uzyskamy obiektywne i pozbawione pew-
zujące audytora – umiejętność skutecznej komunikacji interpersonalnej, dyplomacji, pracy nych uprzedzeń spojrzenie na funkcjonowa-
w zespole, asertywność i przede wszystkim etyczne postępowanie. Od predyspozycji i umie- nie naszej organizacji. Wyniki, które da au-
jętności interpersonalnych audytorów w znaczącym stopniu zależy, czy proces audytu bę-
dyt, będą pozbawione przekłamań i rzetelnie
dzie procesem interaktywnym i umożliwi osiągnięcie postawionych przed nim celów. Dla-
czego? Ponieważ wystraszony i zestresowany audytowany nie jest skory do współpracy. Aby oddadzą rzeczywisty stan rzeczy oraz praw-
porozumiewać się skutecznie, należy używać jasnych sformułowań, aktywnie i uważnie słu- dziwe problemy i zagrożenia – a znając je, ła-
chać, przejąć odpowiedzialność za prowadzenie rozmowy, jeśli jest taka potrzeba, porządko- twiej nam będzie je usunąć.
wać wypowiedzi chaotyczne, podtrzymywać sprzyjający klimat komunikacji. Audyt zewnętrzny może być też począt-
Bardzo ważną kwestią jest komunikacja – jasne poinformowanie audytowanych o celach i za-
kiem wdrażania własnych mechanizmów
kresie audytu może skutecznie wyeliminować negatywne reakcje – opór, kwestionowanie
audytu, złośliwość i agresja. doskonalenia w organizacji, która ów audyt
zleciła – bazując na już zdobytych doświad-
czeniach i obserwacji działań zawodowych
audytorów, firma może opracować i stoso-
Pojęcia wać podobne, w mniejszym zakresie lub
mniej sformalizowane, działania celem oce-
• Audyt – usystematyzowany, niezależny i udokumentowany proces uzyskania dowodu ny innych niż poddane audytowi procesy czy
z audytu i obiektywnej oceny w celu określenia, w jakim stopniu spełniono uzgodnione produkty. I stopniowo udoskonalać całość or-
kryteria audytu;
ganizacji.
• Audytor – osoba posiadająca kompetencje do przeprowadzenia audytu;
• Audytor wyznaczony do kierowania audytem określany jest audytorem wiodącym;
• Audytowany – organizacja, komórka, która jest audytowana;
• Kryteria audytu – zestaw polityk, procedur lub wymagań określonych jako odniesienie; KAROLINA ZMITROWICZ
• Niezgodność – niespełnienie ustalonych wymagań; Pracuje na stanowisku Analityka biznesowe-
• Wnioski z audytu – wynik audytu, przedstawiony przez zespół audytujący w Raporcie z audytu. go w �rmie Pro�-Data. Karolina specjalizuje się
obecnie w modelowaniu wymagań biznesowych
dla ubezpieczeń. Wcześniej pracowała jako Ma-
nager Quality Assurance w projektach informa-
W Sieci
tycznych w sektorze �nansowo – bankowym.
• www.audyty.pl – strona na temat audytów. Opisuje m.in. audyty informatyczne; Pro�-Data to producent oprogramowania spe-
• www.audyt.net – strona zawiera praktyczne informacje dla audytorów wewnętrznych, cjalizujący się w budowie dedykowanych rozwią-
a także narzędzia i wzorce dokumentów audytowych; zań informatycznych dla ubezpieczeń, bankowo-
• www.isaca.org/cobit – o�cjalna strona ISACA, informacje na temat COBIT;
ści i administracji publicznej. Firma posiada cer-
• ww.itil-officialsite.com – o�cjalna strona ITIL;
• http://www.ffiec.gov/ffiecinfobase/booklets/audit/audit_00a_roles_rRespons.html – role ty�kat jakości ISO 9001:2000 w zakresie produk-
i odpowiedzialności w audycie IT. cji oprogramowania.
Kontakt z autorem: karolina_zmitrowicz@wp.pl
72 03/2010
Efektywność pracy
Klient,
który wie czego chce
Czyli sztuka zadawania pytań
Jeśli zdarza Ci się spotykać z osobami nietechnicznymi i musisz
pozyskiwać od nich konkretne informacje, aby móc sprawnie
implementować swoje zadania, to ten artykuł jest dla Ciebie. Skupiliśmy
się w nim na technice zadawania pytań, która ogólne informacje
pomaga przekuć na mierzalne konkrety.
nia dotyczące tej aplikacji. Czy to łatwe za-
Dowiesz się: Powinieneś wiedzieć: danie, czy trudne? O jakich rzeczach bę-
• Jak uzyskiwać potrzebne Ci konkrety z ogól- • Tylko to, co już wiesz. dziesz mówił z tego IT-agnostycznego punk-
nych informacji; tu widzenia?
• Jak omijać impas w rozmowie. Prawdopodobnie opowiesz o:
• swoich wyobrażeniach;
• o tym, co widziałeś w aplikacjach po-
cie czytania tego artykułu przyjął następują- dobnego typu;
ce założenia: • o tym, co ktoś Ci powiedział na temat
Poziom aplikacji tego typu;
trudności • Klient zawsze wie, czego chce – wie, że • o swoich problemach z papierowymi
chce rozwiązać jakiś problem, osiągnąć organizerami;
jakiś cel, coś usprawnić; • o swoich obawach związanych z przej-
• Klient nie zawsze wie, czego potrze- ściem z organizera papierowego na
C
zy nie nurtuje Cię, dlaczego czę- buje – ponieważ jest skupiony przede elektroniczny.
sto uważa się, że klient nie wie, wszystkim na swoich procesach bizne-
czego chce od {programistów | sowych; Chociaż większość klientów jest pewnie
analityków | liderów projektów | teste- • Klient często nie zdaje sobie sprawy o wiele bardziej wyedukowana w kontak-
rów}? Z drugiej strony, dlaczego jest oczy- z konsekwencji swoich oczekiwań – cie z komputerem, to jednak to krótkie do-
wiste, że programiści zawsze wiedzą, cze- gdyż jest ekspertem w obrębie swojej świadczenie pozwoliło Ci spojrzeć na świat
go chcą od klienta? Z pewnością jesteśmy działalności biznesowej, a nie w obsza- oczami stereotypowego klienta. Jakbyś się
bardzo przywiązani do takich przekonań, rze technologii informatycznych. poczuł, gdybyśmy powiedzieli Ci, że nie
zwłaszcza gdy wyrobiliśmy je sobie pod- wiesz, czego chcesz? Pewnie uważałbyś,
czas szeregu spotkań z osobami nietech- Jeśli zgodzisz się na chwilę myśleć w ten że nie mamy racji, przecież Ty wiesz, cze-
nicznymi (oni naprawdę nie wiedzą, cze- sposób, wspólnie poszukamy narzędzi, go chcesz: chcesz mieć elektroniczny orga-
go chcą!). Chyba jednak zgodzisz się z na- które ułatwią pracę z klientem. nizer i starasz się to wytłumaczyć najlepiej
mi, że to jednostronne spojrzenie nie jest jak potrafisz.
do końca sprawiedliwe. Przypatrzenie obu Po drugiej stronie lustra
stronom komunikacji poszerzy naszą per- Czy zastanawiałeś się kiedyś, jakby to było, Po pierwszej stronie lustra
spektywę. gdybyś budząc się pewnego dnia, ze zdzi- Wróćmy teraz do znajomej perspektywy
wieniem zauważył, że przepadła gdzieś ta- programisty. Gdybyś otrzymał zadanie do
Potrzebuję... jemniczo cała twoja, z trudem zbierana, zaimplementowania: Stworzyć elektroniczny
Gdy siedzisz naprzeciw klienta i nie wiesz, wiedza informatyczna, wiedza o programo- organizer, to chciałbyś dowiedzieć się czegoś
co próbuje Ci przekazać, to powinieneś so- waniu, o systemach, że cała Twoja umiejęt- więcej: jak ma wyglądać? Jakie funkcjonal-
bie uświadomić, że ma on jakąś potrze- ność pracy z komputerem sprowadza się do ności ma udostępniać? Jak konkretnie ma
bę (w zależności od człowieka może być wciskania przycisku Power i czasem Reset? działać? To jest sedno sprawy. Aby stwo-
to problem lub cel do osiągnięcia) i uwa- Jakby to było, gdybyś przeżył coś takiego? rzyć oprogramowanie, potrzebujesz bar-
ża, że technologie informatyczne na pew- Trwając w tej perspektywie, wytłumacz dzo konkretnych i szczegółowych informa-
no mu w tym pomogą. Gdyby klient czegoś nam, że chciałbyś, abyśmy stworzyli opro- cji, których klient Ci nie dostarcza. Dlacze-
nie potrzebował, to nie spotykałby się z To- gramowanie, które będzie Twoim osobi- go? Bo nie wie, że powinien. Opisuje swo-
bą. Z tego względu prosimy Cię, abyś w trak- stym organizerem. Opisz swoje oczekiwa- je oczekiwania tak dobrze jak tylko potrafi.
74 03/2010
Klient, który wie czego chce
Dziwi go, że chciałbyś wiedzieć, czy zapiski • usunięć, np.: Po wciśnięciu przycisku ne zachowanie sprawiło, że wyciągnąłeś
w organizerze powinny być trwale przecho- Generuj system od razu generuje ra- wnioski na temat działania systemu?
wywane i jak długo, ile osób ma mieć dostęp port – co to znaczy „od razu”? Jak dłu-
do organizera, czy organizer ma być używa- go ma trwać generowanie raportu? Po- Zadając odpowiednie pytania, możemy
ny na komputerze PC, notebooku, netbo- między jakimi zdarzeniami mierzony jest stopniowo wydobywać cenne informa-
oku, czy telefonie itd. Odpowiedzi na nie- ten czas? Jak konkretnie ma wyglądać ra- cje z tego, co mówi klient lub użytkow-
które pytania są dla klienta oczywiste. Czy port? Jakie informacje ma zawierać? Kto nik. Skąd zatem wiadomo, kiedy przestać
zapiski mają być przechowywane? Jasne, że może wcisnąć przycisk Generuj? W jaki pytać? Wtedy, gdy informacje są komplet-
tak! Jak długo? Na zawsze! Inne pytania bu- sposób system dostarcza raport? ne i jednoznaczne. Gdy na ich podstawie
dzą u klienta zdziwienie, gdyż nie wiedział, • uogólnień, np.: Trzeba odbyć dziesięć można przystąpić do implementacji. Oczy-
że są istotne podczas tworzenia oprogramo- spotkań – kto tak powiedział? Z czego wy- wiście podczas programowania mogą po-
wania. Do momentu, gdy nie wyewoluuje nika ta konieczność? Co by się stało, gdy- jawić się dodatkowe pytania. Może oka-
w ludziach umiejętność telepatii, zadawa- byśmy odbyli osiem lub dziewięć spotkań? zać się, że wymagania nie zostały zebrane
nie pytań jest najlepszym sposobem na po- • zniekształceń, np.: Myślałem, że tak to w wystarczająco konkretnej formie. W ta-
znanie myśli innych osób. ma działać – co sprawiło, że tak pomyśla- kich przypadkach znów sięgamy po narzę-
łeś? Czy jakieś moje zachowanie? Co kon- dzie, jakim jest Sztuka Zadawania Pytań.
Potęga pytań kretnie w moim zachowaniu sprawiło, że Warto wspomnieć również o jednej waż-
Częstym zarzutem powtarzanym przez tak pomyślałeś? W jaki sposób to konkret- nej rzeczy: zanim zaczniesz zadawać pyta-
użytkowników w kierunku programistów
jest to, że programiści na wszystkie prośby
o dodanie lub zmianę funkcjonalności ma-
Usunięcia
Powstają, gdy rozmówca pomija część informacji niezbędnych do prawidłowego zrozumie-
ją tę samą odpowiedź: Nie da się! Użytkow- nia przekazu.
nicy skarżą się, że o cokolwiek by nie prosili,
pierwsze, co słyszą, to odmowa. Łatwo mo- • Interfejs ma być intuicyjny – po czym poznasz, że interfejs jest intuicyjny? Jakie są objawy in-
żesz odczuć frustrację użytkowników: zwy- tuicyjnego interfejsu?
• Organizer nie działa tak, jak trzeba – co konkretnie nie działa? Jakie konkretne czynności
czajnie wyobraź sobie, że przy każdej proś-
wykonujesz? Jakiego efektu się spodziewałeś? Jaki efekt otrzymałeś?
bie o podwyżkę słyszysz: Nie da się! • Sortowanie ma być szybkie – jak długo maksymalnie może trwać sortowanie? Pomiędzy
Zamiast takiej twardej odpowiedzi moż- którymi momentami należy przeprowadzić pomiar?
na zadać kilka pytań:
www.sdjournal.org 75
Efektywność pracy
nia, poproś rozmówcę o zgodę. Tego typu w dół (ang. chunk down). Istnieją również • Klient: Po tym, że trzeba się zalogować,
szczegółowe pytania sprawiają, że rozmów- pytania uogólniające, które prowadzą w od- a w razie awarii komputera nie są traco-
ca musi dokładnie zastanowić się nad od- wrotnym kierunku. Nazywane są one py- ne żadne dane.
powiedzią, musi zastanowić się nad moty- taniami w górę (ang. chunk up). Pytania • Programista [proponuje inny sposób na
wacją swoich oczekiwań. Czasem użytkow- w dół kierują uwagę w stronę konkretów, zapewnienie bezpieczeństwa]: W tech-
nik zdaje sobie sprawę, że nie do końca prze- np.: Co dokładnie? Po czym poznasz? Jak nologii, którą rekomendujemy, stosujemy
myślał swoje oczekiwania lub że są one nie- zmierzysz? Pytania w górę pozwalają od- specjalny bezpieczny moduł logowania.
realistyczne czy niepotrzebne. Nie jest to kryć przyczyny i potrzeby: Dlaczego? Co Jednocześnie możemy wbudować w orga-
zbyt miłe uczucie. Zadbaj zatem o kom- jest w tym ważnego? Finezja w posługiwa- nizer mechanizm kopii bezpieczeństwa.
fort rozmowy i poproś o zgodę na zadawa- niu się pytaniami w górę i w dół (albo tech- Polega on na tym, że przy każdym uru-
nie pytań. niką chunk up / chunk down) polega na chomieniu wszystkie ważne dane są ko-
tym, że gdy pojawia się kwestia sporna na piowane na specjalny serwer bezpieczeń-
Ominąć impas temat szczegółów, to szukamy przyczyny, stwa.
Z pewnością zauważyłeś, że przedstawiony a następnie innego szczegółowego sposobu • Klient: Ok, podoba mi się to rozwiązanie.
sposób na wydobywanie konkretów z infor- wynikającego z tej samej przyczyny. Przy-
macji przekazywanych przez rozmówcę po- kładowy dialog z klientem mógłby przebie- Zauważ, że programista za pomocą py-
zwala tylko na poruszanie się w jedną stro- gać następująco: tań w górę i w dół trafnie zidentyfikował
nę: od ogółu do szczegółu. Co jednak, gdy rzecz ważną dla klienta. Jest nią bezpie-
klient rzuca na stół poważny argument na • Klient: Chcę, żeby mój organizer został czeństwo oprogramowania. Zauważ rów-
dużym poziomie konkretności, np.: Chcę, zaimplementowany w technologii JMS! nież, że proponując inne rozwiązanie niż
żeby mój organizer został zaimplemento- • Programista [pytanie w górę]: Dlaczego technologia JMS, buduje swoją wypo-
wany w technologii JMS! Po krótkim szoku takie ważne jest, aby organizer był wyko- wiedź odkrytej ważnej rzeczy. Kilkukrot-
zaczniesz zastanawiać się, jak z tej sytuacji nany w technologii JMS? nie podkreśla, że nowe rozwiązanie bę-
wybrnąć. Mógłbyś zacząć wyliczać powo- • Klient: Ponieważ słyszałem, że programy dzie bezpieczne. W ten sposób udaje mu
dy, dlaczego w tym konkretnym rozwiąza- w tym napisane są bardzo bezpieczne się ominąć impas w rozmowie. To jest wła-
niu JMS nie jest najlepszym rozwiązaniem. • Programista [szuka rzeczy ważnej dla śnie istota rzeczy: programista omija im-
Z drugiej strony pamiętasz, że bitwa na ar- klienta]: Rozumiem, że bezpieczeństwo pas zamiast go przełamywać. Nie upiera
gumenty w sytuacji gdy strony są na zupeł- oprogramowania jest dla Pana bardzo się przy swoim rozwiązaniu, lub co gorsze
nie innych poziomach merytorycznych, do- ważne? nie krytykuje rozwiązania klienta. Świa-
prowadzi donikąd. Co zrobić w takiej sytu- • Klient: Tak. domie stara się odkryć potrzeby i rzeczy
acji? Oczywiście zadać pytanie! • Programista [pytanie w dół]: Po czym ważne. Poszukuje przyczyn, które spra-
Pytania uszczegóławiające, które oma- konkretnie poznaje Pan, że oprogramowa- wiły, że klient obstaje przy jakimś szcze-
wialiśmy do tej pory, noszą nazwę pytań nie jest bezpieczne? gółowym rozwiązaniu. Gdy już zidentyfi-
kuje i upewni się co do potrzeb, wtedy ma
o wiele szersze pole do działania i może
zaproponować najlepsze jego zdaniem roz-
wiązanie. W przedstawionym przypadku
klient wiedział, czego chciał. Chciał bez-
pieczeństwa. Nie wiedział tylko, czego
konkretnie potrzebował.
Sytuacje podobne do omówionych w ar-
tykule dzieją się każdego dnia. W setkach
firm, na tysiącu spotkań miliony sfrustro-
wanych uczestników wciąż na nowo zadają
sobie te same pytania: Co on mówi? Dlacze-
go mnie nie słucha? O co mu chodzi? Dlaczego
on nic nie rozumie? Gdy rozmawiasz z kimś,
to od Ciebie zależy przynajmniej 50% efek-
tywnej komunikacji. Jak zamierzasz wyko-
rzystać swoje 50%?
MICHAŁ BARTYZEL,
MARIUSZ SIERACZKIEWICZ
Trenerzy i konsultanci w �rmie BNS IT. Badają
i rozwijają metody psychologii programowania,
pomagające programistom lepiej wykonywać ich
pracę. Na co dzień Autorzy zajmują się zwiększa-
niem efektywności programistów poprzez szkole-
nia, warsztaty oraz coaching i trening.
Kontakt z autorami: m.bartyzel@bnsit.pl,
Rysunek 1. Pytania w górę i w dół m.sieraczkiewicz@bnsit.pl
76 03/2010
KLUB PRO
Oferta skierowana dla firm
Jeżeli Twoja firma jest prenumeratorem Software Developer’s Journal za comiesięczną
dopłatą 50 PLN +VAT możesz dodatkowo otrzymać reklamę.
Wystarczy tylko, aby profil Twojej firmy pokrywał się z naszym magazynem.
Wyślij do nas: logo firmy, dane kontaktowe i informację o firmie
Reklama przez 12 kolejnych numerów tylko za 600 PLN +VAT.
Jeżeli nie posiadasz jeszcze prenumeraty możesz ją zamówić w atrakcyjnej cenie.
Dla nowych prenumeratorów specjalna oferta – 690 PLN.
http://www.kei.pl http://www.future-processing.pl
http://www.infotex.com.pl http://www.OprogramowanieKomputerowe.pl
http://www.itsolutions.biz.pl
marcin.pytlik@itsolutions.biz.pl http://www.softline.com.pl
tylko
256,-
Software Developer’s Journal (poprzednio Software 2.0)
jest miesięcznikiem głównie dla programistów, którzy li-
czą, że dostarczymy im gotowe rozwiązania, oszczędza-
jąc im czasu i pracy. Jesteśmy czytani przez tych, któ- UWAGA!
rzy chcą być na bieżąco informowani o najnowszych osią-
gnięciach w dziedzinie IT i nie chcą, żeby jakiekolwiek
istotne wydarzenia umknęły ich uwadze. Aby zadowolić Zmiana danych
kontaktowych
naszych czytelników, prezentujemy zarówno najnowsze
rozwiązania, jaki starsze, sprawdzone technologie.
Obsługa prenumeraty
Software Wydawnictwo EuroPress
1. Telefon 1. Telefon
(022) 427 37 59 +48 22 877 20 80
2. Fax 2. Fax
(022) 244 24 59 22 877 20 70
3. Online 3. Online
pren@software.com.pl software@europress.pl
4. Adres 4. Adres
Software Wydawnictwo EuroPress Polska Sp. z o.o.
ul. Bokserska 1 ul. Jana Kazimierza 46/54
02-682 Warszawa 01-248 Warszawa
Prenumerujesz
– zyskujesz
l oszczędność
pieniędzy
l szybka dostawa
l prezenty
l bezpieczna płatność
on–line
Zadzwoń
0
+48 22 877 20 8
lub
zamów
mailowo!
Ilość Od
Ilość zama- numeru
Tytuł nume-
rów
wianych pisma
prenu- lub mie-
Cena
merat siąca
Software Developer’s
Journal (1 płyta DVD) 12 256
– dawniej Software 2.0 PLN
Felieton
��������
�����������
�
������������������������������������������������������ ������������������������������������������������������������
���������������������������������������������������� ��� ����������� �� ������ ���� �������������� ������ ���� ����������
����������������������������������������������������� ���� ������ ������������� ��������� ���� ���������� ���� �������� ��
��������������������������� �������������������
��������������������������������������������������������� �����������������������������������������������������������
�������������������������������������������������������������������� ���������������������������������������������������������������
��������������������������������������������������������������� ���������������������������������������������������������������
���� ������ ������������� ������� ����� ����� ��������������� ���� ������� ����� ������ ������� ������������� �� ����������� ������ ���
������������������������������������������������������������� ��������� ������� �� ������� �������� ������� �������� ���������� ���
�������������������������������������������������������������� �������� ���� ��������� ���� �������� �������������� �� �������� ���
����� ������������ ��������� ������� �������� ������ ���� �������� ���� ���� ������������ ��������� ���������� ���������� ������ ��
�������������������������������������������������������������������� ���������� ��������� ��������������������� ��������� ����
��������������������������������������������������������������� ������� ������� ���� ����������� ����������� �������� ��������������
����������������������������������������������������������������� ��������������
������������������������ ������� �� ��������� ��� ���� ������ ���� ���� ������������ �� ������
����������� ������� ������������ ������� ������� ���� �� ��� ��������������������������������������������������������������
��� ����� �� ����������� ������������ ����������� ��� ������ ��������� ��������������������������������������������������������������
��������������������������������������������������������������������� ��������� ����������� ��� ���������� �������� ���� ������������ ���
������������������������������������������������������������� ���������� ������ ��������������� �������� ���� ���������� �������� ���
��� ���� ������� ����� ������ ����� ���������� �������� ����������� ���� �����������������������������������������������������������������
��� ��������� ��������� ��������� �������� �������� ������ ����������� �������������������������������������������������������������
���� ������������ ������ �������� ������ ���������� ������ ������� ����������������������������������������������������������������
������ ������ �������� �������� ��������� ��������� ������� ������� �����������������������������������������������������������������
�������������������������������������������������������������� �������
������� ���� ������� ������� �������� �������� �������������� �� ������� �������������������������������������������������������������
������������� ������� ������� �� ������������� ������������� ����� ������������������������������������������������������������
������ ������ ����������� �� ��������������� ����������� �� ��������� ���������������������������������������������������������������
���������������������������������������������������������������� �������������������������������������������
�� 03/2010
�������
Jan, Kasia,
Dyrektor Data Center
Finansowy Manager
Robert,
Dyrektor
Techniczny
Aby dowiedzieć się, jak zwiększyć wydajność infrastruktury IT za pomocą wirtualizacji serwerów,
odwiedź stronę www.itwspierabiznes.pl