background image

 

Rozdział 22 

Poza granice modelu dwuwarstwowego 

Gdy architektura klient/serwer weszła po raz pierwszy w modę, wydawało się 
w miarę pewne, że rozwój tej technologii zmierzał będzie w kierunku zapełnienia 
owej szerokiej luki, jaka istniała między kliencką a serwerową stroną „równania”. 
Reguły logiki aplikacji (business rules) można było co prawda konstruować na 
serwerze, lecz wbudowanie istniejących po stronie serwera reguł logiki aplikacji 
w realizowane po stronie klienta aplikacje okazało się trudnym zadaniem - 
zwłaszcza na wczesnym etapie rewolucji związanej z architekturą klient/serwer. 
Spodziewano się,  że pewnego dnia serwery i klienci zaczną współpracować ze 
sobą na tyle dobrze, iż ograniczenia takie zostaną pokonane i użytkownicy 
końcowi otrzymają w pełni spójne aplikacje. 

Na nieszczęście, w miarę jak coraz więcej producentów przechodziło na 
technologię klient/serwer, cel ów stawał się coraz bardziej odległy. Programiści, 
rozczarowani brakiem integracji między serwerami baz danych i narzędziami do 
programowania aplikacji, zaczęli standardowo wbudowywać reguły logiki 
aplikacji do programów. Nader często spotykało się systemy z regułami i więzami 
(constraint) umieszczonymi całkowicie po stronie klienta i z żadnymi lub 
przynajmniej niewieloma na serwerze bazy danych. 

Chociaż było to najlepszym sposobem na zaopatrywanie użytkowników 
końcowych we w pełni dopracowane aplikacje, to jego wada polegała na tym, że 
zrealizowanych po stronie klienta więzów nie było bynajmniej łatwo 
współużytkować w jednocześnie kilku narzędziach ani też przenosić na inne 
platformy tak, jak więzów po stronie serwera. W 

efekcie programiści 

implementacje tych samych reguł logiki aplikacji musieli konstruować 
wielokrotnie - dla każdego narzędzia programistycznego, jakiego używali, i dla 
każdej platformy, jaką wspierali. Ostatecznym rezultatem było mnóstwo 
straconego czasu i tyle samo błędów powstałych przy przepisywaniu reguł logiki 
aplikacji z jednego miejsca do drugiego. 

Rozwiązaniem dla problemu tego i jeszcze paru innych, których istnienia we 
wczesnym okresie rozwoju technologii klient/serwer nawet nie podejrzewano, 
okazał się model wielowarstwowy (multi-tier). Zamiast tylko dwóch poziomów - 
klienta i serwera - podejście wielowarstwowe dopuszcza ich wiele. W systemie 
wielowarstwowym pomiędzy klientem a serwerem może być kilka poziomów, 
z których każdy pełni specyficzną rolę. 

background image

642 

Część IV 

Delphi umożliwia programowanie aplikacji wielowarstwowych dzięki swym 
czterem kluczowym technologiom: 

„brokerowi zdalnych danych - Remote Data Broker, 

„brokerowi wiêzów - Constraint Broker, 

„wsparciu przetwarzania aktówkowego - Briefcase computing, 

„wsparciu dla częściowych pakietów danych - Partial data package. 

Każdą z nich omówię oddzielnie i pokażę, jak korzystać  z nich  w prawdziwych 
aplikacjach. 

Broker danych zdalnych 

Istniejąca w Delphi technologia Brokera danych zdalnych  (Remote Data Broker
pozwala budować aplikacje typu „chudego” klienta, nie wymagające wsparcia 
obsługi baz danych (database engine) i sterowników na komputerze klienta. 
Aplikacje te bowiem komunikują się poprzez sieć z 

serwerem aplikacji, 

zawierającym komponenty 

TTable

TQuery

 i 

TStoredProc

 niezbędne do 

uzyskania dostępu do serwera bazy danych. W serwerze aplikacji można 
ustanowić więzy i reguły logiki aplikacji, które mogą być współużytkowane przez 
te programy, które poprzez serwer aplikacji uzyskują dostęp do serwera bazy 
danych. Zapewnia to centralizację reguł logiki aplikacji i jednocześnie pozwala 
każdej aplikacji klienta funkcjonować tak, jakby w niej samej mieściły się reguły 
logiki aplikacji.  

UWAGA: 

Chociaż prawdą jest, że model „chudego” klienta pozwala budować aplikacje, nie 
wymagające dołączania do nich obsługi bazy danych Borlanda, to aplikacje typu 
chudego klienta wymagają jednak jakiegoś rodzaju mechanizmu do 
komunikowania się z serwerem aplikacji. Funkcja taka znajduje się w pliku 

DBCLIENT.DLL

, który trzeba dystrybuować wraz z samą aplikacją chudego 

klienta. Wydaje się, że 

DBCLIENT.DLL

 potrzebny jest tylko wtedy, gdy aplikacja 

ta dokonuje zmian w danych i zmiany te wysyła do serwera, lecz by zabezpieczyć 
się z każdej strony, najlepiej plik ten dołączać do każdej aplikacji omawianego 
typu. 

Aby zbudować Brokera danych zdalnych, należy wykonać następujące operacje: 

1. Sprawdź, czy serwer bazy danych InterBase pracuje. 

2.  Uruchom Eksplorator baz danych (Database Explorer) i zdefiniuj nowy alias 

BDE

 o nazwie 

IB

_

EMPLOYEE

, skojarzony z  bazą danych 

EMPLOYEE.GDB

background image

 Rozdział 22 Poza granice modelu dwuwarstwowego 

643

 

dostarczaną wraz z Delphi (standardowo baza ta jest w 

C:\Program 

Files\Borland\IntrBase\Examples

). 

3.  Nowy alias kliknij prawym klawiszem myszy i wybierz 

Import

 

to

 

Dictionary

Spowoduje to importowanie ograniczeń bazy danych oraz innych informacji 
słownika danych z bazy InterBase do słownika danych Delphi. 

4. Wyjdź ze Eksploratora baz danych i powróć do Delphi. 

5. Kliknij opcję menu 

File

\

New

 

Application

, aby rozpocząć nową aplikację 

Delphi. 

6. Kliknij opcję menu 

File\New

  i w oknie  dialogowym 

New

 

Items

 kliknij 

dwukrotnie opcję 

Remote

 

Data

 

Module

.  

7. W kreatorze 

Remote

 

Dataset

 

Wizard

 podaj nazwę klasy (

Class

 

Name

) dla 

Brokera danych zdalnych. 

8.  Na formularzu brokera umieść komponent 

TTabel

, komponent 

Database

 

i komponent 

Session

9. Właściwość 

AutoSessionName

 komponentu 

Session

 ustaw na 

True

10. Właściwość 

AliasName

 komponentu 

Database

 ustaw na 

IB_EMPLOYEE

a jego  właściwość 

DatabaseName

 na 

IB_EMPLOYEE

. Właściwość 

LoginPrompt

 ustaw na 

False

 i w polu edycyjnym właściwości 

Params

 wpisz 

dwa następujące parametry: 

USER NAME=SYSDBA PASSWORD= masterkey 

11. Jego właściwość 

HandleShared

 ustaw na 

True

12. Właściwość 

DatabaseName

 komponentu 

Table

 ustaw na 

IB_EMPLOYEE

a właściwość 

TableName

 na 

DEPARTMENT

13. Prawym klawiszem myszy kliknij komponent 

Table

 i 

wybierz opcję 

Export...from data module

14. Zapisz projekt na dysku. 

Unit2

 zachowaj jako 

RDB01

.

PAS

Unit1

 jako 

RDB00.PAS

, a cały projekt jako 

RDB.DPR

15. Teraz uruchom aplikację RDB, aby zarejestrować jej serwer COM. Zaraz po 

załadowaniu można ją na powrót zamknąć. 

Po utworzeniu brokera danych jesteśmy już gotowi do utworzenia korzystającej 
z niego aplikacji. Zbudujemy zatem aplikację klienta danych zdalnych (RDC, 
Remote Data Client), wykonując następujące czynności: 

1. Rozpocznij nową aplikację Delphi, klikając 

File\New Application

.  

2. Na  domyślnym formularzu umieść 

ClientDataSet

RemoteServer

 

DataSource

background image

644 

Część IV 

3.  Dodaj jeszcze do formularza komponent 

DBGrid

4. Właściwość 

ServerName

 komponentu 

RemoteServer

 ustaw na 

RDB.RemoteDataBroker

5. Właściwość 

RemoteServer

 komponentu 

ClientDataSet

 ustaw na 

RemoteServer1

, zaś jego 

ProviderName

 na 

Table1

  (

Table1

 odwołuje 

się do tablicy 

DEPARTMENT

 w naszej aplikacji RDB). 

6. Właściwość 

DataSet

 komponentu 

DataSource

 ustaw tak, by wskazywała na 

komponent 

ClientDataSet

, a 

właściwość 

DataSource

 komponentu 

DBGrid

 tak, by wskazywała 

DataSource1

7. Otwórz komponent 

ClientDataSet,

 ustawiając na 

True

 jego właściwość 

Active

.  

Powinniśmy teraz w 

DBGrid

 zobaczyć dane z tabeli DEPARTMENT. Jeśli tak, to 

nasze gratulacje - Czytelnik utworzył  właśnie Brokera danych zdalnych (Remote 
Data Broker) i  aplikację kliencką. 

Zanim pójdziemy dalej, zapamiętajmy nasz projekt na dysku. Moduł 

Unit1

 

zapiszmy jako RDC00.PAS, a projekt jako RDC.DPR („RDC” oznacza Remote 
Data Client, czyli klient danych zdalnych). 

Broker więzów 

Prócz pośredniczenia w uzyskiwaniu danych, dostępny w Delphi komponent 
modułu danych zdalnych może również pośredniczyć w realizowaniu więzów. 
Może na przykład użyć informacji o więzach, importowanych z serwera bazy 
danych, by uchronić nas przed samym nawet wysłaniem niepoprawnych danych do 
serwera. Redukuje to ruch w sieci i przyspiesza pracę aplikacji. By przekonać się, 
jak coś takiego działa, wykonajmy następujące czynności: 

1. Ponownie załaduj aplikację RDB do Delphi. 

2. Dwukrotnie klikając komponent 

Table

 wywołaj edytor pól i, aby dodać nowe 

pola, naciśnij CTRL+A. Następnie dodaj do formularza wszystkie pola tabeli 
DEPARTMENT naciskając 

OK

.  

3. Kliknij  pole 

Budget

 w edytorze pól. W Inspektorze obiektów powinieneś 

zobaczyć odpowiadający mu 

ImportedConstraint

4.  Zamknij edytor pól, zapisz aplikację i zrekompiluj ją. 

5. Następnie aplikację RDC ponownie otwórz i uruchom. 

background image

 Rozdział 22 Poza granice modelu dwuwarstwowego 

645

 

6.  Gdy aplikacja pojawi się na ekranie, zacznij redagować tabelę DEPARTMENT 

przy pomocy kontrolki 

DBGrid

 i spróbuj wprowadzić niepoprawną wartość do 

kolumny Budget (niepoprawna jest każdą wartość mniejsza od 10001). 

Zobaczymy,  że wartość ta zostanie natychmiast odrzucona, nawet bez wysyłania 
jej do serwera. Broker więzów (Constraint Broker) implementuje bowiem swą 
własną wersję więzów z serwera i przechwytuje wszystkie niepoprawne wartości 
danych jeszcze zanim zostaną wysłane do serwera. Zwróćmy uwagę na włączenie 
więzów do tekstu wyświetlonego komunikatu. 

Wsparcie dla przetwarzania aktowkówego 

Prócz pośrednictwa w przekazywaniu danych tam i z powrotem pomiędzy 
aplikacją a serwerem aplikacji, Delphi może również przechowywać dane lokalnie. 
Pozwala to na autonomiczną  (off-line) pracę z danymi z serwera, z użyciem 
techniki „aktówkowej”. By zobaczyć, jak metoda ta działa w praktyce, wykonajmy 
następujące kroki: 

1. Zakończ aplikację RDC, o ile jeszcze działa. 

2. Na głównym formularzu RDC umieść trzy komponenty 

Button

,. 

3.  Pierwszy przycisk nazwij 

btSave

, drugi 

btLoad

, trzeci 

btSend

4. Właściwość 

Caption

 przycisku 

btSave

 ustaw na ‘

&Save locally

’, 

przycisku 

btLoad

 na ‘

&Load local data

’, zaś przycisku 

btSend

 na ‘

Send 

changes to server

’. 

5.  Tak zmodyfikuj wymiary przycisków, by ich napisy widoczne były w całości. 

6. Kliknij  dwukrotnie 

bdSave

 i 

jego zdarzenie 

OnClik

 ustaw na: 

ClientDataSet1.SaveToFile(‘C:\TESTLOCAL.DAT’); 

7. Kliknij  dwukrotnie 

bdLoad

 i 

jego zdarzenie 

OnClik

 ustaw na: 

ClientDataSet1.LoadFromFile(‘C:\TESTLOCAL.DAT’); 

8. Kliknij  dwukrotnie 

bdSend

 i 

jego zdarzenie 

OnClik

 ustaw na: 

ClientDataSet1.ApplyUpdates(0); 

9.  Zapisz aplikacje na dysku, po czym uruchom ją. 

10. Gdy aplikacja ukaże się na ekranie, kliknij 

btSave

11. Następnie odszukaj aplikację RDB (która została uruchomiona przez 

mechanizm automatyzacji) i zamknij ją. Zignoruj komunikat o błędzie, który 
zostanie wyświetlony, i kliknij 

Yes

, aby zamknąć serwer aplikacji. 

background image

646 

Część IV 

12. Powróciwszy do RDC zauważysz, że możesz nadal pracować z załadowanym 

zestawem danych. Dokonaj w nich kilku zmian, a następnie zapamiętaj je 
lokalnie klikając przycisk 

btSave

.  

13. Zamknij  aplikację RDC, a następnie uruchom ją raz jeszcze. Spowoduje to 

ponowne otwarcie serwera aplikacji RDB. Zauważ,  że dokonane zmiany 
zostały utracone, ponieważ dane zostały na powrót pobrane z serwera bazy 
danych. 

14. Kliknij  przycisk 

btLoad

, aby załadować lokalną kopię danych. Teraz 

powinieneś zobaczyć swoje modyfikacje. 

15. Kliknij  przycisk 

btSend

, aby dokonane zmiany znalazły odzwierciedlenie 

w serwerze.  Jeśli teraz wyjdziesz z aplikacji i ponownie ją załadujesz, to 
spostrzeżesz,  że zmiany, które pierwotnie zapamiętane były lokalnie, zostały 
przeniesione do kopii danych na serwerze. I to jest właśnie to, co mamy na 
myśli używając metafory „aktówki” - dane mogą być początkowo zapisywane 
zewnętrznie i dopiero później, w dogodnej chwili, przenoszone, a mimo to 
przez cały czas możemy pracować z nimi w sposób ciągły. 

Częściowe pakiety danych 

Inną, wielce użyteczną cechą zaimplementowanej w Delphi technologii brokera 
danych jest możliwość  ściągania (download) do aplikacji klienckiej częściowych 
pakietów danych. Zamiast ładować cały zestaw danych rezultatu zapytania, 
projektant aplikacji może zdecydować się na pobieranie za jednym razem tylko 
małego podzbioru rekordów. Jest to szczególnie i w pierwszym rzędzie korzystne 
w tych aplikacjach, które zwykle otrzymują jedynie niewielkie zestawy danych, 
takich jak aplikacje typu pozycja główna/szczegóły (master/detail). By zobaczyć, 
jak cecha ta uwidacznia się w praktyce, wykonajmy następujące kroki: 

1. Zakończ aplikację RDC, jeśli jeszcze działa. 

2. Umieść na formularzu komponent 

TStatusBar

, który automatycznie 

„doklei” się do dolnej krawędzi formularza. 

3. Jego właściwość 

SimplePanel

 ustaw w Inspektorze obiektów na 

True

4. Kliknij  komponent 

DataSource

, a 

następnie w 

Inspektorze obiektów 

dwukrotnie jego zdarzenie 

OnDataChange

5. Do zdarzenie 

OnDataChange

 wpisz następujący kod:

 

 

With DataSource1.DataSet do 
 StatusBar1.SimpleText := 
 Format(‘%d / %d’, [RecNo, RecordCount]); 

background image

 Rozdział 22 Poza granice modelu dwuwarstwowego 

647

 

6. Właściwość 

PacketRecords

 komponentu 

ClientDataSet

 ustaw 

w Inspektorze obiektów na 

5

. Spowoduje to, że z serwera pobieranych będzie 

po pięć wierszy na raz. Ustawienie jej na 

-1

 (domyślne) spowoduje pobieranie 

wszystkich wierszy, natomiast 

0

 pobiera jedynie informacje ze słownika 

danych. 

7. Uruchom  swoją aplikację. Podczas przewijania rekordów w komponencie 

DBGrid zauważysz,  że aplikacja pobiera pięć nowych wierszy za każdym 
razem, gdy przekroczysz wielokrotność pięciu dotychczas wyświetlanych. Ten 
poziom sterowania pozwala w pełni określić, jaka część zestawu rezultatów 
będzie sprowadzana do klienta za jednym razem. Może to mieć decydujący 
wpływ na szybkość działania, zwłaszcza przy pracy z bardzo dużymi tablicami 
lub przy sięganiu do danych poprzez WAN. 

Na rysunku 22.1 pokazano, jak powinna wyglądać aplikacja RDC. 

 

 

Rysunek 22.1. 
Nasza aplikacja 
klienta danych 
zdalnych w fazie 
wykonania.