Sunteți pe pagina 1din 33

Clean Code

*de ce este mai important felul in care scriem cod decat ceea ce scriem

Ce inseamna Clean Code

Codul trebuie sa fie usor de citit


Codul trebuie sa fie usor de inteles
Codul trebuie sa fie usor de modificat

De oricine

Principii

DRY = Dont Repeat Yourself


Aplicabil ori de cate ori dam Copy / Paste unei bucati de cod
KISS = Keep It Simple and Stupid
Ori de cate ori vrem ca o metoda sa faca de toate
YAGNI = You Aint Gonna Need It
nu scriem metode ce nu sunt necesare inca (poate nu vor fi necesare niciodata)
- oarecum derivat din KISS
SOLID = Single Responsibility (SRP)
Open-closed (OCP)
Liskov substitution (LSP)
Interface segregation (ISP)
Dependency inversion
Single Responsibility Principle
-

O clasa trebuie sa aiba intotdeauna o singura responsabilitate si numai una


In caz contrar orice schimbare de specificatii va duce la inutilitatea ei si rescrierea
intregului cod

Open Close Principle


-

Clasele trebuie sa fie deschise (open) pt extensii


Dar totusi inchise (closed) pt modificari

Liskov Substitution Principle


-

Obiectele pot fi inlocuite oricand cu instante ale claselor derivate fara ca acest lucru sa
afecteze functionalitatea
Intalnita si sub denumirea de Design by Contract

Interface Segregation Principle


-

Mai multe interfete specializabile sunt oricand de preferat unei singure interfete generale
Nu riscam astfel ca prin modificarea contractului unui client sa modificam si
contractele altor clienti
Obiectele nu trebuie obligate sa implementeze metode care nu sunt utile

Dependency Inversion principle


-

O clasa trebuie sa depinda de abstractizari, niciodata de obiecte concrete


O aplicabilitate a acestui principiu este Dependency Injection ce permite cuplarea
slaba a serviciilor de clienti

Program to interfaces, not implementations


Depend on abstractions. Do not depend on concrete classes

Conventii de nume

UpperCamelCase
lowerCamelCase
System Hungarion Notation
Apps Hungarian Notation

Conventii de nume Clase

Compuse dintr-un substantiv specific, fara prefixe si sufixe inutile


Nu trebuie sa uitam de Single Responsibility Principle

Conventii de nume Metode

Trebuie sa descrie clar ce fac


Unde denumirile prost alese nu pot fi evitate (sunt generate automat de mediu) e indicat ca in
interiorul lor sa fie doar apeluri de alte metode
Daca denumirea unei metode contine o conjunctie (si, sau, ori) cel mai probabil vorbim
de 2 metode
Nu abr den met

Conventii de nume Variabile

Nu e indicat ca variabilele de tip siruri de catactere sa contina cod din alte limbaje (SQL,
CSS)
Variabilele booleane trebuie sa sune ca o intrebare la care se poate raspunde cu adevarat/fals
Boolean isTerminated = false;
Cand exista variabile complementare, numele trebuie sa fie simetrice

Reguli de scriere a codului sursa


1.
2.
3.
4.
5.

Declararea unei variabile pe fiecare linie


Blocurile de cod incep cu { si se termina cu } chiar daca avem o singura instructiune
Blocurile cu instructiuni sunt marcate si prin identare
Intre headerul functiei si acolada de deschidere a blocului functiei se pune un spatiu
Acolada de inchidere a unui corp de instructiuni este singura pe linie EXCEPTIE fac situatiile
cand avem if-else sau try-catch
6. Metodele sunt separate printr-o singura linie goala
7. Parametrii sunt separati prin virgula si spatiu
8. Operatorii sunt separati de operanzi printr-un spatiu, EXCEPTIE de la regula fac operatorii
UNARI

Reguli de Clean Code in structuri conditionale

Evitati comparatiile cu true si false


Variabilele booleane pot fi instantiate direct
Nu fiti negativisti
Folositi operatorul ternar ori de cate ori este posibil
Nu comparati direct cu stringuri, folositi enum pt situatii de genul
Constantele trebuie identificate si denumite (de obicei la inceputul claselor)
Ori de cate ori conditiile devin prea mari sunt indicate variabilele intermediare
De obicei folosirea enum denota un design gresit al claselor
Multe constante indica o nevoie de inglobare a lor intr-o tabela din baza de date

Reguli de Clean Code in metode

Orice metoda e indicat sa aiba cel mult 3 niveluri de structuri imbricate (arraw code)
Intotdeauna se va incerca iesirea din functie cat mai repede posibil (prin return sau exceptie)
Variabilele vor fi declarate cat mai aproape de utilizarea lor
Incercati pe cat posibil folosirea this si stabilirea unei conventii de nume pt parametrii
constructorului
Evitati metodele cu mai mult de 2 parametri
Evitati metodele foarte lungi ( peste 20 de linii de cod)
Complexitatea trebuie sa fie invers proportionala cu nr de linii de cod
Atentie la ordinea in care tratati exceptiile

Reguli de Clean Code in clase

Toate metodele dintr-o clasa trebuie sa aiba legatura cu acea clasa


Evitati folosirea claselor generale si mutati prelucrarile respective ca metode statice in clasele
aferente
Evitati primitivele ca parametri si folositi obiecte (clase Wrapper in Java) ori de cate ori acest
lucru este posibil.
Atentie la primitive si in cazul prelucrarilor in mai multe fire de executie
Folositi fisiere de resurse pt sirurile de caractere din GUI
Clasele ce conlucreaza vor fi asezate una langa alta pe cat posibil
Folositi-va de design patterns acolo unde situatia o cere

Reguli de Clean Code in comentarii

De cele mai multe ori acestea nu isi au deloc locul


Codul bine scris este auto-explicativ
Nu folositi comentarii pt a va cere scuze
Nu comentati codul nefolosit devine zombie
Exista solutii de versionare pt recuperarea codului modificat
Atunci cand simtiti nevoia de a folosi comentarii pt a face o metoda lizibila, cel mai probabil
acea functie trebuie separata in 2 functii
Evitati blocurile de comentarii introductive
Toate detaliile de acolo se vor gasi in solutia de versionare

Sunt indicate doar pt biblioteci ce vor fi refolosite de alti programatori (doc comments)
TODO comments

Scurt dictionar

Test Driven Development (TDD) = dezvoltare bazata pe cazuri de utilizare


Refactoring = rescrierea codului intr-o maniera ce se adapteaza mai bine noilor specificatii
Automatic Testing (Unit Testing) = Testarea automata a codului pe baza unor cazuri de
utilizare. Foarte utila in refactoring pt ca putem verifica daca am pastrat toate functionalitatile
sau nu (regression)
Code review = procedura intalnita in special in AGILE (XP, SCRUM) ce presupune ca orice
bucata de cod scrisa sa fie revizuita si de un alt programator
Pair programming = tenica specifica AGILE prin care programatorii lucreaza pe perechi pt
task-uri complexe, pt a invata sau pt a evita code review

Instrumente
IntellijIDEA, R#, ReSharper, PMD, Checkstyle, TM

Git Version Control


De ce controlul versiunilor?

Proiectele software se dezvolta in regim colaborativ, codul fiind controlat de mai multi
programatori
Ai nevoie de o solutie de back-up independenta de masina pe dezvoltare folosita
Ai nevoie de o platforma care sa permita lucru colaborativ (fiecare lucreaza pe masina locala
si apoi modificarile sunt incarcate in sistem pt a fi disponibile tutoror membrilor echipei)
Ai nevoie de o platforma care sa iti permita accesul la istoricul modificarilor
Toata lumea foloseste o solutie de control al versiunii (solutie de versionare)

Concepte

VCS = Version Control Software


SCM = Software Control Management
SCM = Source Code Management
Repository (Repo) = baza de date/imagine/colectie de fisiere din proiect
Branch = imagine locala a proiectului. Permite lucrul pe versiuni paralele fara a afecta
imaginea principala a proiectului
Stash = arhiva locala pt un set de modificari
Commit = salvare modificari pe server

Ce este Git?

An open source version control system (VCS)


A distributed version control system

A directory content management system


A tree based history storage system
A stupid content tracker

Caracteristici Git

Este un sistem distribuit


Toti au acces la istoricul modificarilor
Toti lucreaza pe masinile de dezvoltare in mod offline
Nu exista o autoritate centrala de control toti au aceleasi drepturi
Modificarile pot fi transmise si in mod P2P (peer-to-peer) fara a trece prin server
Este un sistem distribuit de control al versiunii (Distributed Version Control DVC)
Fisierele sunt urmarite prin verificarea hash-ului (SHA 1) acestora

CVC VS DVC

CVC and Subversion


- SVN
- CVS
- Alte solutii comerciale
DVC
- Mercurial
- Git
- BitKeeper
- Darc

Operatii de baza Git (VCS)

Initializare repository
git init
Adauga fisiere noi/modifica fisiere existente
Commit salveaza modificarile pe server
git commit
Istoric vizualizare istoric modificari
Share distribuie modificarile
Update actualizeaza proiectul cu ultimele modificari
Revert anuleaza modificari cu revenire la o versiune anterioara
Branch creare ramura (proiect secundar) de dezvoltare locala

Descarca proiect:
git clone

Tutorial git
1. creeaza repo local
mkdir CTSRepo
cd CTSRepo

2. initializare client Git


git init
3. configurare client
git config - -global user.name Your name here
git config - -global user.email your_email@youremail.com
4. defineste repo-ul master
git remote add origin link git
5. descarcare fisiere din repo-ul master (se creeaza o copie locala)
git clone link git
6. defineste un branch local si lucreaza pe el
git branch work
git checkout work
git rebase master
7. modifica fisiere locale si incarca-le pe server
git status
git add .
git commit a m modificari fisiere
8. treci pe branch-ul master si incarca modificarile
git checkout master
git pull
git rebase work
git push
9. treci pe branch-ul work
git checkout work

JUnit
Ce este Unit Testing?

Metoda simpla si rapida de testare a codului sursa de catre programatori


Are loc in faza de dezvoltare si este un instrument destinat programatorilor
Un unit test este o secventa de cod scrisa de un programator pt a evalua o parte bine definita,
de mici dimensiuni, din codul sursa testat clasa sau metoda
Un unit test evalueaza modul de functionare al unei metode intr-un context bine definit
Un unit test este blocul de baza pt abordarea Test-Driven Development

Ce inseamna TDSS?
= software development process that relies on the repetition of a very short development cycle: first the
developer writes an (initially failing) automated test case that define a desired improvement or new
function, than produces the minimum amount of code to pass that test, and finally refactors the new
code to acceptable standards.

Tipuri de testare a codului sursa


Acceptance testing teste realizate de client. Testeaza daca design-ul corespunde cu ceea
ce s-a dorit

System testing testarea intregului sistem (toate componentele). Testeaza daca sistemul
functioneaza conform design-ului
Integration testing testarea mai multor componente ce sunt combinate sau integrate
Unit Testing testarea celor mai mici parti din cod (clase sau metode)
Regression testing testarea automata a aplicatiei dupa implementarea unor modificari
astfel incat sa fie evitata reaparitia unor erori(bug-uri) anterioare
Block-box testing testarea interfetei publice a unor componente fara a avea informatii cu
privire la implementare, structura interna etc
White-box testing (glass-box testing) testarea unor componente despre care exista
informatii complete

Motive sa folosesti Unit Testing

Usor de scris
Testele pot fi scrise ad-hoc atunci cand ai nevoie de ele
Desi simple, pe baza lor se pot defini colectii de teste Test Suites
Pot fi rulate automat de fiecare data cand e nevoie (write once, use many times)
Exista multe framework-uri si instrumente ce simplifica procesul de scriere si rulare
Reduc timpul pierdut pt debugging si pt gasirea bug-urilor
Reduc nr de bug-uri in codul livrat sau integrat
Creste rata bug-urilor identificate in faza de scriere a codului

Ce este JUnit?
= instrument pt TDD
=framework de clase ce permite scrierea si executia de teste pt diferite metode/clase din cod

Arhitectura JUnit

TestRunner executa teste si raporteaza TestResults


Testul se scrie prin extinderea clasei abstracte TestCase
Pt a scrie teste, trebuie sa intelegi clasa Assert
Fiecare metoda de tip assert are urmatorul set de parametri: message, expected-value, actualvalue
Metodele assert pt valori reale primesc un parametru suplimentar variatia
Fiecare metoda assert are o forma echivalenta ce nu primeste parametrul de tip mesaj varianta
NU este recomandata
Mesajul metodei assert este folosit la documentarea testului si ajuta la parcurgerea logurilor asociate testelor esuate

Concepte JUnit

Fixture set de obiecte utilizate in test


TestCase clasa ce defineste setul de obiecte (fixture) pt a rula mai multe teste
SetUp metoda/etapa de definire a setului de obiecte utilizate (fixture), inainte de testare
TearDown o metoda/etapa de distrugere a obiectelor (fixture) dupa terminarea testelor
Test Suite colectie de cazuri de testare (Test Cases)
Test Runner instrument de rulare a testelor (test suite) si de afisare a rezultatelor

Caracteristici JUnit

Pachetul de functii este destul de simplu


Codul JUnit nu este livrat clientului la build/export
Testele se scriu in Java
Daca un test esueaza celelalte sunt executate in continuare
Testul are o structura simpla:
- Pregateste conditiile initiale (creare obiecte, initializare resurse)
- Apeleaza metodele ce urmeaza sa fie testate
- Verifica daca metoda functioneaza comparand rezultatele generate cu cele asteptate
- Elibereaza resursele utilizate
O metoda de testare poate contine mai multe assert-uri
Simplificarea testelor ajuta la identificarea rapida a bug-urilor
Obiectivul este de a scrie teste care esueaza astfel incat sa fie corectate erorile din timp
Testele pot fi combinate in colectii Test Suites

La JUnit 3 trebuie sa fie Test inainte de denumirea Test Case-ului

Structura Test Case


setUp()
- defineste si construieste resursele sau obiectele (fixture) necesare rularii testelor
- se apeleaza inaintea fiecarei metode de testare
- in cazul seturilor de teste, metoda poate fi una generica, executata o singura data, daca
este definita in interiorul unui TestSetup
tearDown()
- elibereaza/distruge resursele alocate testului
- se apeleaza dupa fiecare metoda de testare
- in cazul seturilor de teste, metoda poate fi una generica, executata o singura data, daca
este definita in interiorul unui TestSetup

Obiecte Mock
Descriere:

un unit test trebuie sa evalueze executia unei metode, insa uneori acest lucru necesita
obiecte/conditii externe metodei
este un testing pattern
reprezinta un inlocuitor al obiectului real

Definire:
-

obiectele mock sunt descrise prin interfata


interfata este implementata in solutia reala dar si in Unit Test

CORRECT Boundary Conditions


Conformance valoarea are formatul corect?
Ordering setul de valori trebuie sa fie ordonat sau nu?
Range este valoarea intre limitele (min si max) acceptate?

Reference codul refera componente externa care NU sunt controlate direct?


Existence valoarea exista (ex: este non-null, non-zero, parte dintr-un set etc)
Cardinality - setul de test contine suficiente valori (regula 0-1-n)?
Time (absolut si relativ) totul se intampla in ordine? La momentul potrivit? Intr-un timp
finit? (UTC vs DST)

The Right BICEP


Right. Sunt rezultatele corecte?

B. Sunt limitele (Boundary conditions) definite CORRECT?


I. Can you check Inverse relationships?
C. Se poate verifica rezultatul si prin alte metode (Cross-check)?
E. Se pot evalua (forta) conditiile care genereaza erori (Error conditions)?
P. Performanta executiei este intre limite (Performance characteristics)?

Proprietati ale testelor:


AUTOMATE pt fi rulate automat
REPETABILE pot fi rulate de nenumarate ori cu aceleasi rezultate
INDEPENDENTE independente de conditiile specifice mediului de executie si
independente de alte teste
COMPLETE testeaza tot ce poate genera erori la un moment dat
REALE sunt la fel de importante ca si codul testat; sunt tot programe si trebuie tratate ca
atare (NU sunt secvente de cod scrise pt un moment anume si apoi aruncate)

Design Pattern
Calitate cod sursa
Principii urmarite in scrierea codului:

usor de citit/inteles clar


usor de modificat structurat
usor de reutilizat
simplu (complexitate)
usor de testat
implementeaza pattern-uri pt probleme standard

Calitate cod sursa


Forte care o influenteaza:

timpul disponibil (termene de predare)


costuri
experienta programatorului
competentele programatorului

claritate specificatii
complexitate solutie
rata schimbari in specificatii, cerinte, echipa etc

Anti Pattern: Big ball of mud


De unde? De ce?

Throwaway code solutii temporare (Prototyping) ce trebuie inlocuite/rescrise


Cut and Paste code
Adaptarea prin comentare/stergere a altor solutii
Termene limita foarte scurte sau nerealiste
Lipsa de experienta
Lipsa unor standarde/proceduri

Cum eviti?

Rescrierea codului (Refactoring) pana la un nivel acceptabil de maturitate


Utilizare Principii Clean Code
Implementare Design Patterns

Design pattern

Un pattern = solutie reutilizabila pt o problema standard, intr-un anumit context


Faciliteaza reutilizarea arhitecturilor si a design-ului software
NU sunt structuri de date

Avantajele unui Design Pattern

Permit reutilizarea solutiilor standard la nivel de cod sursa/arhitectura


Permit documentarea codului sursa/arhitecturilor
Permit intelegerea mai facila a codului sursa/a arhitecturii
Reprezinta concepte universal cunoscute definesc un vocabular comun
Sunt solutii testate si foarte bine documentate

Componentele unui Design-Pattern

Nume :
Face parte din vocabularul unui programator/designer/arhitect software
Identifica in mod unic pattern-ul
Problema:
Descrie scopul urmarit
Defineste contextul
Stabileste cand este aplicabil pattern-ul
Solutie:
Diagrama UML, pseudo-cod ce descrie elementele
Consecinte:
Rezultate

Avantaje si dezavantaje

Utilizare Design Patterns

Observer in Java AWT si Swing pt callback-uri


Iterator in c++ STL si Java Collections
Faade in multe librarii Open-Source pt a ascunde complexitatea rutinelor interne
Bridge si Proxy in framework-uri pt aplicatii distribuite
Singleton in Hybernate si Nhybernate

Tipuri de Design Pattern


1. CREATIONALE
- Initializarea si configurarea claselor si obiectelor
ABSTRACT FACTORY pattern pt crearea de obiecte aflate intr-un anumit context
BUILDER pattern pt crearea in mod structurat (incremental) de obiecte complexe
FACTORY METHOD pattern ce defineste o metoda pt crearea de obiecte din aceeasi
familie (interfata) in subclase
PROTOTYPE pattern pt clonarea unor noi instante (clone) ale unui prototip existent
SINGLETON pattern pt crearea unei singure instante (unica)
2. STRUCTURALE
- Compozitia claselor si obiectelor
- Decuplarea interfetelor si a claselor
ADAPTER adapteaza interfata unui server/serviciu la client
BRIDGE decupleaza modelul abstract de implementare
COMPOSITE agregarea a mai multor obiecte similare
DECORATOR extinde intr-un mod transparent un obiect
FAADE simplifica interfata unui model/subsistem
FLYWEIGHT partajare memorie intre obiecte similare
PROXY interfata catre alte obiecte/resurse
3. COMPORTAMENTALE
- Distributia responsabilitati
- Interactiunea intre clase si obiecte
CHAIN OF RESPONSIBILITY gestioneaza tratarea unui eveniment de catre mai
multi furnizori de solutii
COMMAND Request or Action is first-class object, hence re-storable
ITERATOR gestioneaza parcurgerea unei colectii de elemente
INTERPRETER interpretor pt un limbaj cu o gramatica simpla
MEDIATOR coordoneaza interactiunea dintre mai multi asociati
MEMENTO salveaza si restaureaza starea unui obiect
OBSERVER defineste un handler pt diferite evenimente
STATE gestioneaza obiecte al caror comportament depinde de starea lor
STRATEGY incapsuleaza diferiti algoritmi
TEMPLATE METHOD incapsuleaza un algoritm ai carui pasi depind de o clasa
derivata
VISITOR descrie metode ce pot fi aplicate pe o structura neomogena

CREATIONALE
SINGLETON
Problema:

Se doreste crearea unei singure instante pt o clasa prin care sa fie gestionata o resursa/un
eveniment in mod centralizat
Solutia se bazeaza pe existenta unei singure instante ce poate fi creata o singura data, dar
care poate fi referita de mai multe ori
Asigura un singur punct de acces, vizibil global, la unica instanta
Ex: gestiune conexiune BD sau alte resurse; mecanism de logging unic; manager evenimente;
manager resurse vizuale; manager configurare

Diagrama:

Componente

Singleton() constructor privat (apelabil doar din clasa)


private static Singleton instance atribut static, privat, de tipul clasei ce reprezinta instanta
unica
Singleton getInstance()
- Metoda publica ce da acces la instanta unica
- Instanta unica este creata la primul apel al metodei

Alte implementari:
-

Varianta 1 atribut privat definit static


Varianta 2 atribut public static constant
Varianta 3 prin enumerare

Singleton collection sau singleton registry obiectele unice sunt gestionate printr-o
colectie

Avantaje si dezavantaje
Avantaje:

Gestiune centralizata a unei resurse printr-o instanta unica


Controlul strict al instantierii unei clase o singura data
Nu permite duplicarea instantelor
Usor de implementat
Lazy instantiation obiectul este creat atunci cand este necesar

Dezavantaje:
In multi-threading pot aparea probleme de sincronizare sau cooperare daca singleton-ul
este partajat
Poate deveni un bottleneck care sa afecteze performanta aplicatiei

Scenarii

Conexiune unica la baza de date


Gestiune unica fisiere/fisier de configurare
Gestiune unica preferinte pe platforma Android (SharedPreferences) sau gestiunea setarilor
aplicatiei intr-un context mai general
Gestiune unica conexiune retea
Gestiune centralizata a accesului la anumite resurse utilizate de solutia software
Gestiune unica obiecte costisitoare, pe baza timpului si a resurselor necesare crearii, ce trebuie sa
aiba o instanta unica, utilizata de mai multe ori

MODELUL FACTORY
Problema

Implementarea unui mecanism centralizat prin care crearea obiectelor este transparenta pt
client; prin interfata publica, clientul stie cum sa creeze obiecte insa nu stie cum este
implementat acest lucru
Solutia poate sa fie extinsa prin adaugarea de noi tipuri concrete de obiecte fara a afecta codul
existent
Complexitatea creaarii obiectelor este ascunsa clientului
Obiectele sunt referite printr-o interfata comuna; clase concrete reprezinta o familie de
obiecte definita in jurul interfetei comune
Eliminarea dependentei codului clientului de crearea efectiva a obiectelor utilizate in solutie

SIMPLE FACTORY

Este un caz particular al pattern-ului Factory

Unul dintre cele mai folosite in productie datorita simplitatii in implementare si a avantajelor
oferite
NU este scris in cartea celor 4 (GoF), el aparand natural, din practica

Diagrama

Componente
InterfataProdus interfata abstracta a obiectelor de tip Produs
Produs tipurile concrete de clase ce implementeaza interfata; instantele acestei clase
vor fi generate de catre Factory
Factory clasa ce incapsuleaza procesul de creare a obiectelor de tip InterfaceProdus
Client alta clasa sau o metoda, care foloseste interfata Factory-ului pt a construi obiecte
noi

MODELUL FACTORY METHOD (Virtual


Constructor)

Componente:

InterfataProdus interfata ce defineste tipurile generice de obiecte ce pot fi create


Produs clasa concreta ce defineste tipul de obiecte ce poate fi creat
Factory clasa abstracta ce defineste interfata unui generator de obiecte
FactoryConcretA, FactoryConcretB - clasa concreta ce implementeaza generatorul
de obiecte

Avantaje si dezavantaje
Avantaje:
Toate obiectele create au in comun interfata
Controlul strict al instantierii obiectele nu sunt create direct prin constructori ci prin
metoda de tip factory
Diferitele tipuri de obiecte sunt gestionate unitar prin interfata comuna noi tipuri, din
aceeasi familie, pot fi adaugate fara modificari
Usor de implementat
Pot fi generate obiecte noi care apartin aceleiasi familii (interfata comuna)
Implementeaza principiul Dependency Inversion
Dezavantaje:
Nu pot fi generate obiecte noi
Constructorii sunt privati clasele nu pot fi extinse

MODELUL ABSTRACT FACTORY


Problema:

Se doreste implementarea unui mecanism prin care crearea obiectelor este transparenta pt client
Solutia poate sa fie extinsa prin adaugarea de noi tipuri concrete de obiecte fara a afecta codul
scris
Complexitatea crearii obiectelor este ascunsa clientului. Acesta stie cum sa le creeze insa nu stie
cum acestea sunt efectiv create
Crearea obiectelor este decuplata de solutie si generatorul poate fi inlocuit fara prea mare ajutor
Obiectele sunt referite printr-o interfata comuna si nu direct. Ele formeaza o familie de obiecte in
jurul interfetei comune

Diagrama

Componente

InterfataFactory interfata ce defineste metodele abstracte pt crearea de instante


InterfataProdusA/InterfataProdusB interfete ce definesc tipurile abstracte de obiecte ce pot
fi create
FactoryConcretA/FactoryConcretB clase concrete ce implementeaza interfata si metodele
prin care sunt create obiecte de tipul Product
ProdusTipA, ProdusTipB,.. clase concrete ce definesc diferitele tipuri de obiecte ce pot fi
create

Avantaje si dezavantaje
Avantaje:

Decupleaza generatorul de instante de clientul care le utilizeaza


Controlul strict al instantierii obiectele nu sunt create direct prin constructori ci prin metode
de tip factory
Diferitele tipuri de obiecte sunt gestionate unitar prin interfata comuna noi tipuri pot fi
adaugare fara modificari

Dezavantaje:

Nr mare de clase implicate


Nivel de complexitate ridicat

Scenarii

Gestiune creare produse catalog magazine virtuale


Gestiune creare tipuri diferite de client
Gestiune creare tipuri diferite de rapoarte
Gestiune creare tipuri de nr de telefon

Gestiune creare tipuri de conturi bancare


Gestiune creare tipuri de pizza
Gestiune creare meniuri intr-un restaurant

Factory
Toate pattern-urile Factory promoveaza loose coopling si sunt bazate pe Dependency
Inversion Principle
Factory Method
- Bazata pe mostenire crearea obiectelor este realizata de subclase ce implementeaza
metoda factory
- Are scopul de a delega crearea obiectelor catre subclase
AbstractFactory
- Bazata pe compunere crearea obiectelor este realizata prin metode publice de
interfata
- Are scopul de a crea familii de obiecte fara a depinde de implementarea lor concreta

MODELUL BUILDER
Problema:

Solutia trebuie sa construiasca obiecte complexe printr-un mecanism care este independent de
procesul de realizare a obiectelor
Clientul construieste obiecte complexe specificand doar tipul si valoarea sa, fara a cunoaste
detaliile interne ale obiectului (cum stocheaza si reprezinta valorile)
Procesul de construire a obiectelor trebuie sa poata fi utilizat pt a defini obiecte diferite din aceeasi
familie
Obiectele sunt gestionate prin interfata comuna
Instanta de tip Builder construieste obiectul insa tipul acestuia este definit de subclase

Avantaje si dezavantaje
Avantaje:

Obiectele complexe pot fi create independent de partile care il compun (un obiect poate sa le
contina pe toate sau doar o parte)
Sistemul permite reprezentarea diferita a obiectelor create printr-o interfata comuna
Algoritmul de creare a obiectului este flexibil deoarece clientul alege ce parti sa fie create

Dezavantaje:

Atentie la crearea de obiecte pot fi omise atribute

MODELUL PROTOTYPE
Scenariu:
ACME Inc doreste sa dezvolte un joc 3D pt dispozitive Android utilizand un engine propriu. Cele 2
modele 3D pt caractere sunt destul de complexe si generarea lor are impact asupra timpului de procesare
si implicit asupra duratei de viata a acumulatorului. Acelasi model este utilizat de mai multe ori pt a
popula o scena cu personaje. Trebuie gasita o solutie eficienta prin care scenele sa fie incarcate rapid.

Problema

Solutia genereaza obiecte costisitoare (timp creare si memorie ocupata) cu durata de viata lunga
Pt eficienta, solutia reutilizeaza obiectul prin clonarea acestuia (se creeaza o instanta noua a
obiectului)
Implementat prin metoda clone()

Diagrama

Avantaje si dezavantaje
Avantaje:
Creare rapida de obiecte identice (valori) prin clonare

Evita apelul explicit al constructorului


Poate fi construita o colectie de prototipuri care sa fie utilizata pt a genera obiecte noi
Dezavantaje:
Atentie la crearea de obiecte ce partajeaza aceleasi resurse shallow copy

STRUCTURAL DESIGN PATTERN


MODELUL ADAPTER (Wrapper)
Scenariu:
ACME INC doreste sa cumpere un nou framework pentru serviciile din back end . Interfata pt aceste
servicii gestioneaza datele prin intermediul obiectelor de tip ACME, iar noul framework proceseaza
datele prin intermediul obiectelor de tip MICRO. Programatorii companiei trebuie sa gaseasca o solutie
de a integra cele 2 framework-uri fara a le modifica.
Problema
Utilizarea impreuna a unor clase ce nu au o interfata comuna
Clasele nu se modifica insa se construieste o interfata ce permite utilizarea lor in alt context
Clasele sunt adaptate la un nou context
Apelurile catre interfata clasei sunt mascate de interfata adaptorului
Transformarea datelor dintr-un format in altul

Componente:
ClasaExistena clasa existenta ce trebuie adaptata la o noua interfata
ClasaContextNou defineste interfata specifica noului domeniu
Adaptor

- Adapteaza interfata clasei existente la cea a clasei din noul context


- Contine (composition) o referinta catre clasa/obiectul ce trebuie adaptat
Client reprezinta framework-ul care apeleaza interfata specifica noului domeniu

Avantaje si dezavantaje
Avantaje

Clasele existente (la client si la furnizor) nu sunt modificate pt a putea fi folosite intr-un alt
context
Se adauga doar un layer intermediar
Pot fi definite cu usurinta adaptoare pt orice context

Dezavantaje

Adaptorul de clase se bazeaza pe derivare multipla, lucru care nu este posibil in Java.
Alternativa este prin interfete si compunere

MODELUL FAADE (Wrapper)


Scenariu
ACME Inc dezvolta o solutie software pt managementul unei locuinte inteligente. Includerea in
framework a tuturor componentelor controlabile dintr-o astfel de locuinta (ferestre, incalzire, alarma etc)
a generat un nr mare de clase. Departamentul care dezvolta interfata Web a solutiei ofera un set minim
de functii ce pot fi controlate de la distanta. Desi functionalitatea este simpla, nr mare de clase ce se
instantiaza si a metodelor apelate ingreuneaza dezvoltarea si testarea. In acest sens, o interfata mai
simpla ar ajuta acest departament.
Problema
Solutia contine o multime de clase, iar executia unei functii presupune apeluri multiple de
metode aflate in aceste clase
Clasele nu se modifica insa se construieste un layer intermediar ce permite apelul/gestiunea
facila a metodelor din mai multe interfete
Utila in situatia in care framework-ul creste in complexitate si nu este posibila rescrierea lui pt
simplificare
Apelurile catre multiplele interfete sunt mascate de aceasta interfata comuna

Scenariu

Diagrama

Componente:
Clasa1, Clasa2,..Package1, Package2..
- Clase existente ce pun la dispozitie diferite interfete
Faade - defineste o interfata simplificata pt contextul existent
Client reprezinta framework-ul care apeleaza interfata specifica noului domeniu

Avantaje si dezavantaje
Avantaje:

Framework-ul nu se rescrie
Se adauga doar un layer intermediar ce ascunde complexitatea framework-ului din spate
Pot fi definite cu usurinta metode care sa simplifice orice situatie
Implementeaza principiul Least Knowledge reducerea interactionilor intre obiect la
nivel de prieteni apropiati

Dezavantaje:
Creste nr de clase wrapper
Creste complexitatea codului prin ascunderea unor metode
Impact negativ asupra performantei aplicatiei

MODELUL DECORATOR (Wrapper)


Problema:

Extinderea (decorarea) statica sau la run-time a functionalitatii sau starii unor obiecte,
independent de alte instante ale aceleasi clase
Obiectul poate fi extins prin aplicarea mai multor decoratori
Clasa existenta nu trebuie sa fie modificata
Utilizarea unei abordari traditionale, prin derivarea clasei, duce la ierarhii complexe ce sunt
greu de gestionat. Derivarea adauga comportament nou doar la compilare

Diagrama

Componente
AbstractProduct clasa abstracta ce defineste interfata obiectelor ce pot fi decorate cu
noi functii
ConcreteProduct - defineste obiecte ce pot fi decorate
Decorator
- Gestioneaza o referinta de tip AbstractProduct catre obiectul decorat
- Metodele mostenite din AbstractProduct apeleaza implementarile specifice din clasa
obiectului referit
- Poate defini o interfata comuna claselor decorator
ConcreteDecorator adauga functii noi obiectului referit

Avantaje si dezavantaje
Avantaje:

Extinderea functionalitatii a unui obiect particular se face dinamic, la run-time


Decorarea este transparenta pt utilizator deoarece clasa mosteneste interfata specifica
obiectului
Decorarea se face pe mai multe niveluri, insa transparent pt utilizator
Nu impune limite privind un nr maxim de decorari

Dezavantaje:

Un decorator este un wrapper pt obiectul initial. El nu este identic cu obiectul incapsulat


Utilizarea excesiva genereaza o multime de obiecte care arata la fel, care se comporta diferit
Dificil de inteles si verificat codul
Situatia trebuie analizata cu atentie deoarece in unele situatii pattern-ul Strategy e mai indicat

ADAPTER vs FAADE vs DECORATOR


ADAPTER asigura o interfata diferita obiectului
FAADE asigura o interfata simplificata obiectului
DECORATOR asigura o interfata imbunatatita obiectului

MODELUL COMPOSITE
ACME Inc dezvolta o solutie software pt managementul resurselor umane dintr-o companie. Solutia
trebuie sa ofere un mecanism unitar care sa centralizeze angajatii companiei si care sa tina cont de:

Relatiile ierarhice
Apartenenta angajatilor la un departament
Rolurile diferite ale angajatilor
Setul comun de functii pe care un angajat le poate indeplini

Problema
Solutia contine o multime de clase aflate in relatie ierarhica ce trebuie tratate unitar
Se construiesc structuri arborescente in care nodurile intermediare si cele frunza sunt
tratate unitar

Diagrama

Componente:
Componenta
- Contine descrierea abstracta a tuturor componentelor din ierarhie
- Descrie interfata obiectelor aflate in compozitie

NodFrunza
- Reprezinta nodurile frunza din compozitie
- Implementeaza toate metodele
Composite
- Reprezinta o componenta compusa are noduri fiu
- Implementeaza metode prin care sunt gestionate nodurile fiu

Avantaje

Framework-ul nu se rescrie
Permite gestiunea facila a unor ierarhii de clase ce contin atat primitive cat si obiecte compuse
Codul devine mai simplu deoarece obiectele din ierarhie sunt tratate unitar
Adaugarea de noi componente care respecta interfata comuna nu ridica probleme
suplimentare

MODELUL FLYWEIGHT
Scenariu problema
ACME Inc dezvolta un editor de texte ca solutie alternativa la solutiile cunoscute. In faza de testare s-a
observat ca pe masura ce creste dimensiunea textului, creste si memoria ocupata de aceasta aplicatie.
Ritmul de crestere este unul anormal, destul de rapid, iar in final genereaza intarzieri intre momentul
tastarii unui caracter si cel al afisarii. Test pe aceasta zona au aratat ca exista o legatura intre nr de
caractere tastata si nr de obiecte.

Problema

Solutia genereaza o multime de obiecte cu o structura interna complexa si care ocupa un


volum mare de memorie
Obiectele au atribute comune insa o parte din starea lor variaza; memoria ocupata de ele
poate fi minimizata prin partajarea starii fixe intre ele
Starea obiectelor poate fi gestionata prin structuri externe iar nr de obiecte efectiv create
poate fi minimizat
Utilizarea unui obiect inseamna reincarcarea starii lui variabile intr-un obiect existent

Diagrama

Componente:
Flyweight interfata ce permite obiectelor sa primeasca valori ce fac parte din starea lor si
sa faca diferite procesari pe baza acesteia
FlyweightFactory
- Un pattern de tip factory ce construieste si gestioneaza obiecte de tip flyweight
- Mentine o colectie de obiecte diferite astfel incat ele sa fie create o singura data
FlyweightConcret
- Clasa implementeaza interfata de tip Flyweight si permite stocarea starii permanente
(ce nu poate fi partajat) a obiectelor
- Valori ce reprezinta o stare temporara partajata intre obiecte sunt primite si procesate
prin intermediul metodelor din interfata
Client
- Gestioneaza obiectele de tip flyweight si starea lor temporara

Avantaje si dezavantaje
Avantaje:

Se reduce memoria ocupata de obiecte prin partajarea lor intre clienti sau a starii lor intre
obiecte de acelasi tip
Pt a gestiona corect partajarea obiectelor de tip Flyweight intre clienti si fire de executie,
acestea trebuie sa immutable

Dezavantaje

Trebuie analizate clasele si contextul pt a se determina ce reprezinta starea variabila ce poate fi


internalizata
Efectele sunt vizibile pt solutii in care nr de obiecte este mare
Nivelul de memorie redusa depinde de nr de categorii de obiecte de tip Flyweight

FLYWEIGHT vs DECORATOR vs PROTOTYPE


PROTOTYPE creeaza obiecte identice prin clonarea unui obiect existent. Obiectele
create sunt identice (spatiu de memorie, atribute)
DECORATOR permite modificarea la run-time a functionalitatii obiectului fara a-i
schimba definitia. Obiectele sunt create in mod normal si apoi decorate la executie

FLYWEIGHT permite stocarea si crearea obiectelor prin partajarea unui obiect partial
ce contine doar partea comuna (atribute si metode). Obiectele flyweight partajeaza partea
comuna insa isi gestioneaza partea specifica

FLYWEIGHT sabloane asemanatoare

ADAPTER modifica interfata obiectului


DECORATOR adauga dinamic functii noi la comportamentul obiectului
FAADE asigura o interfata simplificata

MODELUL PROXY
Problema

Interconectarea de API-uri diferite aflate pe aceeasi masina sau in retea


Definirea unei interfete intre framework-uri diferite

Diagrama

Componente
InterfataEntitate
- Defineste interfata obiectului real la care se face conectarea
- Interfata este implementata si de proxy astfel incat sa se poata conecta la obiecte
Proxy
- Gestioneaza referinta catre obiectul real
- Implementeaza interfata obiectului real
- Controleaza accesul la obiectul real
Entitate obiectul real catre care proxy-ul are legatura

Tipuri de proxy

Virtual Proxies gestioneaza crearea si initializarea unor obiecte costisitoare; acestea pot fi
create doar atunci cand e nevoie sau partajeaza o singura instanta intre mai multi clienti
Remote Proxies asigura o instanta virtuala locala pt un obiect aflat la distanta Java RMI
Proiection Proxies controleaza accesul la metodele unui obiect sau la anumite obiecte
Smart References gestioneaza referintele catre un obiect

Sabloane asemanatoare
ADAPTER modifica interfata obiectului

DECORATOR adauga dinamic functii noi la comportamentul obiectului


STRATEGY- modifica comportamentul obiectului
FAADE asigura o interfata simplificata
COMPOSITE agrega mai multe obiecte asemanatare pt o gestiune unitara

BEHAVIORAL DESIGN PATTERN


STRATEGY
Problema

Alegerea la run-time a algortimului/functiei care sa fie utilizata pt procesarea unor date


Algoritmul se poate alege pe baza unor conditii descrise la executie in functie de contextul
datelor de intrare
Clasa existenta nu trebuie sa fie modificata
Utilizarea unei abordari traditionale, prin includerea in clasa a tuturor metodelor posibile, duce le
ierarhii complexe ce sunt greu de gestionat. Derivarea adauga comportament nou doar la
compilare

Diagrama

Componente
IStrategy clasa abstracta ce defineste interfata obiectelor ce pot oferi noi
functii/algoritmi de prelucrare
StrategyA defineste obiecte ce furnizeaza solutii pt prelucrarea datelor
Obiect
- Gestioneaza o referinta de tip IStrategy catre obiectul care va oferi functia/algoritmul
- Gestioneaza datele/contextul ce necesita prelucrare

Avantaje

Alegerea metodei de prelucrare a datelor se face dinamic, la run-time


Este permisa definirea de noi algoritmi independent de modificarea clasei ce gestioneaza datele

Nu impune limite privind un nr maxim de functii/algoritmi ce pot fi folositi

MODELUL OBSERVER
Problema

Exista componente care trebuie sa fie notificate la producerea unui eveniment


Gestiunea evenimentelor la nivel de interfata
Componentele se aboneaza/inregistreaza la acel eveniment modificare stare/actiune
La producerea unui eveniment pot fi notificate mai multe componente

Avantaje

Externalizarea/delegarea functiilor catre componente observator care dau solutii la anumite


evenimente independent de proprietarul evenimentului
Conceptul integrat in pattern-ul arhitectural Model View Controller (MVC)
Implementeaza conceptul POO de loose coupling obiectele sunt interconectate prin
notificari si nu prin instantieri de clase si apeluri de metode

Diagrama

Componente
Observabil clasa abstracta ce defineste interfata obiectelor, gestioneaza evenimente si
care sunt observabile
ObservabilConcret defineste obiecte ce permit abonarea unor observatori
Observator
interfata ce defineste modalitatea in care sunt notificati observatorii
Permite gestiunea mai multor observatori
ConcreteDecorator implementeaza functii concrete care sunt executate in urma
notificarii

Metode de comunicare
2 modele de notificare a observatorului la modificarea starii:
Push obiectul trimite toate detaliile observatorului
Pull obiectul doar notifica observatorul si acesta cere datele cand are nevoie de ele

MODELUL CHAIN OF RESPONSIBILITY


Problema

Tratarea unui eveniment sau a unui obiect se face diferit in functie de starea acestuia
Gestiunea tuturor cazurilor ar implica o structura complexa care sa verifice toate cazurile
particulare
Exista legaturi de dependenta intre cazurile de utilizare: executia unui caz poate implica
ignorarea celorlalte sau tratarea urmatorului caz

Diagrama

Componente
Handler clasa abstracta ce defineste interfata obiectelor ce gestioneaza cererea de
procesare a evenimentului
HandlerA defineste obiecte concrete ce formeaza secventa de tratare a notificarii
Client genereaza evenimentul sau notifica primul obiect din secventa de obiecte

MODELUL STATE
Problema

Aplicatia trateaza un anumit eveniment diferit in functie de starea unui obiect


Nr de stari posibile poata sa creasca si tratarea unitara a acestora poate sa influenteze
complexitatea solutiei
Modul de tratare a actiunii este asociat unei anumite stari si este incapsulat intr-un obiect de
stare

Diagrama

Componente:
State clasa abstracta ce defineste interfata obiectelor ce gestioneaza implementarea unor
actiuni in functie de stare
StareConcretA, StareConcretB defineste obiecte concrete ce implementeaza metodele
de actiuni aferente starii respective
Context gestioneaza referinta de tip State si foloseste metodele acesteia pt a implementa
diferite prelucrari in functie de stare

MODELUL COMMAND
Problema

Aplicatia defineste actiuni parametrizabile ce pot fi executate mai tarziu fara a solicita
clientului cunoasterea detaliilor interne necesare executiei
Pt a nu bloca clientul, se doreste ca aceste actiuni sa fie definite si trimise spre executie fara a
mai fi gestionate de client
Se decupleaza executia intarziata (ulterioara) a unei actiuni de proprietar. Din punctul acestuia
de vedere, actiunea a fost deja trimisa spre executie
Concept echivalent cu macro-urile. Obiectul de tip command incapsuleaza toate informatiile
necesare executiei actiunii mai tarziu de catre responsabil
Clientul este decuplat de cel ce executa actiunea

Diagrama

Componente
Comanda defineste interfata necesara executiei actiunii + alte detalii
ComandaConcreta
- Extinde intefata comenzii si implementeaza metoda prin care este controlat Receiver-ul
- Reprezinta legatura dintre Receiver si actiune
Client creeaza un obiect ComandaConcreta si seteaza Receiver-ul acestuia
Invoker (ManagerComenzi)
- Creeaza comanda si cere indeplinirea actiunii
Receiver obiectul care este responsabil cu executia actiunii

Scenariu
ACME Inc dezvolta o solutie software pt un restaurant, astfel incat chelnerul sa poata prelua comenzile
direct pe telefonul mobil. Comenzile sunt preluate de la client si ele sunt create pe loc, fiind automat
alocat bucatarul specializat pe acel fel de mancare, ingredientele folosite si alte cerinte speciale ale
clientului. Aceste detalii sunt puse de aplicatie, fara a fi necesara interventia chelnerului care doar
seteaza felul de mancare solicitat. Comenzile sunt trimise bucatarilor la finalizarea comenzii pt masa
respectiva, urmand sa fie executate in functie de gradul de incarcare al fiecarui bucatar.

MODELUL TEMPLATE METHOD


Problema

Implementarea unui algoritm presupune o secventa predefinita si fixa de pasi


Metoda ce defineste schema algortimului metoda template
Pot fi extinse /modificate metodele care implementeaza fiecare pas insa schema algoritmului
nu este modificabila
Implementeaza principiul Hollywood: Dont call us, we call you
Metodele concrete ce definesc pasii algoritmului sunt apelate de metode template

Diagrama

Componente
TemplateTestare
- Clasa abstracta ce defineste interfata unui obiect de tip TemplateTestare si modalitatea
in care sunt executate metodele
- Contine o metoda template ce implementeaza sablonul de executie a interfetei si care se
supradefineste
TestareJUnit defineste interfata obiectului intr-o situatie concreta
TestareNUnit defineste interfata obiectului intr-o situatie concreta

MODELUL MEMENTO
Problema

Aplicatia trebuie sa permita salvarea starii unui obiect


Imaginile starii obiectului pt diferite momente sunt gestionate separat
Obiectul isi poate restaura starea pe baza unei imagini anterioare

Diagrama

Componente
Memento gestioneaza starea interna a obiectului Originator pt un anumit moment. Este
creat de Originator si este gestionat de Caretaker
Originator obiectul al carui stare este urmarita; poata genera un memento cu starea lui
la momentul respectiv. Poate sa isi refaca starea pe baza unui Memento
ManagerStari (Caretaker) gestioneaza obiectele de tip Memento fara a avea acces pe
continutul acestora