Rozdział 1 Czy Delphi jest produktem dla każdego? Średnio raz na kilka lat jedna z firm produkujących oprogramowanie wprowadza na rynek narzędzie albo technologię, która ma pomóc w tworzeniu bezbłędnego oprogramowania w rekordowo krótkim czasie. Status rewelacyjnej nowości, na której skupiało się zainteresowanie fachowców, uzyskiwały kolejno: systemy zarządzania bazami danych (DBMS), działające w oparciu o model klient - serwer, technologia CASE (ang. computer aided software engineering, komputerowo wspomagana inżynieria oprogramowania), wreszcie programowanie zorientowane obiektowo. Z kolei dziś wiele osób wiąże wielkie nadzieje z językiem Java. Powszechne jest mniemanie, że żadne pojedyncze narzędzie programistyczne nie rozwiąże wszystkich problemów związanych z tworzeniem poważnych aplikacji. Uważa się, że jeśli jakieś narzędzie pozwala na szybkie tworzenie gotowych aplikacji, to najprawdopodobniej generuje nieefektywny kod. Jeśli umożliwia wygodne komponowanie formularzy ekranowych i okien w środowisku graficznym, to zapewne nie najlepiej nadaje się do programowania na niższym poziomie. Narzędzie generujące aplikacje, działające w oparciu o model klientserwer, najprawdopodobniej nie jest w stanie bezpośrednio komunikować się z bazami danych środowiska Paradox. Te i podobne opinie są bardzo rozpowszechnione. Nie zamierzamy przekonywać nikogo, że Delphi oferuje rozwiązania wszystkich problemów, nękających twórców oprogramowania. Można natomiast zauważyć, że Delphi wyznacza zupełnie nowy kierunek rozwoju narzędzi programowania wizualnego. Delphi to pierwsze narzędzie do przyspieszonego tworzenia aplikacji (typu RAD, ang. rapid application development), wyposażone w wydajny kompilator optymalizujący kod. Jeśli dodamy do tego rozbudowane narzędzia do tworzenia i modyfikowania komponentów, komplet narzędzi internetowych i wielowarstwową architekturę baz danych, to uzyskamy obraz najpotężniejszego - jak dotąd - pakietu technologii do tworzenia oprogramowania w środowisku Windows. Być może Delphi nie jest jeszcze jedynym i wymarzonym narzędziem dla autora aplikacji pod Windows, ale stanowi rozwiązanie bardzo bliskie ideału. Mimo wszystkich swych zalet, Delphi nie wygeneruje bezbłędnego programu, jeśli sam autor nie będzie się trzymał odpowiednich reguł inżynierii oprogramowania. Delphi nie zaprojektuje aplikacji i nie zidentyfikuje potrzeb użytkownika; nie
26 Część I zastąpi programisty w pracy koncepcyjnej. Delphi jest tylko narzędziem, które robi dokładnie to, co mu się każe. Celem autora niniejszej książki było przekazanie czytelnikowi wiedzy niezbędnej do efektywnego użycia narzędzia, jakim jest Delphi, przy tworzeniu aplikacji obsługi baz danych, działających w oparciu o model klient-serwer. Dlaczego Delphi? W rozmowach na temat tworzenia aplikacji typu klient-serwer przy użyciu Delphi osoby, które nie zetknęły się z tym narzędziem, zadają często pytanie: Dlaczego właśnie Delphi?. Na rynku dostępnych jest przecież wiele dobrych narzędzi do tworzenia oprogramowania klient-serwer. Produkty takie jak PowerBuilder, Visual Basic i inne pakiety zdobyły znaczące udziały w rynku narzędzi programistycznych. Dlaczego ktokolwiek miałby zmieniać jedno z nich na Delphi? UWAGA: Wprawdzie fakt, iż jakiś produkt dobrze się sprzedaje, nie musi od razu oznaczać, że produkt ten reprezentuje wysoki poziom techniczny, jednak wiele osób uważa czynnik popularności rynkowej za decydujący wskaźnik jakości. Należy zatem nadmienić, że Delphi sprzedaje się lepiej niż Visual Basic i PowerBuilder. Na przykład w roku premiery pierwszej wersji Delphi liczba sprzedanych kopii nowego produktu przekroczyła łączną liczbę sprzedanych egzemplarzy Visual Basica i PowerBuildera. Można wskazać wiele powodów, dla których wybór Delphi jest uzasadniony. Jak już wspomniano, narzędzie to skutecznie łączy mechanizmy programowania wizualnego z kompilatorem optymalizującym kod. Nie można tego powiedzieć o większości innych narzędzi typu RAD. Należy pamiętać, że sam fakt obecności w pakiecie kompilatora, generującego kod maszynowy, nie oznacza jeszcze, iż wynikowy kod jest optymalizowany. Zarówno PowerBuilder, jak i Visual Basic w pierwotnej postaci generowały pseudo-kod. Powstałe pliki wynikowe musiały być interpretowane w trakcie wykonania. W odpowiedzi na pojawienie się Delphi firmy Microsoft i Powersoft szybko uzupełniły swoje produkty o kompilator generujący kod maszynowy. Rzecz w tym, że tłumaczenie języka Visual Basic lub PowerScript na kod maszynowy nie jest prostym zadaniem, gdyż żaden z tych języków nie był projektowany z myślą o kompilacji. Tym trudniejsza jest optymalizacja wygenerowanego kodu. Z drugiej strony, Object Pascal, używany w środowisku Delphi, od zawsze był językiem kompilowanym. Płynie stąd jeden wniosek: Delphi, jako jedyne z dostępnych obecnie narzędzi typu klient-serwer, zapewnia wydajność wymaganą
27 w najpoważniejszych zastosowaniach. Dla systemów Visual Basic i Power Builder Delphi jest tym, czym w systemie DOS były dla pakietu Clipper kompilatory języka C. Sukces Delphi spowodował, że wielu producentów narzędzi do tworzenia oprogramowania, działającego w modelu klient-serwer, pospiesznie uzupełnia swoje produkty o mechanizmy kompilacji programów do postaci kodu maszynowego. Można odnieść wrażenie, że wszyscy starają się dogonić Delphi - który z kolei jest produktem wciąż rozwijającym się. Kompilator Delphi charakteryzuje się bardzo dobrymi parametrami. Jest on najmłodszym członkiem rodziny znanych kompilatorów Pascala firmy Borland, które cieszą się zasłużoną opinią narzędzi generujących wydajne, a jednocześnie oszczędnie gospodarujące zasobami, programy wynikowe. To samo stwierdzenie prawdziwe jest także w odniesieniu do kompilatora Object Pascala, zawartego w pakiecie Delphi. W dodatku w Delphi zastosowano ten sam generator kodu, co w linii produktów Borland C++. Pozwala to uzyskać wysoką wydajność, kojarzoną zazwyczaj z językiem C, a jednocześnie uniknąć związanych z tym językiem utrudnień i komplikacji. Programistom nie wystarczy jednak samo tylko generowanie kodu maszynowego. Oczekiwania sięgają dalej i obejmują także platformę tworzenia aplikacji, która powinna być wystarczająco rozbudowana, by zaspokajała wyszukane potrzeby, ale jednocześnie nadawała się do realizacji najprostszych zadań programistycznych. Obiektowa struktura nie powinna wykluczać ewentualnego programowania fragmentów aplikacji bezpośrednio w assemblerze. Narzędzie programistyczne powinno umożliwiać generowanie plików EXE, lecz w razie potrzeby - również bibliotek DLL i sterowników (driverów). Szybkie tworzenie aplikacji do obsługi baz danych nie powinno wiązać się z koniecznością dołączania do każdego napisanego programu obszernego modułu typu database engine. Delphi spełnia wszystkie powyższe oczekiwania. Można odnieść wrażenie, że produkt ten łączy w sobie najlepsze cechy wszystkich nowoczesnych narzędzi programistycznych dla środowiska Windows. Delphi oferuje obszerną bibliotekę klas obiektów, która ogranicza konieczność samodzielnego pisania kodu, występującą często w przypadku innych narzędzi. Nadal jednak możliwe jest pisanie procedur w assemblerze. Niemal każdą aplikację stworzyć można w środowisku graficznym przenosząc komponenty na formularz. Nie zamknięto jednak drogi do bezpośredniego odwoływania się do interfejsu API Windows, przechwytywania komunikatów lub komunikacji z innymi procesami. Za jednym naciśnięciem klawisza można wygenerować program typu EXE, działający w Windows; można jednak również budować biblioteki DLL, sterowniki urządzeń i aplikacje, działające w trybie znakowym. Wreszcie - mimo że Delphi jest narzędziem przeznaczonym przede wszystkim do programowania baz danych - da się przy jego użyciu stworzyć każdą aplikację - od edytora do wygaszacza ekranu. Nawet Delphi napisano przy użyciu Delphi!
28 Część I Jeśli dodamy do tego uniwersalne narzędzia i rozbudowany debugger (program uruchomieniowy), to uzyskamy pakiet niemal bezkonkurencyjny. Podsumujmy cechy Delphi decydujące o przewadze tego narzędzia nad konkurentami: kompletna biblioteka podstawowych obiektów; szybki kompilator, generujący kod maszynowy; doskonały, zintegrowany debugger; umiarkowanie rozbudowany i prosty w obsłudze mechanizm dostępu do baz danych; środowisko tworzenia aplikacji funkcjonujące w oparciu o rozbudowane narzędzia komunikacyjne. W każdej z powyższych dziedzin Delphi bądź to wykazuje znacząca przewagę technologiczną nad konkurencyjnymi narzędziami, bądź też jako jedyny pakiet oferuje tego rodzaju rozwiązania. Programowanie bez ograniczeń Dociekliwy Czytelnik, który zapoznał się z imponującą listą możliwości i zalet Delphi, zechce zapewne spytać, czego w omawianym pakiecie brakuje. Czy może zdarzyć się sytuacja, w której użytkownik Delphi natrafi na barierę nie do pokonania, wynikającą z ograniczeń wykorzystywanego narzędzia? Prawdopodobieństwo zajścia takiej sytuacji jest niewielkie. Delphi jest pakietem w pełni rozszerzalnym. Można go uzupełniać i rozbudowywać na tak wiele sposobów, że najprawdopodobniej sprosta każdemu zadaniu programistycznemu - od stworzenia aplikacji do obsługi bazy danych po konstruowanie kontrolek ActiveX. Na poniższej liście zebrano cechy Delphi, decydujące o rozszerzalności tego pakietu: bezpośredni dostęp do interfejsu API Windows; wbudowany assembler; obsługa wstawek w assemblerze; możliwość tworzenia własnych komponentów VCL i ActiveX; możliwość tworzenia bibliotek DLL i innych dodatkowych obiektów Windows; tworzenie aplikacji w architekturze wielopoziomowej; w pełni obiektowa struktura - możliwość dziedziczenia cech istniejących klas obiektów albo budowania własnych klas od podstaw.
29 Należy zwrócić uwagę, że nie wszystkie narzędzia programowania obiektowego oferują możliwości wymienione w ostatnim punkcie powyższego podsumowania. Wiele pakietów oferowanych jako zorientowane obiektowo nie spełnia ścisłych kryteriów, decydujących o zaliczeniu narzędzia do tej kategorii. Możliwość użycia danych typu obiekt nie czyni z pakietu narzędzia programowania obiektowego. Dostępne w niektórych pakietach mechanizmy programowania obiektowego oferują bardzo niską wydajność, co wyklucza ich praktyczne wykorzystanie. Aby narzędzie można było nazwać zorientowanym obiektowo, musi ono spełnić cztery podstawowe kryteria: Dziedziczenie - Na bazie istniejących typów obiektów musi dać się tworzyć nowe typy; musi się to odbywać na drodze dziedziczenia atrybutów i metod. Polimorfizm - Sposób wywołania metody obiektu nie może zależeć od rzeczywistego typu obiektu, w którym tę metodę zdefiniowano. Na przykład, metoda Show wykonuje zupełnie inne czynności przy rysowaniu przycisku ekranowego, a inne przy rysowaniu tabeli. Mimo to sposób wywołania metody jest identyczny w przypadku obu tych obiektów. Ponadto, jeśli założyć, że oba wymienione typy obiektów pochodzą od wspólnego przodka, wywołanie metody Show przodka za pośrednictwem egzemplarza (instancji) tabeli albo przycisku powinno spowodować wyświetlenie właściwego obiektu graficznego. Enkapsulacja - Dane i kod programu powinno dać się umieszczać w pojedynczych obiektach. Obiekt musi zatem zawierać elementy danych (podobnie jak rekord) i procedury (zwane metodami). Procedury zawarte w obiekcie muszą mieć automatycznie zapewniony dostęp do danych obiektu. Obiektowość jako pierwotna metoda programowania - Mechanizmy programowania obiektowego powinny być dla danego narzędzia pierwotną metodą tworzenia programu. Nie mogą być uzupełnieniem, dodanym z czasem do istniejącego już produktu. Będąc podstawową metodą tworzenia kodu, mechanizmy programowania obiektowego powinny zapewniać wydajność wystarczającą w praktycznych zastosowaniach; w przeciwnym razie należy poddać w wątpliwość jakość narzędzia, którego pierwotna i podstawowa metoda tworzenia programu nie oferuje niezbędnej wydajności. Delphi spełnia powyższe kryteria, podobnie jak C++ i inne środowiska programowania zorientowanego obiektowo. Niewiele osób pamięta, że kompilator Pascala firmy Borland był narzędziem zorientowanym obiektowo, zanim jeszcze odpowiednie mechanizmy pojawiły się w kompilatorach Microsoft C i Borland C. Mechanizmy programowania obiektowego w Delphi nie są dodatkiem, lecz podstawą dla całego środowiska. Narzędzia programowania wizualnego, o które uzupełniono pakiet, pozwalają uniknąć wielu uciążliwości, kojarzonych zazwyczaj z programowaniem zorientowanym obiektowo.
30 Część I Fakt, że Delphi pochodzi od zorientowanego obiektowo kompilatora, generującego kod maszynowy, istotnie wyróżnia ten pakiet spośród innych narzędzi typu RAD. Jak już wspomniano, Delphi wywodzi się z rodziny kompilatorów Turbo Pascala. Kompilatory Pascala firmy Borland generowały kod maszynowy i już od końca lat osiemdziesiątych oferowały mechanizmy programowania obiektowego. W Delphi technologię tę wprowadzono w świat narzędzi do przyspieszonego tworzenia aplikacji (ang. rapid application development, RAD). Na przeciwnym biegunie znajdują się Visual Basic i Power Builder, które narodziły się jako środowiska programowania wizualnego, funkcjonujące w oparciu o interpretery. Teraz autorzy usiłują przekształcić je w narzędzia programowania obiektowego i generatory kodu maszynowego. Powyższe różnice mogą mieć olbrzymie znaczenie praktyczne. Delphi jest środowiskiem zaprojektowanym od podstaw i konsekwentnie rozwijanym, co zapewnia elastyczność i szybkość. Pozostałe wymienione pakiety szybko zdobyły pozycję rynkową i dopiero teraz dopracowywane są pod względem technicznym. Czas pokaże, która z filozofii rozwoju produktu przynosi lepsze efekty. Należy jednak pamiętać, że przekształcenie interpretera, pozbawionego mechanizmów programowania obiektowego w wydajny kompilator, generujący kod maszynowy i zorientowany obiektowo, nie jest zadaniem prostym. Skalowalność Jedną z najważniejszych właściwości narzędzia działającego w oparciu o model klient-serwer jest skalowalność (ang. scalability) - zdolność do pracy zarówno z prostymi, jak i ze złożonymi bazami danych. Czy narzędzie, które dobrze działa z tabelami dbase będzie równie sprawnie funkcjonować z tabelą Sybase? Wielowarstwowa architektura baz danych czyni z Delphi narzędzie skalowalne, przewyższające pod tym względem większość innych produktów dostępnych na rynku. Do cech pakietu, decydujących o jego skalowalności, należą: obsługa tabel lokalnych oraz przechowywanych na odległych serwerach baz danych; obsługa zapytań heterogenicznych i dostęp do wielu platform zarządzania bazami danych z jednej aplikacji; niezależny od platformy dostęp do baz danych za pośrednictwem mechanizmu Borland Database Engine; ułatwia przenoszenia aplikacji między różnymi platformami systemów zarządzania bazami danych; szybkie, dedykowane drivery BDE dla większości platform typu klient-serwer; wirtualizacja obiektów typu DataSet (zbiór danych); umożliwia niezależnym producentom tworzenie własnych sterowników dostępu do baz danych, z pominięciem BDE;
31 możliwość tworzenia maksymalnie zredukowanych, nie wymagających konfiguracji, aplikacji typu klient (tzw. chudy klient ); możliwość tworzenia serwerów; pełna obsługa mechanizmów ODBC. Delphi jest zatem wyjątkowo uniwersalnym narzędziem do tworzenia aplikacji, działających w modelu klient-serwer i nadaje się zarówno do obsługi lokalnych baz danych, jak i baz na serwerze SQL. Zawartość książki Poniżej przedstawiono w skrócie zawartość kolejnych rozdziałów książki. Rozdział 2 - Szybki start,- zawiera informacje umożliwiające jak najszybsze rozpoczęcie tworzenia aplikacji do obsługi baz danych. Treść rozdziału obejmuje wyłącznie zagadnienia najbardziej podstawowe i przeznaczona jest dla osób, które chciałyby szybko wypróbować Delphi w praktyce. Rozdział 3 - Elementy składowe aplikacji - przedstawiono elementy, z których składają się aplikacje Delphi. Czytelnicy po raz pierwszy stykający się z Delphi powinni koniecznie zapoznać się z treścią tego rozdziału. Rozdział 4 - Konwencje - zawiera uwagi i wskazówki dotyczące nazewnictwa elementów programu i obiektów baz danych, a także struktury programu w języku Object Pascal. Rozdział 5 - Praktyczne wprowadzenie do języka SQL - ma charakter przewodnika po języku SQL i przeznaczony jest dla osób, które nigdy z tego języka nie korzystały, bądź też chcą odświeżyć swoją wiedzę na jego temat. Podano tutaj tylko najważniejsze informacje, pominięto natomiast nieistotne szczegóły. Rozdział 6 - Projektowanie baz danych w modelu klient-serwer - poświęcony jest teorii relacyjnych baz danych i powiązaniu elementów teorii z praktyką obsługi baz danych w Delphi. Rozdział 7 - Projektowanie aplikacji w modelu klient-serwer - dotyczy projektowania aplikacji, obsługujących bazy danych w modelu klient-serwer. Rozdziały 6 i 7 uzupełniają się wzajemnie i mogą być przydatne dla wszystkich Czytelników, poważnie zainteresowanych tworzeniem aplikacji do obsługi baz danych. Rozdział 8 - Pierwsza rzeczywista aplikacja bazy danych klient/serwer - otwiera część książki, mającą charakter samouczka. Część ta obejmuje kolejne rozdziały, do czternastego - Rentman - po narodzinach włącznie. W rozdziałach tych
32 Część I przedstawiono kolejne etapy projektowania w pełni funkcjonalnej aplikacji do obsługi bazy danych, działającej w modelu klient-serwer. Rozdział 15 - Delphi na sewerze SQL Microsoft otwiera część książki o charakterze referencyjnym. Ta część książki kończy się na rozdziale 18. Rozdział 15 poświęcony jest zagadnieniom związanym z tworzeniem aplikacji do obsługi baz danych, korzystających z serwera Microsoft SQL. Informacje zawarte w tym rozdziale okażą się zapewne przydatne dla wszystkich autorów aplikacji, komunikujących się z serwerem SQL firmy Microsoft. Rozdział 16 - Delphi w środowisku Oracle - poświęcony jest zagadnieniom związanym z tworzeniem aplikacji do obsługi baz danych Oracle. Czytelnikom, którzy po raz pierwszy stykają się z oprogramowaniem Oracle, rozdział ten posłuży za krótkie wprowadzenie w problematykę jednego z najpopularniejszych systemów do zarządzania relacyjnymi bazami danych. Doświadczeni programiści, dobrze znający Oracle, znajdą tutaj opisy najczęstszych problemów, występujących przy tworzeniu aplikacji Delphi, komunikujących się z bazami danych Oracle. Rozdział 17 - Delphi a Interbase - zawiera szczegółowe omówienie systemu zarządzania relacyjnymi bazami danych InterBase (niektóre wersje pakietu Delphi zawierają również oprogramowanie InterBase). Ten rozdział prezentuje najważniejsze cechy InterBase oraz niuanse związane ze stosowaniem Delphi razem z InterBase. Rozdział 18 - Delphi na serwerze SQL Sybase - poświęcony jest zagadnieniom związanym z tworzeniem aplikacji do obsługi baz danych, korzystających z serwera Sybase SQL. Informacje zawarte w tym rozdziale okażą się przydatne dla wszystkich autorów aplikacji, komunikujących się z serwerem Sybase SQL. Rozdział 19 - Raporty - rozpoczyna część książki poświęconą bardziej zaawansowanym zagadnieniom. Rozdział ten omawia podstawy tworzenia w Delphi raportów na postawie baz danych. Opisano tutaj metody tworzenia prostych zestawień tabelarycznych, raportów typu nadrzędny-podrzędny i raportów na podstawie tabel krzyżowych. Rozdział 20 - Reguły biznesowe na serwerze bazy danych i rozdział 21- Reguły biznesowe w aplikacjach Delphi - prezentują wybrane metody definiowania reguł przetwarzania (ang. business rules) dla aplikacji klienta i dla serwera. Rozdział 22 - Poza granice modelu dwuwarstwowego - opisuje metody tworzenia w Delphi aplikacji klient-serwer o architekturze wielowarstwowej. Rozdział 23 - Sterowanie współbieżnością poświęcony jest kontroli współbieżności w aplikacjach Delphi, przeznaczonych do obsługi baz danych. Większość potencjalnych problemów rozwiązywana jest automatycznie na poziomie serwera bazy danych i oprogramowania Borland Database Engine. Mimo
33 to autorzy rozbudowanych aplikacji typu klient-serwer powinni zwrócić uwagę na kilka zagadnień z tego obszaru. Rozdział 24 - Zaawansowane programowanie w SQL - zawiera informacje na temat zaawansowanego programowania w języku SQL. Główne tematy tego rozdziału to tworzenie procedur osadzonych i perspektyw, a także wykorzystanie procedur zdarzeń. Ponadto omówiono tutaj niektóre techniki zapisu programu w języku SQL i przedstawiono rozważania na temat filozofii projektowania baz danych. Rozdział 25 - Optymalizacja wydajności w aplikacjach typu klient/serwer - przedstawia szereg metod optymalizacji napisanych w Delphi aplikacji typu klientserwer. Zawarte w nim wskazówki dotyczą zarówno optymalizacji samych programów w Delphi, jak i obiektów serwera, do których te programy się odwołują. Rozdział 26 - Borland Database Engine (BDE) - zawiera szczegółowe omówienie pakietu Borland Database Engine; prezentowane zagadnienia obejmują bezpośrednie wywoływanie funkcji API BDE (IDAPI) oraz wykorzystywanie ich do uzupełniania standardowych funkcji, oferowanych przez komponenty Delphi. Rozdział 27 - Tworzenie własnych komponentów Delphi - omawia tworzenie własnych komponentów do obsługi baz danych - zarówno w oparciu o istniejące komponenty, jak i całkowicie od podstaw. Rozdział 28 - Przygotowanie programu instalacyjnego aplikacji - stanowi wprowadzenie w problematykę instalacji i publikacji programów stworzonych w środowisku Delphi. Przedstawiono tutaj wiele praktycznych wskazówek i ostrzeżeń. Omówiono również program instalacyjny InstallShield, dostarczany razem z Delphi. Dodatek A - Przewodnik dla użytkowników innych narzędzi - zawiera informacje, które mogą pomóc użytkownikom innych pakietów i języków, rozpoczynającym pracę z Delphi. Omówienie dotyczy środowisk PowerBuilder, Visual Basic i C++ oraz dialektów Xbase.