DESIGN
PATTERNS – CALE DE CREŞTERE A FIABILITĂŢII SOFTWARE
Ion IVAN Liviu
MIJACHE
Rezumat: Una dintre cele mai noi şi
puternice posibilităţi de creştere a fiabilităţii software este folosirea
design pattern ca modalitate de proiectare a unor aplicaţii software care să
răspundă cerinţelor crescânde de fiabilitate. Sunt prezentate concepte de bază,
efectele acestui mod de lucru şi se propun modalităţi de evaluare pentru
fiabilitate.
Cuvinte cheie: Pattern,
design, fiabilitate, enterprise applications
Software actual se confruntă cu frontiera complexităţii. Pe de-o parte se
aşteaptă ca aplicaţiile software să facă să funcţioneze, fără erori, sisteme
mari, precum si reţele de astfel de sisteme, cum sunt: reţelele electrice,
sistemele de control al traficului aerian, reţelele ale sistemelor financiare,
sisteme militare de comandă şi control, Internet. Tot al fel se aşteaptă ca
aplicaţiile software să conducă activităţile diverselor echipamente cum sunt:
monitorizarea implantului de inimă, diagnosticarea folosind instrumente
nanometrice, protezele digitale. Sistemele de dimensiuni mari, care cuprind de
la câteva sute până la câteva mii de platforme, milioane de linii de cod,
miliarde de byte de date, au devenit rapid foarte populare. Pe de altă parte de
la toate aceste sisteme se aşteaptă să funcţioneze la nivele din ce în ce mai
înalte de fiabilitate, securitate şi siguranţă. Aceste două caracteristici - creşterea rapidă a dimensiunilor şi a
complexităţii – sunt cauzele principale pentru problemele actuale ale
dezvoltatorilor de sisteme şi aplicaţii software. De aici apar cele mai multe
erori şi aici trebuie îmbunătăţit procesul de dezvoltare a aplicaţiilor
software.
- Fiabilitatea Software
În continuare se va face referire
la aplicaţiile informatice cu caracter economic, dedicate structurilor
organizaţionale orientate spre producţie şi servicii Enterprise Applications -
EA. Acum când aplicaţiile Web influenţează totul, începând cu experienţa
clienţilor până la relaţia cu vânzătorii, fiabilitatea sistemelor informatice
ale organizaţiilor sunt în creştere, devenind critice pentru companii, clienţi,
şi parteneri de afaceri. Pentru că o cădere a unei aplicaţii va duce la o
afacere pierdută şi la costuri semnificative de reparare, şi pentru că Internet
este întotdeauna deschis pentru afaceri, companiile solicită ca fiabilitatea
EA, să fie de 24 de ore timp de 7 zile. Internet a făcut din informaţie şi în
mod imediat şi din accesarea fără eroare a acesteia bunul cel mai valoros
pentru o companie.
EA reprezintă o colecţie de
hardware, servicii ale sistemului de operare, componente software, şi de cele
mai multe ori procese umane care sunt concepute pentru a colabora în scopul
asigurării serviciului de procesare aşteptat. Fiabilitatea întregii aplicaţii
depinde foarte mult de fiabilitatea fiecărei componente. Pentru că toate
componentele dintr-un sistem sunt în strânsă legătură, o cădere a unei
componente va afecta fiabilitatea altora.
Căderile aplicaţiilor survin în
urma a mai multe aspecte dintre care amintim:
Ø testare inadecvată,
Ø probleme ale schimbării
managementului,
Ø erori de operare,
Ø cod slab calitativ,
Ø lipsa unui proces de
asigurare a calităţii,
Ø interacţiuni cu servicii
sau aplicaţii externe,
Ø condiţii de operare
diferite - grade de folosire mai mari, supraîncărcare ,
Ø evenimente întâmplătoare
- căderi de securitate,
Ø căderi hardware - hard-disk-uri,
echipamente de reţea, servere, surse de energie, memorie, CPU,
Ø probleme legate de mediu -
energia, răcirea, focul, praf, dezastre naturale.
Pe scurt fiabilitatea software se referă la cât de bine o aplicaţie asigură
cu acurateţe, fără eroare, conform serviciul care a fost definit în
specificaţiile funcţionale. În plus faţă de cât de mult rulează o aplicaţie
fără eroare, fiabilitatea software se mai referă şi la oferirea rezultatelor
corecte şi la detecţia şi recuperarea erorilor cu scopul de a evita căderile.
Fiabilitatea unui sistem este o măsură a abilităţii sistemului de a
funcţiona în timp fără a înregistra căderi. în funcţie de sistem, e posibil ca
fiabilitatea pe termen lung să nu reprezinte o preocupare pentru cei ce
dezvoltă sistemul. De exemplu, să considerăm un sistem de auto-aterizare.
Cerinţa de disponibilitate a sistemului este ridicată - trebuie să fie
disponibil în momentul când primeşte o cerere de aterizare. Pe de altă parte,
cerinţa de fiabilitate este destul de redusă în sensul că sistemul nu trebuie să
rămână operaţional pentru o lungă perioadă de timp. Fiabilitatea unui sistem
este măsurată în mod normal ca timpul mediu până la cădere Mean Time To Failure , durata de viaţă aşteptată a
sistemului.
MTTF = Ore de lucru
/Numărul de căderi
De exemplu dacă echipa
de design se aşteaptă ca aplicaţia să ofere o fiabilitate de o cădere la
fiecare 30 de zile de operare timp de 24 de ore pe zi, adică o cădere la
fiecare 720 de ore de funcţionare. Testarea va dovedi că aplicaţia rulează
corect timp de 1800 de ore şi înregistrează numai două căderi, rezultă că MTTF
= 1800/2 = 900 ore. Altfel spus ne vom aştepta ca aplicaţia să ruleze
aproximativ 900 de ore între două căderi succesive. În acest exemplu
fiabilitatea a depăşit parametrii din design. De aceea o noţiune importantă a
fiabilităţii software este aceea că o cădere software va apărea doar în
momentul în care aplicaţia este disponibilă şi se execută.
Consecinţele căderilor variază de la a nu
asigura serviciul, până la asigurarea unui serviciu incorect, şi până la a
genera date corupte şi a afecta stabilitatea sistemului. În timp ce unele
dintre căderi sunt doar inconveniente, alte căderi variază de la întreruperi cauzatoare
de pierdere de timp atunci când un sistem de achiziţie nu este prea solicitat
pentru a mai răspunde unei noi cereri de achiziţie, până la inconveniente
serioase cum ar fi un sistem bursier care nu mai are resurse pentru a mai
accepta o nouă autentificare şi până la
catastrofe majore în cazul căderii unui sistem de navigaţie al unei nave.
- Design Patterns
În
mod tradiţional fiabilitatea software este privită din punctul de vedere al
comportamentului produsului existent în comparaţie cu nivelurile planificate
înaintea ciclului de realizare. Căile de creştere tradiţionale vizează un
produs existent şi modificări pe acesta în vederea eliminării de erori.
Abordarea modernă a fiabilităţii vizează
definirea de tehnici şi metode care interacţionează pe toată durata proceselor
specifice ciclului de realizare asigurând ca fiecare stadiu al producţiei software
să aibă un nivel de fiabilitate ridicat. Este un mod activ de creştere a
fiabilităţii software în timpul proiectării, a codificării, respectiv în timpul
celorlalte etape ale ciclului de realizare. Nu se mai aşteaptă efectuarea
modificărilor pe un produs finit ci, se intervine în timpul procesului pentru a
utiliza astfel de resurse încât ceea ce se obţine să fie fiabil.
Software bazat pe componente este o tehnologie eficientă de creştere a
productivităţii dezvoltatorilor şi de creştere a calităţii software în general.
Din nefericire multe dintre componente nu întrunesc specificaţiile iniţiale,
chiar şi cele care sunt construite folosind arhitecturi middleware populare cum
sunt: COM+, EJB, CORBA Component Model. Motivul pentru aceasta sunt simple: modelele
pentru componente middleware furnizează numai infrastructura care formează
elementele de bază pentru construirea sistemelor software complexe. În mod
particular, designul specific al componentelor, aspectele legate de evoluţia,
configurarea, distribuţia, concurenţa, scalabilitatea componentelor nu sunt
prezentate de modelele convenţionale ale componentelor. Rezolvarea eficientă a acestor aspecte rămâne
în responsabilitatea dezvoltatorilor. Pentru crearea unei componente de succes
pe lângă rezolvarea corectă a problemei specifice, trebuie să se implementeze
complet serviciile si funcţiile necesare fiecărui model.
Design Pattern este o disciplina de rezolvare a acestor problemele software
care s-a dezvoltat în rândul comunităţii programatorilor de aplicaţii
orientate-obiect. Scopul principal al comunităţii de dezvoltatori ce folosesc
patterns este acela de a crea o literatură de bază care să îmbunătăţească
designul şi dezvoltarea în general. DP
au devenit populari odată cu descrierea unora dintre aceştia în [GoF95].
În această disciplină se utilizează
terminologia în limba engleză, pentru că dezvoltarea tehnologiilor a fost
făcută în limba engleză. Astfel termenul pattern este asimilat direct în limba
română la fel ca termenul software. Pattern este folosit pentru a desemna un
set de elemente cheie după care se pot realiza soluţii pentru o anumită clasă
de probleme similare. Formele la plural au fost asimilate tot în limba engleză.
Numele diferiţilor patterns au fost preluate tot în limba engleză pentru a se
identifica uşor cu cele din terminologia de specialitate. Desigur că se pot
adapta şi traduce denumirile, dar în acest mod s-ar crea confuzie între
denumirile în română şi cele în engleză şi de aceea am preferat adoptarea
denumirilor internaţional recunoscute.
Patterns au rădăcini în multe discipline inclusiv literatura de programare,
dar în mod special în cartea despre panificarea urbană şi arhitecturile
clădirilor[ALEX79]. El afirmă acolo că “fiecare pattern este o regulă tripartită, care exprimă relaţia între
un anume context, o problemă şi o soluţie”. Un pattern ca element de lucru
exprimă o relaţie între un anume context, un anume sistem de forţe care apar în
mod repetat în acel context şi o anume configuraţie spaţială care permite
acestor forţe să fie rezolvate. Ca element de limbaj, un pattern este o
instrucţiune, care arată cum va fi folosită în mod repetat, această
configuraţie spaţială, pentru a rezolva sistemul de forţe dat, de fiecare dată
când contextul este relevant.
Drept urmare se afirmă că din punct de vedere
software, fiecare pattern este o regulă
tripartită care exprimă o relaţie între un anume context, un anume sistem de
forţe care se manifestă în mod repetat în acel context, şi o anumită configuraţie
software care permite acestor forţe să se anuleze.
În general un pattern are patru elemente
esenţiale: numele pattern, problema, soluţia, consecinţele.
Numele
pattern este un element folosit pentru descrierea unei
probleme de design, a soluţiei, şi a consecinţelor. În general conţine unul sau
2 cuvinte. Numele pattern ne permite să sporim vocabularul de design, şi să
proiectăm la un nivel superior de abstractizare. Astfel folosirea numelui ne
permite să rezumăm o cantitate apreciabilă de informaţie în doar câteva
cuvinte, ceea ce face comunicarea cu
colegii, sau alţi designeri mult mai uşoară
Problema
descrie când se aplică pattern. Explică problema şi contextul ei. Descrie
probleme specifice de design cum sunt modul de reprezentare al algoritmilor ca
obiecte; descrie clase sau structuri de obiecte care sunt fixe ca design.
Uneori problema include o lista de condiţii care trebuiesc îndeplinite pentru a
avea sens aplicarea pattern.
Soluţia
descrie elementele care formează designul, relaţiile, responsabilităţile şi
colaborările. Soluţia nu descrie un design particular concret sau o anume
implementare, pentru că un pattern este ca un şablon care va fi aplicat în
multe situaţii diferite. În schimb pattern asigură o descriere abstractă a problemei de design şi cum se aranjează în general elementele, clase
şi obiecte, pentru rezolvarea ei.
Consecinţele
sunt rezultatul şi urmările aplicării pattern. Deşi consecinţele nu sunt
prezentate de cele mai multe ori când descriem deciziile de design, ele sunt
critice pentru evaluarea alternativelor de design precum şi a costurilor şi
beneficiilor aplicării lor. Consecinţele pentru software se referă cel mai
adesea la echilibrul spaţiu – timp. Prezintă de asemenea probleme legate de
limbaje şi implementare. Pentru că reutilizarea este un factor important în
designul software orientat obiect, consecinţele unui pattern includ impactul
asupra flexibilităţii sistemului, extensibilităţii sau a portabilităţii.
Listarea acestor consecinţe ajută şa înţelegerea şi evaluarea lor.
Numele unui DP abstractizează şi identifică
aspectele cheie ale unei structuri de design comune care face utilă crearea
unui design orientat obiect, reutilizabil. DP identifică clasele şi instanţele,
rolurile şi colaborările precum şi distribuţia responsabilităţii lor. Fiecare
DP prezintă o anumită problemă de design, şi descrie când se aplică această
soluţie în contextul constrângerilor de design existente, şi a consecinţelor
aplicării acesteia.
Un PL defineşte o colecţie de patterns şi regulile pentru combinarea lor
într-o arhitectură. Limbajele de pattern descriu framework-uri sau familii
unitare de sisteme. Un framework este un
set de clase care cooperează şi care fac posibil reutilizarea designului pentru
o anumită clasă de aplicaţii software. De exemplu un framework ajută la construirea
unor compilatoare pentru limbaje diferite şi pentru platforme ţintă diferite;
sau ajută la modelarea unor aplicaţii financiare. Un framework se customizează
pentru o aplicaţie particulară, prin crearea unor subclase specifice aplicaţiei
prin moştenirea unor clase abstracte ale framework-ului.
Deşi se numesc DPs, în realitate nu se referă
numai la design, ci vin să schimbe modul tradiţional de gândire despre analiza,
designul şi implementarea aplicaţiilor software. Pentru aceasta DPs propun
crearea de noi nivele de abstractizare. De fiecare dată când se abstractizează
ceva, se izolează practic detaliile particulare de restul problemei, cu scopul
declarat de a separa lucrurile care se schimbă de lucrurile care rămân la fel.
Astfel fiabilitatea respectivei probleme supuse abstractizării este separată în
fiabilitatea lucrurilor modificabile şi fiabilitatea lucrurilor care rămân la
fel. Se pleacă de la premisa că aducerea a cât mai multe lucruri care rămân la
fel într-o problemă anume va duce la o fiabilitate sporită. Practic părţile
care rămân fixe sunt considerate a avea o fiabilitate maximă, diferenţa fiind
făcută de părţile modificabile, care sunt considerate a avea o fiabilitate mai
mică. Cu cât rămân mai puţine astfel de părţi, şi cu cât fiabilitatea părţilor
fixe este mai mare se afirmă că fiabilitatea produsului pe ansamblu a crescut.
Un pattern se spune că este bun dacă:
Ø rezolvă o problemă: pattern prezintă o soluţie nu doar
principii abstracte sau strategii;
Ø este un concept dovedit: pattern prezintă o soluţie cu rezultate
urmărite, nu doar teorii sau speculaţii;
Ø soluţia nu este evidentă: multe dintre tehnicile de rezolvare a
problemelor - de exemplu paradigmele sau metodele de design software, încearcă
se deriveze soluţiile plecând de principii; cele mai bune patterns generează
soluţii indirecte pentru o problemă anume, abordare necesară pentru cele mai
dificile probleme de design;
Ø descrie o relaţie: patterns nu numai că descriu module, dar
descriu structuri şi mecanisme interne acestor module;
Ø are o componenta umană semnificativă: toate aplicaţiile software servesc
confortului uman şi calităţii vieţii; de aceea cei mai buni patterns se referă
explicit la utilitate şi estetică.
- Categorii de design
patterns
Au fost identificate următoarele categorii de
patterns:
Ø idiom: se referă
la modul în care este scris codul într-un limbaj particular, pentru a rezolva o
anume problemă;
Ø design specific: prezintă soluţia cu care
se vine pentru rezolvarea unei anumite problemă;
Ø design standard: se referă la modul în
care se rezolvă un anumit tip de problemă; de cele mai multe ori sunt patterns
care au devenit generali datorită reutilizării;
Ø design pattern: prezintă modul în care
se rezolvă o clasă întreagă de probleme similare; de cele mai multe ori aceştia
apar după aplicarea de mai multe ori a unui design standard, şi apoi găsirea
unui pattern comun în toate acele aplicaţii.
În [GoF95] sunt discutaţi 23 de patterns diferiţi,
clasificaţi după trei scopuri, fiecare dintre aceste scopuri referindu-se la un
anume aspect care variază: creaţional, structural şi comportamental.
Creaţional:
cum este creat un obiect. Acest lucru implică adesea izolarea detaliilor de
creare a unui obiect astfel încât codul să nu fie dependent de ce tipuri de
obiect sunt, în aşa fel încât să nu fie necesară modificarea codului când se
adaugă un nou tip de obiect. În această categorie sunt incluşi patterns
denumiţi: Singleton,
Factory Method şi Prototype
Structural:
proiectarea obiectelor pentru satisfacerea constrângerilor particulare ale
proiectului. Aceasta se referă la modul în care obiectele sunt conectate între
ele pentru ca schimbările din sistem să nu necesite schimbări ale acestor
conexiuni.
Comportamental:
obiectele care sunt responsabile cu un anume tip de acţiuni dintr-un program
. Acestea încapsulează procese care se doresc a se executa, de exemplu
interpretarea unui limbaj, răspunsul la o cerere, implementarea unui algoritm.
În această categorie sunt incluşi denumiţi: Observer
şi Visitor
Un alt criteriu
pentru clasificarea DPs, ţine cont dacă un pattern se aplică pentru clase sau
pentru obiecte. Patterns pentru clase se ocupă cu relaţiile dintre clase şi
subclasele aferente. Aceste relaţii sunt stabilite prin moştenire, aşa că sunt
statice – la momentul compilării. Patterns pentru obiecte sunt răspunzători cu
legăturile dintre obiecte, care se
modifică la momentul rulării şi sunt mult mai dinamici.
Ulterior acestei
abordari, care este considerată ca fiind definitoare pentru conceptul de design
patterns, pornind de la aceşti 23 de patterns s-au dezvoltat numeroşi alţii, din
ce in ce mai complecşi, care au fost clasificaţi în noi categorii. În ultimii
ani patterns au început sa fie clasficaţi în funcţie de scop, domeniul de
aplicabilitate şi de etapa din cadrul ciclului de dezvoltare referită. În
tabelele nr. 1, 2
şi 3 sunt
prezentaţi o suită de patterns reprezentativi, clasificaţi după aceste
categorii. Se observă includerea între aceştia a tutror celor 23 de patterns
iniţiali precum şi participarea aceestora la definirea altora.
Tabelul nr. 1 Clasificarea DPs în funcţie de scop
Scop
|
Design
Pattern
|
Descriere
|
DPs
Fundamentali
|
Abstract
Superclass
|
Asigură o
unitate conceptuală a unui set de clase
|
Delegation
|
O modalitate de
extindere si folosire a unei clase
|
|
Immutable
|
Nu permite
informaţiilor despre un obiect să fie modificate după ce acesta a fost
construit
|
|
Interface
|
Instanta unei
clase ofera servicii si date unei instantei a altei clase.
|
|
Interface and
Abstract Class
|
O clasă care
implementează o interfaţă şi extinde o clasa abstractă
|
|
Marker
Interface
|
O clasă care
implementează o interfaţă pentru a indica valoarea booleană a unui atribut al
unei alte clase
|
|
Proxy
|
O modalitate de
a accesa un obiect prin intermediul altuia
|
|
DPs
Creaţional
|
Abstract
Factory
|
O modalitate de
a crea un obiect care implementează un set de interfeţe similare.
|
Builder
|
O modalitate de
construire a unui obiect complex
|
|
Factory Method
|
Un obiect care
reprezintă date externe sau procesează evenimente externe.
|
|
Object Pool
|
Permite refolosirea
obiectelor care sunt greu de creat sau care sunt create într-un număr
limitat.
|
|
Prototype
|
Permite unui
obiect sa creeze copii ale lui însuşi
|
|
Singleton
|
Asigură
instanţierea unui singur obiect dintr-o anumită clasa
|
|
DPs de Partiţionare
|
Composite
|
Permite crearea
recursivă de obiecte similiare într-o manieră similară unui arbore
|
Filter (Pipe)
|
Permite
obiectelor sa fie conectate dinamica pentru a realiza operaţii pe şiruri de
date
|
|
Read-Only
Interface
|
Asigură
modificarea unui obiect numai de către unii dintre clienţii lui
|
|
DPs
Structural
|
Adapter
|
Implementează o
interfaţa cunoscută clienţilor săi asigurând acces la o interfaţă necunoscută
clienţilor săi
|
Bridge
|
Impelementează
abstractizările şi implementările în clase separate permiţând combinarea lor
dinamică
|
|
Cache
Management
|
Permite
accesarea rapidă a unor obiecte care în alt fel ar dura mai mult
|
|
Decorator
|
Extinde
funcţionalităţile unui obiect într-un mod transparent clienţilor săi
|
|
Dynamic Linkage
|
Permite unui
program să încarce la cerere diferite clase care implementează o interfaţă
cunoscută
|
|
Façade
|
Simplică
accesul la un set de obiecte prin intermediul unui obiect pe care toate
celelate obiecte il folosesc ca sa comunice cu setul.
|
|
Flyweight
|
Permite
partajarea unei informaţii comune între mai multe instante ale aceleiasi
clase
|
|
Iterator
|
Defineşte o
interfaţă care declară metode pentru accesul secvenţial la obiectele dintr-o
colecţie
|
|
Virtual Proxy
|
Ascunde
inexistenţa unui obiect printr-un
altul care implementează aceeaşi interfaţă permiţând intarzierea
instanţierii celui din urmă
|
|
DPs
Comportamen-
tal
|
Chain of
Responsibility
|
Permite unui
obiect transmiterea unei comenzi fără să ştie ce obiect sau ce tip de obiecte
o vor recepţiona
|
Command
|
Incapsulează
comenzile în obiecte pentru o uşoară manipulare a lor
|
|
Little Language
/ Interpreter
|
Permite
definirea unui mic limbaj care sa faciliteze rezolvarea unui set similar de
probleme
|
|
Mediator
|
Foloseşte un
obiect pentru a coordona schimbarea stărilor unor alte obiecte
|
|
Null Object
|
Defineşte o
alternativă la folosirea null pentru a indica absenţa unui obiect
|
|
Observer
|
Permite
înregistrarea dinamică de către un obiect a obiectelor care depind de el în
vederea notificării
|
|
Snapshot
|
Permite creare
de imagini ale stării unui obiect astfel încat aceasta să fie refăcută
ulterior
|
|
State
|
Incapsulează
starea unui obiect ca obiecte discrete
|
|
Strategy
|
Încapsulează
algoritmi similari în clase care sunt subclase ale unei superclase comune.
|
|
Template Method
|
O clasa abstractă
care conţine doar o parte din logica necesară realizării scopului
|
|
Visitor
|
Permite
realizarea unei anume operaţii pentru mai multe obiecte prin definirea unei
clase separate cu logica necesară realizării operaţiei.
|
|
DPs de Concurenţă
|
Asynchronous
Processing
|
Asigură o coadă
de procese pentru executarea lor asincronă.
|
Balking
|
Dacă o metodă
este apelată în momentul în care obiectul nu o poate executa atunci se
asigură ca acea metodă nu execută nimic
|
|
Double
Buffering
|
Asigură
producerea de date asincrone astfel încât acestea sa fie pregătite înainte ca
ele să fie necesare
|
|
Future
|
Incapsulează
toată logica astel încât pentru client să nu conteze daca procesarea este
sincronă sau nu
|
|
Guarded
Suspension
|
Asigură
execuţia unei metode până când este îndeplinită o condiţie
|
|
Lock Object
|
Asigură un
obiect unitar care să solicite acces unic la mai multe obiecte
|
|
Producer-Consumer
|
Coordonează
producţia şi consumarea asincronă de informaţii şi obiecte
|
|
Read/Write Lock
|
Asigură acces
concurent la citire şi acces exclusiv la scriere
|
|
Scheduler
|
Controlează
ordinea în care sunt executate metodele unui singur fir de execuţie
|
|
Single Threaded
Execution
|
Previne
apelurile concurente la o metodă să ducă la executarea concurentă a metodei
|
|
Two-Phase Termination
|
Asigură
ordonarea încheierii unui proces sau unui fir de execuţie
|
Tabelul nr. 2 Clasificarea DPs în funcţie de etapa de
dezvoltare
Etapa
|
Design
Pattern
|
Descriere
|
DPs cu Responsabilită
ţi Generale
|
Controller
|
Adaugă un
eveniment care să decupleze clasa sursa a unui eveniment de clasa sursă care
il rezolvă.
|
Creator
|
Determină care
clasă crează o instanţă a unei alte clase
|
|
Expert
|
Adaugă
responsabilitate unei clase care deţine informaţia necesară pentru realizarea
responsabilităţii
|
|
Law of Demeter
|
Daca două clase
nu trebuie să ştie de prezenţa celeilalte atunci acestea nu trebuie să
interacţioneze direct
|
|
Low
Coupling/High Cohesion
|
Permite
modificarea unei clase astfel încât sa ducă la o modificare facilă a
designului
|
|
Polymorphism
|
Permite
folosirea de metode diferite în funcţie de typul obiectului
|
|
Pure
Fabrication
|
Permite crearea
unei clase care sa nu devină greu de modificat
|
|
DPs ai
Interfetei Grafice
cu Utilizatorul
|
Conversational
Text
|
Desigunul
trebuie să admită comenzi sub formă de text
|
Direct
Manipulation
|
Permite
utilizatorului să interacţioneze cu obeictele manipuland reprezentări ale
acestora oferită de interfaţă
|
|
Ephemeral
Feedback
|
Asigură
feedback utilizatorilor despre starea muncii lor fără a interveni în fluxul
natural de muncă
|
|
Explorable
Interface
|
Designul
interfeţelor trebuie să fie indulgent cu greşelile utilizatorului
|
|
Form
|
Permite
utilizatorului să adauge date structurate sub formă de informaţii discrete
|
|
Disabled
Irrelevant Things
|
Ascunde
elementele de interfaţă care nu sunt necesare într-un anumit context
|
|
Interaction
Style
|
Mapează
modalităţile de de interacţiune oferite de interfaţă utilizatorului cu
cerinţele aplicaţiei
|
|
Limited
Selection Size
|
Evită
prezentarea de valori pentru selectare la un anumit moment în afara unui
număr maxim
|
|
Selection
|
Permite
utilizatorului să selecteze comenzi sau valori din liste
|
|
Step-by-Step
Instructions
|
Conduce
utilizatorul informândul ce urmează să facă la pasul următor
|
|
Supplementary
Window
|
Afişează o
fereastră suplimentară pentru informaţii suplimentare despre o fereastră
părinte
|
|
Window per Task
|
Fiecare acţiune
completă trebuie săă aibă o fereastră unică
|
|
DPs de
Organizare a Codului
|
Accessor Method
Name
|
Foloseste nume
si definitii de funcţii care sunt uşor de citit
|
Anonymous
Adapter
|
Foloseşte
obiectele de tratare a evenimentelor ca adaptoare anonime
|
|
Checked vs.
Unchecked Exceptions
|
Toate
excepţiile interne vor fi unchecked iar cele externe vor fi checked
|
|
Conditional
Compilation
|
Controlează
dacă un compilator intorduce sau ignoră comenzi pentru debug
|
|
Composed Method
|
Reorganizarea
unor metode care sunt prea mari ]n metode mai mici
|
|
Convert
Exceptions
|
Excepţiile
netratate în layerul curent vor fi convertite si trimise la layerul superior
|
|
Define
Constants in Interfaces
|
Se definesc
constantele în interfeţele claselor
|
|
Extend Super
|
Impelmentarea
unei metode care modifică logica unei clase parinte
|
|
Intention
Revealing Method
|
Folosirea de nume
semnificative pentru acţiuni care nu sunt executate de funcţii cu denumiri
clare
|
|
Server Socket
|
Cod standard
scris pentru a controla partea de server a unui socket
|
|
Client Socket
|
Cod standard
scris pentru a controla partea de client a unui socket
|
|
Switch
|
Selectarea
diverselor parti din cod pentru executie intr-o clauză switch
|
|
Symbolic
Constant Name
|
Folosirea de
nume simbolice pentru constante
|
|
DPs de Optimizare
a Codului
|
Double Checked
Locking
|
Evită dublarea
eforturilor de iniţializare ale unei resurse de către două fire de execuţie
|
Hashed Adapter
Objects
|
Transmite un
apel de metodă către un obiect adaptor asociat cu un obiect arbitrar
|
|
Lazy
Initialization
|
Iniţializrea
unui obiect doar în momentul în care acesta este necesar
|
|
Lookup Table
|
Evită
recalcularea unor valori prin calcularea lor iniţială şi salvarea lor
ulterioară
|
|
Loop Unrolling
|
Măreşte numărul
de operaţii efecutate într-o singură iteraţie
|
|
DPs de
Robusteţe a Codului
|
Assertion
Testing
|
Verifică dacă o
metode este conformă cu apelurile clineţilor
|
Copy Mutable
Parameters
|
Copierea unui
obiect în cazul în care se doreşte nemodificarea stării acestuia prin
modificarea lui.
|
|
Guaranteed
Cleanup
|
Asigură
terminarea unui obiect în cazul în care acesta nu execută corect terminarea
lui
|
|
Maximize
Privacy
|
Membrii
claselor trebuie să fie cât mai privaţi posibil
|
|
Return New
Objects from Accessor
|
Un obiect
returnat trebuie să fie copiat şi nu transmis prin valoare
|
|
DPs de
Testare
|
Acceptance
Testing
|
Testarea făcută
pentru a vedea dacă software livrat respectă nevoile organizaţiei pentru care
a fsot realizat
|
Black Box
Testing
|
Definirea de
teste numai pe baza cerinţele
|
|
Clean Room
Testing
|
Cei care au
proiectat sistemul nu trebuie să discute specificaţiile cu cei care
realizează testele
|
|
Integration
Testing
|
Testarea
împreuna, pentru prima dată, a
claselor dezvoltate separat
|
|
Regression
Testing
|
Retestarea unor
module pentru a observa dacă modificările au introdus noi buguri
|
|
System Testing
|
Tetstarea unui
sistem ca o entitate, într-un mediu similar cu cel în care va lucra
|
|
Unit Testing
|
Testarea
claselor individuale isolat de celelalte clase din program
|
|
White Box
Testing
|
Definirea de
teste pentru toate situaţile semnificative
|
Tabelul nr. 3 Clasificarea DPs în funcţie de domeniul de
aplicabilitate
Clasa
|
Design
Pattern
|
|
DPs de
Transacţii
|
ACID
Transaction
|
Asigură ca
rezultatul unei tranzacţii nu este inconsistent.
|
Audit Trail
|
Menţine un set
de înregistrări ale tranzacţiilor efectuate asupra unui obiect sau unui set
de obiecte
|
|
Composite
Transaction
|
Definirea de
tranzacţii complexe alcătuite din tranzactii ACID
|
|
Two Phase
Commit
|
Un obiect care
asigură că o tranzacţie complexe alcătuită din două tranzacţii ACID fie se
termină, fie eşuează
|
|
DPs de Arhitecturi
Distribuite
|
Demilitarized
Zone
|
Serverele
publice de Internet se vor lega la o reţea LAN care este conectată la
firewall şi la reţeaua Internet
|
Mobile Agent
|
Un obiect are
nevoie să acceseze volume mari de date aflate la distanţă
|
|
Object
Replication
|
Multiplicarea
unui obiect pe mai multe maşini astfel încât el să apară clienţilor ca fiind
unic
|
|
Object Request
Broker
|
O arhitectură
care permite obiectelor să facă apeluri la distanţă fără a cunoaşte detaliile
apelului
|
|
Process Pair
|
Două obiecte
care lucrează în pereche pentru ca în momentul în care unul cade celălalt să
îl repornească
|
|
Prompt Repair
|
Repararea unui
obiect care cade imediat după această cădere
|
|
Redundant
Independent Objects
|
Păstrarea unor
obiecte redundante în cazul în care una dintre masini cade
|
|
Shared Object
|
Un obiect care
va efectua logica necesară partajării unui alt obiect
|
|
DPs de
Procesare Distribuită
|
Connection
Multiplexing
|
Un obiect care
gestionează conexiunile dintre mai multe alte oiecte
|
Heartbeat
|
Transmiterea de
mesaje periodice care să confirme clientului că serverul execută acţiuni în
numele clientului
|
|
Heavyweight/Lightweight
Object
|
Proiectarea de
clienţi care sunt cât mai mici
|
|
Mailbox
|
Stocarea
mesajelor în recipiente pentru fiecare dintre destinatari
|
|
Object
Identifier
|
Fiecare obiect
trebuie să aibă un identificator unic
|
|
Protection
Proxy
|
Limitarea
accesului la un obiect furnizând alte obiecte care pe baza drepturilor de
securitate accesează un proxy
|
|
Publish-Subscribe
|
Transmiterea
fiecărui mesaj către destinatarul precizat
|
|
Registry
|
Un mecanism
care returnează un proxy la un obiect dându-i-se numele obiectului sau numele
serviciului
|
|
Retransmission
|
Reluarea
transmisiei unui mesaj până când se încheie cu succes
|
|
DPs de Concurenţă
|
Ephemeral Cache
Item
|
Folosirea unei
copii locale a unor obiecte de la surse de date aflate la distanţă
|
Deep
Transaction Nesting
|
Implementarea
posibilităţii de a restaura starea unui obiect modificat prin folosirea de
tranzacţii imbricate
|
|
Lock File
|
Folosirea unui
fişier de blocare care să gestioneze accesul exclusiv la resurse partajate
|
|
Optimistic
Concurrency
|
Folosirea de
copii ale obiectelor pentru executarea de tranzacţii
|
|
Session Object
|
Folosirea unui
singur obiect pentru informaţiile despre o sesiune de pe server
|
|
Static Locking
Order
|
Asigură
preluarea blocării obiectelor în aceeaşi ordine pentru toate obiectele
|
|
Thread Pool
|
Refolosirea
unui fir de execuţie aflat într-un pool dacă recrearea unuia nou durează mai
mult
|
|
DPs de
Timp
|
Temporal
Property
|
Menţinerea unui
istoric al valorilor unor atribute care se modifică de-a lungul timpului
|
Time Server
|
Asigură
sincronizarea ceasurilor calculatoarelor dintr-o aplicaţie distribuită
|
|
Versioned
Object
|
Asigură
regăsirea unei stării mai vechi sau viitoare a unui obiect în funcţie de
momentul temporal
|
|
DPs de
Baze de date
|
CRUD
|
Organizarea
operaţiilor pe baza de date în operaţii de Creare, Selectare, Modificare,
Ştergere (Create, Retrieve, Update and Delete)
|
isDirty
|
Evitarea
modificării unor date din baza de date care nu necesită acest lucru
|
|
Lazy Retrieval
|
Amânarea
aducerii de atribute din baza de date pentru obiecte complexe până în
momentul în care acestea sunt necesare
|
|
Persistence
Layer
|
Menţine
independenţa aplicaţiei faţă de baza de date
|
|
Stale Object
|
Folosirea
informaţiilor despre ultima stare a unui obiect cu atribute aduse din baza de
date pentru operaţii cu versiunea actuală a obiectului
|
|
Type Conversion
|
Organizarea
metodelor de conversie a tipurilor de date în clase de conversie
|
4.
Descrierea design pattern
Pentru descrierea unui DP se vor folosi atât
metodele grafice cât şi cele descriptive. Metodele grafice deşi sunt importante
şi utile nu sunt suficiente deoarece prezintă produsul final al designului ca
relaţie între clase şi obiecte. Pentru reutilizarea designului, trebuie
înregistrate deciziile, alternativele, şi consecinţele care au condus la
alegerea acestuia. Exemplele concrete sunt şi ele importante pentru că ajută la
înţelegerea designului prezentând modul cum acesta este folosit în producţie.
Descrierea fiecărui DP trebuie împărţită în
secţiuni după următorul model, care face ca deciziile de alegerea a acestora să
fie mai uşoare, mai uşor de citit, înţeles, învăţat, comparat şi folosit.
Ø
Numele
Pattern şi clasificarea: numele pattern rezumă în unu, două cuvinte esenţa
unui pattern. Un nume bine ales este vital, pentru că va deveni parte a
vocabularului de design.
Ø
Scopul:
rezumă
răspunsul la următoarele întrebări: Ce face respectivul design pattern? Care îi
sunt raţiunile şi scopul? Ce problemă particulară de design este rezolvată prin
respectivul pattern?
Ø
Pseudonim: alt nume sub care
mai este cunoscut pattern, în cazul în care există
Ø
Motivaţia:
un
scenariu care ilustrează o problemă de design şi modul în care clasele sau
obiectele se structurează în cadrul pattern pentru soluţionarea problemei.
Scenariul ajută la înţelegerea descrieri care urmează şi care este mai
abstractă.
Ø
Aplicabilitatea:
răspunde
la următoarele întrebări: Care sunt situaţiile în care design pattern se aplică
? Care sunt exemplele de design mai slab pe care pattern le rezolvă ? Cum sunt
recunoscute aceste situaţii?
Ø
Structura:
o
reprezentare grafică a claselor din pattern folosind o notaţie bazată pe OMT – Object Modeling Technique. Se
folosesc de asemenea diagrame de interacţiune, pentru a ilustra secvenţele de
cereri şi colaborările dintre obiecte.
Ø
Participanţii:
clasele
şi/sau obiectele participante la design pattern şi responsabilităţile lor.
Ø
Colaborare:
prezintă
modul în care participanţii colaborează între ei pentru rezolvarea
responsabilităţilor.
Ø
Consecinţe:
ilustrează
cum îşi suportă pattern obiectivele, care sunt consecinţele şi rezultatele
folosirii patterns şi care sunt aspectele din structura sistemului care variază
independent.
Ø
Implementări:
se
referă la tehnicile, şi sugestiile care trebuiesc ştiute pentru implementarea
pattern, precum şi la problemele specifice unui sau altuia dintre limbajele de
programare.
Ø
Exemple
de cod: sunt fragmente de cod care ilustrează cum va fi implementat pattern în
diverse limbaje.
Ø
Utilizări
cunoscute: se referă la
exemple de patterns care sunt regăsiţi în sisteme reale.
Ø
Relaţii
cu alţi patterns: identifică alţi patterns care sunt foarte legaţi de
cel în cauză; care sunt diferenţele importante; cu care dintre ceilalţi
patterns vor fi aceştia din urmă folosiţi.
5.
Concluzii
Conform unui studiu al grupului Gartner [Will00], se apreciază ca piaţa
pentru componentele prefabricate a crescut de la 1,4 miliarde USD în 1997 la
aproape 8 miliarde USD in 2002. Tot în acest studiu se aprecaiză că un procent
de 70 % din aplicaţiile software nou create
vor fi asamblate din componente până în 2003. Acelaşi studiu afirmă că
piaţa componetelor va deveni domeniul cel mai activ din cadrul pieţei de
software. Windows 2000 şi mai nou Windows Server 2003 şi EJB – Enterprise Java
Beans sunt platforme mature care suportă EA scalabile bazate pe componete. În
următorii ani, majoritatea aplicaţiilor nou create vor fi livrate pentru aceste
platforme, şi în ambele cazuri folosirea componentelor este obligatorie din
punct de vedere tehnic. Iată de ce folosirea unor componente care să fie în
prealabil fiabile duce către o fiabilitate mult sporită a aplicaţiilor. DPs
sunt cheia atât pentru realizarea acestor componente cât şi pentru asamblarea
acestora în aplicaţii.
Bibliografie
1.
[GoF95] E. GAMMA, R. Helm, R. Johnson, and J. Vlissides, “Design Patterns: Elements of Reusable Object-Oriented
Software”. Reading, MA: Addison-Wesley, 1995.
2. [ECKE03] B.
ECKEL, “Thinking in Patterns”, Revision 0.9, 20-05-2003, MindView, Inc.
3. [COPE01] J.W. COOPER “Design Patterns and Object Oriented Programming in Visual Basic 6 and VB.NET ”, IBM Thomas J Watson Research Center January 14,
2001
4. [SHAL01]
A. SHALLOWAY, J.R. Trott – “Design Patterns Explained – A New perspective On
Object Oriented Design” , 2001
5. [ALEX79]
ALEXANDER, C., Ishikawa, S., Silverstein, M., “The
Timeless Way of Building”, New York: Oxford University Press, 1979.
6. [LYU96] LYU, R., M., ed. "Handbook of Software Reliability
Engineering", IEEE Computer Society Press 50 years of service , Los Alamitos, CA.; Computing McGraw-Hill, 1996
7.
[WILL00]
WILLIAMS J D, “Raising Components”, Application Development
Trends, vol. 7, no.9, Sep 2000, pp.27--32.
8.
[FOWL02]
FOWLER Martin, RICE David, FOEMMEL Matthew, HIEATT Edward, MEE Robert, STAFFORD Randy - “Patterns of Enterprise Application
Architecture” - Addison-Wesley Pub Co, November , 2002
Anexa nr 1 -
Lista de acronime
1. P – Pattern = prezintă modul în care se rezolvă
o clasă întreagă de probleme similare
2. DP – Design
Pattern = prezintă
modul în care se rezolvă o clasă întreagă de probleme similare de proiectare software
3. DPs – Design
Patterns = mulţimea de design pattern
4. PL – Pattern
language = limbaj de design
DESIGN
PATTERNS – CALE DE CREŞTERE A FIABILITĂŢII SOFTWARE
Ion IVAN Liviu
Mijache
Rezumat: Una dintre cele mai noi şi
puternice posibilităţi de creştere a fiabilităţii software este folosirea
design pattern ca modalitate de proiectare a unor aplicaţii software care să
răspundă cerinţelor crescânde de fiabilitate. Sunt prezentate concepte de bază,
efectele acestui mod de lucru şi se propun modalităţi de evaluare pentru
fiabilitate.
Cuvinte cheie: Pattern,
design, fiabilitate, enterprise applications
Software actual se confruntă cu frontiera complexităţii. Pe de-o parte se
aşteaptă ca aplicaţiile software să facă să funcţioneze, fără erori, sisteme
mari, precum si reţele de astfel de sisteme, cum sunt: reţelele electrice,
sistemele de control al traficului aerian, reţelele ale sistemelor financiare,
sisteme militare de comandă şi control, Internet. Tot al fel se aşteaptă ca
aplicaţiile software să conducă activităţile diverselor echipamente cum sunt:
monitorizarea implantului de inimă, diagnosticarea folosind instrumente
nanometrice, protezele digitale. Sistemele de dimensiuni mari, care cuprind de
la câteva sute până la câteva mii de platforme, milioane de linii de cod,
miliarde de byte de date, au devenit rapid foarte populare. Pe de altă parte de
la toate aceste sisteme se aşteaptă să funcţioneze la nivele din ce în ce mai
înalte de fiabilitate, securitate şi siguranţă. Aceste două caracteristici - creşterea rapidă a dimensiunilor şi a
complexităţii – sunt cauzele principale pentru problemele actuale ale
dezvoltatorilor de sisteme şi aplicaţii software. De aici apar cele mai multe
erori şi aici trebuie îmbunătăţit procesul de dezvoltare a aplicaţiilor
software.
- Fiabilitatea Software
În continuare se va face referire
la aplicaţiile informatice cu caracter economic, dedicate structurilor
organizaţionale orientate spre producţie şi servicii Enterprise Applications -
EA. Acum când aplicaţiile Web influenţează totul, începând cu experienţa
clienţilor până la relaţia cu vânzătorii, fiabilitatea sistemelor informatice
ale organizaţiilor sunt în creştere, devenind critice pentru companii, clienţi,
şi parteneri de afaceri. Pentru că o cădere a unei aplicaţii va duce la o
afacere pierdută şi la costuri semnificative de reparare, şi pentru că Internet
este întotdeauna deschis pentru afaceri, companiile solicită ca fiabilitatea
EA, să fie de 24 de ore timp de 7 zile. Internet a făcut din informaţie şi în
mod imediat şi din accesarea fără eroare a acesteia bunul cel mai valoros
pentru o companie.
EA reprezintă o colecţie de
hardware, servicii ale sistemului de operare, componente software, şi de cele
mai multe ori procese umane care sunt concepute pentru a colabora în scopul
asigurării serviciului de procesare aşteptat. Fiabilitatea întregii aplicaţii
depinde foarte mult de fiabilitatea fiecărei componente. Pentru că toate
componentele dintr-un sistem sunt în strânsă legătură, o cădere a unei
componente va afecta fiabilitatea altora.
Căderile aplicaţiilor survin în
urma a mai multe aspecte dintre care amintim:
Ø testare inadecvată,
Ø probleme ale schimbării
managementului,
Ø erori de operare,
Ø cod slab calitativ,
Ø lipsa unui proces de
asigurare a calităţii,
Ø interacţiuni cu servicii
sau aplicaţii externe,
Ø condiţii de operare
diferite - grade de folosire mai mari, supraîncărcare ,
Ø evenimente întâmplătoare
- căderi de securitate,
Ø căderi hardware - hard-disk-uri,
echipamente de reţea, servere, surse de energie, memorie, CPU,
Ø probleme legate de mediu -
energia, răcirea, focul, praf, dezastre naturale.
Pe scurt fiabilitatea software se referă la cât de bine o aplicaţie asigură
cu acurateţe, fără eroare, conform serviciul care a fost definit în
specificaţiile funcţionale. În plus faţă de cât de mult rulează o aplicaţie
fără eroare, fiabilitatea software se mai referă şi la oferirea rezultatelor
corecte şi la detecţia şi recuperarea erorilor cu scopul de a evita căderile.
Fiabilitatea unui sistem este o măsură a abilităţii sistemului de a
funcţiona în timp fără a înregistra căderi. în funcţie de sistem, e posibil ca
fiabilitatea pe termen lung să nu reprezinte o preocupare pentru cei ce
dezvoltă sistemul. De exemplu, să considerăm un sistem de auto-aterizare.
Cerinţa de disponibilitate a sistemului este ridicată - trebuie să fie
disponibil în momentul când primeşte o cerere de aterizare. Pe de altă parte,
cerinţa de fiabilitate este destul de redusă în sensul că sistemul nu trebuie să
rămână operaţional pentru o lungă perioadă de timp. Fiabilitatea unui sistem
este măsurată în mod normal ca timpul mediu până la cădere Mean Time To Failure , durata de viaţă aşteptată a
sistemului.
MTTF = Ore de lucru
/Numărul de căderi
De exemplu dacă echipa
de design se aşteaptă ca aplicaţia să ofere o fiabilitate de o cădere la
fiecare 30 de zile de operare timp de 24 de ore pe zi, adică o cădere la
fiecare 720 de ore de funcţionare. Testarea va dovedi că aplicaţia rulează
corect timp de 1800 de ore şi înregistrează numai două căderi, rezultă că MTTF
= 1800/2 = 900 ore. Altfel spus ne vom aştepta ca aplicaţia să ruleze
aproximativ 900 de ore între două căderi succesive. În acest exemplu
fiabilitatea a depăşit parametrii din design. De aceea o noţiune importantă a
fiabilităţii software este aceea că o cădere software va apărea doar în
momentul în care aplicaţia este disponibilă şi se execută.
Consecinţele căderilor variază de la a nu
asigura serviciul, până la asigurarea unui serviciu incorect, şi până la a
genera date corupte şi a afecta stabilitatea sistemului. În timp ce unele
dintre căderi sunt doar inconveniente, alte căderi variază de la întreruperi cauzatoare
de pierdere de timp atunci când un sistem de achiziţie nu este prea solicitat
pentru a mai răspunde unei noi cereri de achiziţie, până la inconveniente
serioase cum ar fi un sistem bursier care nu mai are resurse pentru a mai
accepta o nouă autentificare şi până la
catastrofe majore în cazul căderii unui sistem de navigaţie al unei nave.
- Design Patterns
În
mod tradiţional fiabilitatea software este privită din punctul de vedere al
comportamentului produsului existent în comparaţie cu nivelurile planificate
înaintea ciclului de realizare. Căile de creştere tradiţionale vizează un
produs existent şi modificări pe acesta în vederea eliminării de erori.
Abordarea modernă a fiabilităţii vizează
definirea de tehnici şi metode care interacţionează pe toată durata proceselor
specifice ciclului de realizare asigurând ca fiecare stadiu al producţiei software
să aibă un nivel de fiabilitate ridicat. Este un mod activ de creştere a
fiabilităţii software în timpul proiectării, a codificării, respectiv în timpul
celorlalte etape ale ciclului de realizare. Nu se mai aşteaptă efectuarea
modificărilor pe un produs finit ci, se intervine în timpul procesului pentru a
utiliza astfel de resurse încât ceea ce se obţine să fie fiabil.
Software bazat pe componente este o tehnologie eficientă de creştere a
productivităţii dezvoltatorilor şi de creştere a calităţii software în general.
Din nefericire multe dintre componente nu întrunesc specificaţiile iniţiale,
chiar şi cele care sunt construite folosind arhitecturi middleware populare cum
sunt: COM+, EJB, CORBA Component Model. Motivul pentru aceasta sunt simple: modelele
pentru componente middleware furnizează numai infrastructura care formează
elementele de bază pentru construirea sistemelor software complexe. În mod
particular, designul specific al componentelor, aspectele legate de evoluţia,
configurarea, distribuţia, concurenţa, scalabilitatea componentelor nu sunt
prezentate de modelele convenţionale ale componentelor. Rezolvarea eficientă a acestor aspecte rămâne
în responsabilitatea dezvoltatorilor. Pentru crearea unei componente de succes
pe lângă rezolvarea corectă a problemei specifice, trebuie să se implementeze
complet serviciile si funcţiile necesare fiecărui model.
Design Pattern este o disciplina de rezolvare a acestor problemele software
care s-a dezvoltat în rândul comunităţii programatorilor de aplicaţii
orientate-obiect. Scopul principal al comunităţii de dezvoltatori ce folosesc
patterns este acela de a crea o literatură de bază care să îmbunătăţească
designul şi dezvoltarea în general. DP
au devenit populari odată cu descrierea unora dintre aceştia în [GoF95].
În această disciplină se utilizează
terminologia în limba engleză, pentru că dezvoltarea tehnologiilor a fost
făcută în limba engleză. Astfel termenul pattern este asimilat direct în limba
română la fel ca termenul software. Pattern este folosit pentru a desemna un
set de elemente cheie după care se pot realiza soluţii pentru o anumită clasă
de probleme similare. Formele la plural au fost asimilate tot în limba engleză.
Numele diferiţilor patterns au fost preluate tot în limba engleză pentru a se
identifica uşor cu cele din terminologia de specialitate. Desigur că se pot
adapta şi traduce denumirile, dar în acest mod s-ar crea confuzie între
denumirile în română şi cele în engleză şi de aceea am preferat adoptarea
denumirilor internaţional recunoscute.
Patterns au rădăcini în multe discipline inclusiv literatura de programare,
dar în mod special în cartea despre panificarea urbană şi arhitecturile
clădirilor[ALEX79]. El afirmă acolo că “fiecare pattern este o regulă tripartită, care exprimă relaţia între
un anume context, o problemă şi o soluţie”. Un pattern ca element de lucru
exprimă o relaţie între un anume context, un anume sistem de forţe care apar în
mod repetat în acel context şi o anume configuraţie spaţială care permite
acestor forţe să fie rezolvate. Ca element de limbaj, un pattern este o
instrucţiune, care arată cum va fi folosită în mod repetat, această
configuraţie spaţială, pentru a rezolva sistemul de forţe dat, de fiecare dată
când contextul este relevant.
Drept urmare se afirmă că din punct de vedere
software, fiecare pattern este o regulă
tripartită care exprimă o relaţie între un anume context, un anume sistem de
forţe care se manifestă în mod repetat în acel context, şi o anumită configuraţie
software care permite acestor forţe să se anuleze.
În general un pattern are patru elemente
esenţiale: numele pattern, problema, soluţia, consecinţele.
Numele
pattern este un element folosit pentru descrierea unei
probleme de design, a soluţiei, şi a consecinţelor. În general conţine unul sau
2 cuvinte. Numele pattern ne permite să sporim vocabularul de design, şi să
proiectăm la un nivel superior de abstractizare. Astfel folosirea numelui ne
permite să rezumăm o cantitate apreciabilă de informaţie în doar câteva
cuvinte, ceea ce face comunicarea cu
colegii, sau alţi designeri mult mai uşoară
Problema
descrie când se aplică pattern. Explică problema şi contextul ei. Descrie
probleme specifice de design cum sunt modul de reprezentare al algoritmilor ca
obiecte; descrie clase sau structuri de obiecte care sunt fixe ca design.
Uneori problema include o lista de condiţii care trebuiesc îndeplinite pentru a
avea sens aplicarea pattern.
Soluţia
descrie elementele care formează designul, relaţiile, responsabilităţile şi
colaborările. Soluţia nu descrie un design particular concret sau o anume
implementare, pentru că un pattern este ca un şablon care va fi aplicat în
multe situaţii diferite. În schimb pattern asigură o descriere abstractă a problemei de design şi cum se aranjează în general elementele, clase
şi obiecte, pentru rezolvarea ei.
Consecinţele
sunt rezultatul şi urmările aplicării pattern. Deşi consecinţele nu sunt
prezentate de cele mai multe ori când descriem deciziile de design, ele sunt
critice pentru evaluarea alternativelor de design precum şi a costurilor şi
beneficiilor aplicării lor. Consecinţele pentru software se referă cel mai
adesea la echilibrul spaţiu – timp. Prezintă de asemenea probleme legate de
limbaje şi implementare. Pentru că reutilizarea este un factor important în
designul software orientat obiect, consecinţele unui pattern includ impactul
asupra flexibilităţii sistemului, extensibilităţii sau a portabilităţii.
Listarea acestor consecinţe ajută şa înţelegerea şi evaluarea lor.
Numele unui DP abstractizează şi identifică
aspectele cheie ale unei structuri de design comune care face utilă crearea
unui design orientat obiect, reutilizabil. DP identifică clasele şi instanţele,
rolurile şi colaborările precum şi distribuţia responsabilităţii lor. Fiecare
DP prezintă o anumită problemă de design, şi descrie când se aplică această
soluţie în contextul constrângerilor de design existente, şi a consecinţelor
aplicării acesteia.
Un PL defineşte o colecţie de patterns şi regulile pentru combinarea lor
într-o arhitectură. Limbajele de pattern descriu framework-uri sau familii
unitare de sisteme. Un framework este un
set de clase care cooperează şi care fac posibil reutilizarea designului pentru
o anumită clasă de aplicaţii software. De exemplu un framework ajută la construirea
unor compilatoare pentru limbaje diferite şi pentru platforme ţintă diferite;
sau ajută la modelarea unor aplicaţii financiare. Un framework se customizează
pentru o aplicaţie particulară, prin crearea unor subclase specifice aplicaţiei
prin moştenirea unor clase abstracte ale framework-ului.
Deşi se numesc DPs, în realitate nu se referă
numai la design, ci vin să schimbe modul tradiţional de gândire despre analiza,
designul şi implementarea aplicaţiilor software. Pentru aceasta DPs propun
crearea de noi nivele de abstractizare. De fiecare dată când se abstractizează
ceva, se izolează practic detaliile particulare de restul problemei, cu scopul
declarat de a separa lucrurile care se schimbă de lucrurile care rămân la fel.
Astfel fiabilitatea respectivei probleme supuse abstractizării este separată în
fiabilitatea lucrurilor modificabile şi fiabilitatea lucrurilor care rămân la
fel. Se pleacă de la premisa că aducerea a cât mai multe lucruri care rămân la
fel într-o problemă anume va duce la o fiabilitate sporită. Practic părţile
care rămân fixe sunt considerate a avea o fiabilitate maximă, diferenţa fiind
făcută de părţile modificabile, care sunt considerate a avea o fiabilitate mai
mică. Cu cât rămân mai puţine astfel de părţi, şi cu cât fiabilitatea părţilor
fixe este mai mare se afirmă că fiabilitatea produsului pe ansamblu a crescut.
Un pattern se spune că este bun dacă:
Ø rezolvă o problemă: pattern prezintă o soluţie nu doar
principii abstracte sau strategii;
Ø este un concept dovedit: pattern prezintă o soluţie cu rezultate
urmărite, nu doar teorii sau speculaţii;
Ø soluţia nu este evidentă: multe dintre tehnicile de rezolvare a
problemelor - de exemplu paradigmele sau metodele de design software, încearcă
se deriveze soluţiile plecând de principii; cele mai bune patterns generează
soluţii indirecte pentru o problemă anume, abordare necesară pentru cele mai
dificile probleme de design;
Ø descrie o relaţie: patterns nu numai că descriu module, dar
descriu structuri şi mecanisme interne acestor module;
Ø are o componenta umană semnificativă: toate aplicaţiile software servesc
confortului uman şi calităţii vieţii; de aceea cei mai buni patterns se referă
explicit la utilitate şi estetică.
- Categorii de design
patterns
Au fost identificate următoarele categorii de
patterns:
Ø idiom: se referă
la modul în care este scris codul într-un limbaj particular, pentru a rezolva o
anume problemă;
Ø design specific: prezintă soluţia cu care
se vine pentru rezolvarea unei anumite problemă;
Ø design standard: se referă la modul în
care se rezolvă un anumit tip de problemă; de cele mai multe ori sunt patterns
care au devenit generali datorită reutilizării;
Ø design pattern: prezintă modul în care
se rezolvă o clasă întreagă de probleme similare; de cele mai multe ori aceştia
apar după aplicarea de mai multe ori a unui design standard, şi apoi găsirea
unui pattern comun în toate acele aplicaţii.
În [GoF95] sunt discutaţi 23 de patterns diferiţi,
clasificaţi după trei scopuri, fiecare dintre aceste scopuri referindu-se la un
anume aspect care variază: creaţional, structural şi comportamental.
Creaţional:
cum este creat un obiect. Acest lucru implică adesea izolarea detaliilor de
creare a unui obiect astfel încât codul să nu fie dependent de ce tipuri de
obiect sunt, în aşa fel încât să nu fie necesară modificarea codului când se
adaugă un nou tip de obiect. În această categorie sunt incluşi patterns
denumiţi: Singleton,
Factory Method şi Prototype
Structural:
proiectarea obiectelor pentru satisfacerea constrângerilor particulare ale
proiectului. Aceasta se referă la modul în care obiectele sunt conectate între
ele pentru ca schimbările din sistem să nu necesite schimbări ale acestor
conexiuni.
Comportamental:
obiectele care sunt responsabile cu un anume tip de acţiuni dintr-un program
. Acestea încapsulează procese care se doresc a se executa, de exemplu
interpretarea unui limbaj, răspunsul la o cerere, implementarea unui algoritm.
În această categorie sunt incluşi denumiţi: Observer
şi Visitor
Un alt criteriu
pentru clasificarea DPs, ţine cont dacă un pattern se aplică pentru clase sau
pentru obiecte. Patterns pentru clase se ocupă cu relaţiile dintre clase şi
subclasele aferente. Aceste relaţii sunt stabilite prin moştenire, aşa că sunt
statice – la momentul compilării. Patterns pentru obiecte sunt răspunzători cu
legăturile dintre obiecte, care se
modifică la momentul rulării şi sunt mult mai dinamici.
Ulterior acestei
abordari, care este considerată ca fiind definitoare pentru conceptul de design
patterns, pornind de la aceşti 23 de patterns s-au dezvoltat numeroşi alţii, din
ce in ce mai complecşi, care au fost clasificaţi în noi categorii. În ultimii
ani patterns au început sa fie clasficaţi în funcţie de scop, domeniul de
aplicabilitate şi de etapa din cadrul ciclului de dezvoltare referită. În
tabelele nr. 1, 2
şi 3 sunt
prezentaţi o suită de patterns reprezentativi, clasificaţi după aceste
categorii. Se observă includerea între aceştia a tutror celor 23 de patterns
iniţiali precum şi participarea aceestora la definirea altora.
Tabelul nr. 1 Clasificarea DPs în funcţie de scop
Scop
|
Design
Pattern
|
Descriere
|
DPs
Fundamentali
|
Abstract
Superclass
|
Asigură o
unitate conceptuală a unui set de clase
|
Delegation
|
O modalitate de
extindere si folosire a unei clase
|
|
Immutable
|
Nu permite
informaţiilor despre un obiect să fie modificate după ce acesta a fost
construit
|
|
Interface
|
Instanta unei
clase ofera servicii si date unei instantei a altei clase.
|
|
Interface and
Abstract Class
|
O clasă care
implementează o interfaţă şi extinde o clasa abstractă
|
|
Marker
Interface
|
O clasă care
implementează o interfaţă pentru a indica valoarea booleană a unui atribut al
unei alte clase
|
|
Proxy
|
O modalitate de
a accesa un obiect prin intermediul altuia
|
|
DPs
Creaţional
|
Abstract
Factory
|
O modalitate de
a crea un obiect care implementează un set de interfeţe similare.
|
Builder
|
O modalitate de
construire a unui obiect complex
|
|
Factory Method
|
Un obiect care
reprezintă date externe sau procesează evenimente externe.
|
|
Object Pool
|
Permite refolosirea
obiectelor care sunt greu de creat sau care sunt create într-un număr
limitat.
|
|
Prototype
|
Permite unui
obiect sa creeze copii ale lui însuşi
|
|
Singleton
|
Asigură
instanţierea unui singur obiect dintr-o anumită clasa
|
|
DPs de Partiţionare
|
Composite
|
Permite crearea
recursivă de obiecte similiare într-o manieră similară unui arbore
|
Filter (Pipe)
|
Permite
obiectelor sa fie conectate dinamica pentru a realiza operaţii pe şiruri de
date
|
|
Read-Only
Interface
|
Asigură
modificarea unui obiect numai de către unii dintre clienţii lui
|
|
DPs
Structural
|
Adapter
|
Implementează o
interfaţa cunoscută clienţilor săi asigurând acces la o interfaţă necunoscută
clienţilor săi
|
Bridge
|
Impelementează
abstractizările şi implementările în clase separate permiţând combinarea lor
dinamică
|
|
Cache
Management
|
Permite
accesarea rapidă a unor obiecte care în alt fel ar dura mai mult
|
|
Decorator
|
Extinde
funcţionalităţile unui obiect într-un mod transparent clienţilor săi
|
|
Dynamic Linkage
|
Permite unui
program să încarce la cerere diferite clase care implementează o interfaţă
cunoscută
|
|
Façade
|
Simplică
accesul la un set de obiecte prin intermediul unui obiect pe care toate
celelate obiecte il folosesc ca sa comunice cu setul.
|
|
Flyweight
|
Permite
partajarea unei informaţii comune între mai multe instante ale aceleiasi
clase
|
|
Iterator
|
Defineşte o
interfaţă care declară metode pentru accesul secvenţial la obiectele dintr-o
colecţie
|
|
Virtual Proxy
|
Ascunde
inexistenţa unui obiect printr-un
altul care implementează aceeaşi interfaţă permiţând intarzierea
instanţierii celui din urmă
|
|
DPs
Comportamen-
tal
|
Chain of
Responsibility
|
Permite unui
obiect transmiterea unei comenzi fără să ştie ce obiect sau ce tip de obiecte
o vor recepţiona
|
Command
|
Incapsulează
comenzile în obiecte pentru o uşoară manipulare a lor
|
|
Little Language
/ Interpreter
|
Permite
definirea unui mic limbaj care sa faciliteze rezolvarea unui set similar de
probleme
|
|
Mediator
|
Foloseşte un
obiect pentru a coordona schimbarea stărilor unor alte obiecte
|
|
Null Object
|
Defineşte o
alternativă la folosirea null pentru a indica absenţa unui obiect
|
|
Observer
|
Permite
înregistrarea dinamică de către un obiect a obiectelor care depind de el în
vederea notificării
|
|
Snapshot
|
Permite creare
de imagini ale stării unui obiect astfel încat aceasta să fie refăcută
ulterior
|
|
State
|
Incapsulează
starea unui obiect ca obiecte discrete
|
|
Strategy
|
Încapsulează
algoritmi similari în clase care sunt subclase ale unei superclase comune.
|
|
Template Method
|
O clasa abstractă
care conţine doar o parte din logica necesară realizării scopului
|
|
Visitor
|
Permite
realizarea unei anume operaţii pentru mai multe obiecte prin definirea unei
clase separate cu logica necesară realizării operaţiei.
|
|
DPs de Concurenţă
|
Asynchronous
Processing
|
Asigură o coadă
de procese pentru executarea lor asincronă.
|
Balking
|
Dacă o metodă
este apelată în momentul în care obiectul nu o poate executa atunci se
asigură ca acea metodă nu execută nimic
|
|
Double
Buffering
|
Asigură
producerea de date asincrone astfel încât acestea sa fie pregătite înainte ca
ele să fie necesare
|
|
Future
|
Incapsulează
toată logica astel încât pentru client să nu conteze daca procesarea este
sincronă sau nu
|
|
Guarded
Suspension
|
Asigură
execuţia unei metode până când este îndeplinită o condiţie
|
|
Lock Object
|
Asigură un
obiect unitar care să solicite acces unic la mai multe obiecte
|
|
Producer-Consumer
|
Coordonează
producţia şi consumarea asincronă de informaţii şi obiecte
|
|
Read/Write Lock
|
Asigură acces
concurent la citire şi acces exclusiv la scriere
|
|
Scheduler
|
Controlează
ordinea în care sunt executate metodele unui singur fir de execuţie
|
|
Single Threaded
Execution
|
Previne
apelurile concurente la o metodă să ducă la executarea concurentă a metodei
|
|
Two-Phase Termination
|
Asigură
ordonarea încheierii unui proces sau unui fir de execuţie
|
Tabelul nr. 2 Clasificarea DPs în funcţie de etapa de
dezvoltare
Etapa
|
Design
Pattern
|
Descriere
|
DPs cu Responsabilită
ţi Generale
|
Controller
|
Adaugă un
eveniment care să decupleze clasa sursa a unui eveniment de clasa sursă care
il rezolvă.
|
Creator
|
Determină care
clasă crează o instanţă a unei alte clase
|
|
Expert
|
Adaugă
responsabilitate unei clase care deţine informaţia necesară pentru realizarea
responsabilităţii
|
|
Law of Demeter
|
Daca două clase
nu trebuie să ştie de prezenţa celeilalte atunci acestea nu trebuie să
interacţioneze direct
|
|
Low
Coupling/High Cohesion
|
Permite
modificarea unei clase astfel încât sa ducă la o modificare facilă a
designului
|
|
Polymorphism
|
Permite
folosirea de metode diferite în funcţie de typul obiectului
|
|
Pure
Fabrication
|
Permite crearea
unei clase care sa nu devină greu de modificat
|
|
DPs ai
Interfetei Grafice
cu Utilizatorul
|
Conversational
Text
|
Desigunul
trebuie să admită comenzi sub formă de text
|
Direct
Manipulation
|
Permite
utilizatorului să interacţioneze cu obeictele manipuland reprezentări ale
acestora oferită de interfaţă
|
|
Ephemeral
Feedback
|
Asigură
feedback utilizatorilor despre starea muncii lor fără a interveni în fluxul
natural de muncă
|
|
Explorable
Interface
|
Designul
interfeţelor trebuie să fie indulgent cu greşelile utilizatorului
|
|
Form
|
Permite
utilizatorului să adauge date structurate sub formă de informaţii discrete
|
|
Disabled
Irrelevant Things
|
Ascunde
elementele de interfaţă care nu sunt necesare într-un anumit context
|
|
Interaction
Style
|
Mapează
modalităţile de de interacţiune oferite de interfaţă utilizatorului cu
cerinţele aplicaţiei
|
|
Limited
Selection Size
|
Evită
prezentarea de valori pentru selectare la un anumit moment în afara unui
număr maxim
|
|
Selection
|
Permite
utilizatorului să selecteze comenzi sau valori din liste
|
|
Step-by-Step
Instructions
|
Conduce
utilizatorul informândul ce urmează să facă la pasul următor
|
|
Supplementary
Window
|
Afişează o
fereastră suplimentară pentru informaţii suplimentare despre o fereastră
părinte
|
|
Window per Task
|
Fiecare acţiune
completă trebuie săă aibă o fereastră unică
|
|
DPs de
Organizare a Codului
|
Accessor Method
Name
|
Foloseste nume
si definitii de funcţii care sunt uşor de citit
|
Anonymous
Adapter
|
Foloseşte
obiectele de tratare a evenimentelor ca adaptoare anonime
|
|
Checked vs.
Unchecked Exceptions
|
Toate
excepţiile interne vor fi unchecked iar cele externe vor fi checked
|
|
Conditional
Compilation
|
Controlează
dacă un compilator intorduce sau ignoră comenzi pentru debug
|
|
Composed Method
|
Reorganizarea
unor metode care sunt prea mari ]n metode mai mici
|
|
Convert
Exceptions
|
Excepţiile
netratate în layerul curent vor fi convertite si trimise la layerul superior
|
|
Define
Constants in Interfaces
|
Se definesc
constantele în interfeţele claselor
|
|
Extend Super
|
Impelmentarea
unei metode care modifică logica unei clase parinte
|
|
Intention
Revealing Method
|
Folosirea de nume
semnificative pentru acţiuni care nu sunt executate de funcţii cu denumiri
clare
|
|
Server Socket
|
Cod standard
scris pentru a controla partea de server a unui socket
|
|
Client Socket
|
Cod standard
scris pentru a controla partea de client a unui socket
|
|
Switch
|
Selectarea
diverselor parti din cod pentru executie intr-o clauză switch
|
|
Symbolic
Constant Name
|
Folosirea de
nume simbolice pentru constante
|
|
DPs de Optimizare
a Codului
|
Double Checked
Locking
|
Evită dublarea
eforturilor de iniţializare ale unei resurse de către două fire de execuţie
|
Hashed Adapter
Objects
|
Transmite un
apel de metodă către un obiect adaptor asociat cu un obiect arbitrar
|
|
Lazy
Initialization
|
Iniţializrea
unui obiect doar în momentul în care acesta este necesar
|
|
Lookup Table
|
Evită
recalcularea unor valori prin calcularea lor iniţială şi salvarea lor
ulterioară
|
|
Loop Unrolling
|
Măreşte numărul
de operaţii efecutate într-o singură iteraţie
|
|
DPs de
Robusteţe a Codului
|
Assertion
Testing
|
Verifică dacă o
metode este conformă cu apelurile clineţilor
|
Copy Mutable
Parameters
|
Copierea unui
obiect în cazul în care se doreşte nemodificarea stării acestuia prin
modificarea lui.
|
|
Guaranteed
Cleanup
|
Asigură
terminarea unui obiect în cazul în care acesta nu execută corect terminarea
lui
|
|
Maximize
Privacy
|
Membrii
claselor trebuie să fie cât mai privaţi posibil
|
|
Return New
Objects from Accessor
|
Un obiect
returnat trebuie să fie copiat şi nu transmis prin valoare
|
|
DPs de
Testare
|
Acceptance
Testing
|
Testarea făcută
pentru a vedea dacă software livrat respectă nevoile organizaţiei pentru care
a fsot realizat
|
Black Box
Testing
|
Definirea de
teste numai pe baza cerinţele
|
|
Clean Room
Testing
|
Cei care au
proiectat sistemul nu trebuie să discute specificaţiile cu cei care
realizează testele
|
|
Integration
Testing
|
Testarea
împreuna, pentru prima dată, a
claselor dezvoltate separat
|
|
Regression
Testing
|
Retestarea unor
module pentru a observa dacă modificările au introdus noi buguri
|
|
System Testing
|
Tetstarea unui
sistem ca o entitate, într-un mediu similar cu cel în care va lucra
|
|
Unit Testing
|
Testarea
claselor individuale isolat de celelalte clase din program
|
|
White Box
Testing
|
Definirea de
teste pentru toate situaţile semnificative
|
Tabelul nr. 3 Clasificarea DPs în funcţie de domeniul de
aplicabilitate
Clasa
|
Design
Pattern
|
|
DPs de
Transacţii
|
ACID
Transaction
|
Asigură ca
rezultatul unei tranzacţii nu este inconsistent.
|
Audit Trail
|
Menţine un set
de înregistrări ale tranzacţiilor efectuate asupra unui obiect sau unui set
de obiecte
|
|
Composite
Transaction
|
Definirea de
tranzacţii complexe alcătuite din tranzactii ACID
|
|
Two Phase
Commit
|
Un obiect care
asigură că o tranzacţie complexe alcătuită din două tranzacţii ACID fie se
termină, fie eşuează
|
|
DPs de Arhitecturi
Distribuite
|
Demilitarized
Zone
|
Serverele
publice de Internet se vor lega la o reţea LAN care este conectată la
firewall şi la reţeaua Internet
|
Mobile Agent
|
Un obiect are
nevoie să acceseze volume mari de date aflate la distanţă
|
|
Object
Replication
|
Multiplicarea
unui obiect pe mai multe maşini astfel încât el să apară clienţilor ca fiind
unic
|
|
Object Request
Broker
|
O arhitectură
care permite obiectelor să facă apeluri la distanţă fără a cunoaşte detaliile
apelului
|
|
Process Pair
|
Două obiecte
care lucrează în pereche pentru ca în momentul în care unul cade celălalt să
îl repornească
|
|
Prompt Repair
|
Repararea unui
obiect care cade imediat după această cădere
|
|
Redundant
Independent Objects
|
Păstrarea unor
obiecte redundante în cazul în care una dintre masini cade
|
|
Shared Object
|
Un obiect care
va efectua logica necesară partajării unui alt obiect
|
|
DPs de
Procesare Distribuită
|
Connection
Multiplexing
|
Un obiect care
gestionează conexiunile dintre mai multe alte oiecte
|
Heartbeat
|
Transmiterea de
mesaje periodice care să confirme clientului că serverul execută acţiuni în
numele clientului
|
|
Heavyweight/Lightweight
Object
|
Proiectarea de
clienţi care sunt cât mai mici
|
|
Mailbox
|
Stocarea
mesajelor în recipiente pentru fiecare dintre destinatari
|
|
Object
Identifier
|
Fiecare obiect
trebuie să aibă un identificator unic
|
|
Protection
Proxy
|
Limitarea
accesului la un obiect furnizând alte obiecte care pe baza drepturilor de
securitate accesează un proxy
|
|
Publish-Subscribe
|
Transmiterea
fiecărui mesaj către destinatarul precizat
|
|
Registry
|
Un mecanism
care returnează un proxy la un obiect dându-i-se numele obiectului sau numele
serviciului
|
|
Retransmission
|
Reluarea
transmisiei unui mesaj până când se încheie cu succes
|
|
DPs de Concurenţă
|
Ephemeral Cache
Item
|
Folosirea unei
copii locale a unor obiecte de la surse de date aflate la distanţă
|
Deep
Transaction Nesting
|
Implementarea
posibilităţii de a restaura starea unui obiect modificat prin folosirea de
tranzacţii imbricate
|
|
Lock File
|
Folosirea unui
fişier de blocare care să gestioneze accesul exclusiv la resurse partajate
|
|
Optimistic
Concurrency
|
Folosirea de
copii ale obiectelor pentru executarea de tranzacţii
|
|
Session Object
|
Folosirea unui
singur obiect pentru informaţiile despre o sesiune de pe server
|
|
Static Locking
Order
|
Asigură
preluarea blocării obiectelor în aceeaşi ordine pentru toate obiectele
|
|
Thread Pool
|
Refolosirea
unui fir de execuţie aflat într-un pool dacă recrearea unuia nou durează mai
mult
|
|
DPs de
Timp
|
Temporal
Property
|
Menţinerea unui
istoric al valorilor unor atribute care se modifică de-a lungul timpului
|
Time Server
|
Asigură
sincronizarea ceasurilor calculatoarelor dintr-o aplicaţie distribuită
|
|
Versioned
Object
|
Asigură
regăsirea unei stării mai vechi sau viitoare a unui obiect în funcţie de
momentul temporal
|
|
DPs de
Baze de date
|
CRUD
|
Organizarea
operaţiilor pe baza de date în operaţii de Creare, Selectare, Modificare,
Ştergere (Create, Retrieve, Update and Delete)
|
isDirty
|
Evitarea
modificării unor date din baza de date care nu necesită acest lucru
|
|
Lazy Retrieval
|
Amânarea
aducerii de atribute din baza de date pentru obiecte complexe până în
momentul în care acestea sunt necesare
|
|
Persistence
Layer
|
Menţine
independenţa aplicaţiei faţă de baza de date
|
|
Stale Object
|
Folosirea
informaţiilor despre ultima stare a unui obiect cu atribute aduse din baza de
date pentru operaţii cu versiunea actuală a obiectului
|
|
Type Conversion
|
Organizarea
metodelor de conversie a tipurilor de date în clase de conversie
|
4.
Descrierea design pattern
Pentru descrierea unui DP se vor folosi atât
metodele grafice cât şi cele descriptive. Metodele grafice deşi sunt importante
şi utile nu sunt suficiente deoarece prezintă produsul final al designului ca
relaţie între clase şi obiecte. Pentru reutilizarea designului, trebuie
înregistrate deciziile, alternativele, şi consecinţele care au condus la
alegerea acestuia. Exemplele concrete sunt şi ele importante pentru că ajută la
înţelegerea designului prezentând modul cum acesta este folosit în producţie.
Descrierea fiecărui DP trebuie împărţită în
secţiuni după următorul model, care face ca deciziile de alegerea a acestora să
fie mai uşoare, mai uşor de citit, înţeles, învăţat, comparat şi folosit.
Ø
Numele
Pattern şi clasificarea: numele pattern rezumă în unu, două cuvinte esenţa
unui pattern. Un nume bine ales este vital, pentru că va deveni parte a
vocabularului de design.
Ø
Scopul:
rezumă
răspunsul la următoarele întrebări: Ce face respectivul design pattern? Care îi
sunt raţiunile şi scopul? Ce problemă particulară de design este rezolvată prin
respectivul pattern?
Ø
Pseudonim: alt nume sub care
mai este cunoscut pattern, în cazul în care există
Ø
Motivaţia:
un
scenariu care ilustrează o problemă de design şi modul în care clasele sau
obiectele se structurează în cadrul pattern pentru soluţionarea problemei.
Scenariul ajută la înţelegerea descrieri care urmează şi care este mai
abstractă.
Ø
Aplicabilitatea:
răspunde
la următoarele întrebări: Care sunt situaţiile în care design pattern se aplică
? Care sunt exemplele de design mai slab pe care pattern le rezolvă ? Cum sunt
recunoscute aceste situaţii?
Ø
Structura:
o
reprezentare grafică a claselor din pattern folosind o notaţie bazată pe OMT – Object Modeling Technique. Se
folosesc de asemenea diagrame de interacţiune, pentru a ilustra secvenţele de
cereri şi colaborările dintre obiecte.
Ø
Participanţii:
clasele
şi/sau obiectele participante la design pattern şi responsabilităţile lor.
Ø
Colaborare:
prezintă
modul în care participanţii colaborează între ei pentru rezolvarea
responsabilităţilor.
Ø
Consecinţe:
ilustrează
cum îşi suportă pattern obiectivele, care sunt consecinţele şi rezultatele
folosirii patterns şi care sunt aspectele din structura sistemului care variază
independent.
Ø
Implementări:
se
referă la tehnicile, şi sugestiile care trebuiesc ştiute pentru implementarea
pattern, precum şi la problemele specifice unui sau altuia dintre limbajele de
programare.
Ø
Exemple
de cod: sunt fragmente de cod care ilustrează cum va fi implementat pattern în
diverse limbaje.
Ø
Utilizări
cunoscute: se referă la
exemple de patterns care sunt regăsiţi în sisteme reale.
Ø
Relaţii
cu alţi patterns: identifică alţi patterns care sunt foarte legaţi de
cel în cauză; care sunt diferenţele importante; cu care dintre ceilalţi
patterns vor fi aceştia din urmă folosiţi.
5.
Concluzii
Conform unui studiu al grupului Gartner [Will00], se apreciază ca piaţa
pentru componentele prefabricate a crescut de la 1,4 miliarde USD în 1997 la
aproape 8 miliarde USD in 2002. Tot în acest studiu se aprecaiză că un procent
de 70 % din aplicaţiile software nou create
vor fi asamblate din componente până în 2003. Acelaşi studiu afirmă că
piaţa componetelor va deveni domeniul cel mai activ din cadrul pieţei de
software. Windows 2000 şi mai nou Windows Server 2003 şi EJB – Enterprise Java
Beans sunt platforme mature care suportă EA scalabile bazate pe componete. În
următorii ani, majoritatea aplicaţiilor nou create vor fi livrate pentru aceste
platforme, şi în ambele cazuri folosirea componentelor este obligatorie din
punct de vedere tehnic. Iată de ce folosirea unor componente care să fie în
prealabil fiabile duce către o fiabilitate mult sporită a aplicaţiilor. DPs
sunt cheia atât pentru realizarea acestor componente cât şi pentru asamblarea
acestora în aplicaţii.
Bibliografie
1.
[GoF95] E. GAMMA, R. Helm, R. Johnson, and J. Vlissides, “Design Patterns: Elements of Reusable Object-Oriented
Software”. Reading, MA: Addison-Wesley, 1995.
2. [ECKE03] B.
ECKEL, “Thinking in Patterns”, Revision 0.9, 20-05-2003, MindView, Inc.
3. [COPE01] J.W. COOPER “Design Patterns and Object Oriented Programming in Visual Basic 6 and VB.NET ”, IBM Thomas J Watson Research Center January 14,
2001
4. [SHAL01]
A. SHALLOWAY, J.R. Trott – “Design Patterns Explained – A New perspective On
Object Oriented Design” , 2001
5. [ALEX79]
ALEXANDER, C., Ishikawa, S., Silverstein, M., “The
Timeless Way of Building”, New York: Oxford University Press, 1979.
6. [LYU96] LYU, R., M., ed. "Handbook of Software Reliability
Engineering", IEEE Computer Society Press 50 years of service , Los Alamitos, CA.; Computing McGraw-Hill, 1996
7.
[WILL00]
WILLIAMS J D, “Raising Components”, Application Development
Trends, vol. 7, no.9, Sep 2000, pp.27--32.
8.
[FOWL02]
FOWLER Martin, RICE David, FOEMMEL Matthew, HIEATT Edward, MEE Robert, STAFFORD Randy - “Patterns of Enterprise Application
Architecture” - Addison-Wesley Pub Co, November , 2002
Anexa nr 1 -
Lista de acronime
1. P – Pattern = prezintă modul în care se rezolvă
o clasă întreagă de probleme similare
2. DP – Design
Pattern = prezintă
modul în care se rezolvă o clasă întreagă de probleme similare de proiectare software
3. DPs – Design
Patterns = mulţimea de design pattern
4. PL – Pattern
language = limbaj de design
************************
Materialul este referit prin:
Ion IVAN, Liviu MIJACHE - Design Patterns – cale de crestere a fiabilitatii software - Software 2003, ASE Publishing House, pp. 609-625, Bucuresti , 2003
************************
Materialul este referit prin:
Ion IVAN, Liviu MIJACHE - Design Patterns – cale de crestere a fiabilitatii software - Software 2003, ASE Publishing House, pp. 609-625, Bucuresti , 2003
No comments:
Post a Comment