Concepte si Principii POO de
baza
UML - review
OOP
Paradigma POO (1)
Necesitatea:
Spatiul problemei Spatiul solutiei
Modelul problemei Modelul solutiei
POO ofera instrumente eficiente pentru reprezentare
POO permite rezolvarea problemei in termenii problemei,
nu in termeni specifici modelului calculatorului pe care
se executa solutia.
Obiect = reprezentarea unui element din spatiul problemei
(def. generala)
in spatiul solutiei
Orice obiect are o stare
Orice obiect are o interfata
OOP
Paradigma POO(2)
Concepte:
1.
2.
3.
Clasa
- implementare a unui TAD
Obiect
= instanta a unei clase
Metoda = implementarea unei operatii din interfata TAD
(mesaj = apel al metodei > interactiune intre obiecte)
Caracteristici:
1.
Incapsulare (date + operatii)
ascunderea informatiei protectia informatiei consistenta datelor
2.
Mostenire reutilizarea codului
3.
Polimorfism = capacitatea unei entitati de a reactiona diferit in
functie de starea sa.
OOP
Avantaje ale POO
Abstractizare (de nivel inalt)
Un obiect poate fi utilizat fara a se cunoaste reprezentarea sa interna
Modularitate & Modificabilitate
Codul sursa corespunzator unui obiect poate fi scris si intretinut
independent de codul sursa corespunzator altor obiecte.
O clasa poate fi usor schimbata fara a se modifica alte clase.
Biblioteci de clase
Lizibilitate
Usor de inteles -> de depanat, intretinut
Reutilizabilitate
!!! Doar daca programele sunt construite respectand principiile POO!!!
OOP
Reutilizabilitate
prin instantiere (trivial)
prin compozitie (agregare) ( hasa relationship)
Shape
Window
Rectangle
RoundRectangle
prin mostenire (is-a or is-like-a relationship)
OOP
Reutilizabilitate(2)
is - a relationship
Substitutie pura!
Shape* s=new Circle();
s->draw();
Suprascriere (Overriding)
OOP
Suprascriere Supraincarcare
Exemplu:
class Shape{
void draw();
};
class Circle: public Shape{
\\
public:
void draw(); \\ overriding
void draw (int width);
\\
\\ overloading
};
OOP
Reutilizabilitate (3)
is-like-a relationship
Adaugare de functionalitate
Shape* s=new Triangle();
s->draw();
//s->FlipVertical();
((Triangle*)s)->FlipVertical();
//possible using cast!
//downcasting
Noile functii nu sunt
accesibile direct prin clasa de baza.
OOP
Reutilizabilitate(4)
interfata = multimea mesajelor (cererilor) care pot fi trimise
clasa = implementarea unui tip
subtip
(substitutie: instanta unui subtip in locul unei instante a tipului)
Mostenire de interfata Mostenire de clasa (reutilizare cod)
Mostenire de clasa defineste implementarea unui obiect folosind
implementarea unui alt object
Mostenire de interfata descrie cazurile in care un obiect poate fi
utilizat in locul unui alt obiect
OOP
Polimorfism
Principiul Substitutiei
Un obiect al clasei derivate
poate apare oriunde
un obiect clasei de baza
este asteptat
Exemplu C++:
Shape* s1 = new Circle();
Shape* s2 = new Triangle();
s1->draw(); s2->draw();
Shape *x[2];
x[0]=new Triangle();x[1]=s1;
for (int i=0; i<2; i++)
x[i]->draw();
OOP
10
Legare Statica si Dinamica
Legarea dintre numele unei functii si codul sau se poate face:
- la compilare => legare statica
- in timpul executiei => legare dinamica
Legare dinamica (Late Binding)
Daca se trimite un mesaj unui obiect,
codul corespunzator se determina doar
la momentul executie lui.
( posibil doar pentru referinte si pointeri)
Metodele virtuale permit legarea dinamica
Polimorfism =
proprietatea unei entitati de a reactiona diferit in functie de starea sa.
Este posibil folosind legarea dinamica !
OOP
11
Exemplu
void Move(Shape& s, int dx, int dy){
// !!! Reference type
s.erase();
s.move(dx,dy)
s.draw();
}
// . . .
Circle c(10,10,50);
Triangle t(10,10, 20,20, 50,50);
Move(c,2 ,2);
Move(t, 4, 4);
OOP
12
Mecanismul C++
VMT Virtual Method Table
VMT_for_Point
p:Point
Shape
VPTR
PTR_draw
x
y
PTR_erase
Point::draw()
Point
VMT_for_Circle
c:Circle
VPTR
PTR_draw
x
y
r
PTR_erase
Circle::draw()
OOP
Circle
13
Cateva reguli de programare!
Problemele de proiectare pot fi simplificate prin introducerea unui nou nivel
de indirectare conceptuala.
Construieste clasele cat mai atomic posibil; adica, fiecare clasa trebuie sa
aiba un scop singur si clar (in general implementarea unui TAD).
In general o metoda :
schimba starea objectului apelant, folosindu-se de starea anterioara,
furnizeaza informatii despre stare.
Pastreaza totul private pe cat posibil, si lasa doar interfata clasei public.
(modifica starea doar prin mesaje!!!!!!)
Nu folosi mostenire multipla decat daca este absolut necesar!
Alege intre compozitie si mostenire
Cum? Daca e nevoie de upcast mostenire,
altfel compozitie
OOP
14
SOLID Principii de proiectare
(The Principles of OOD).
SOLID stands for:
Single Responsibility principle (SRP)
Open Closed principle (OCP)
Liskov Substitution Principle (LSP)
Interface Segregation principle (ISP)
Dependency Inversion principle (DIP)
OOP
15
Single Responsibility principle (SRP)
Principiu: Trebuie sa existe doar o motivatie pentru a schimba o clasa!
motivatie pentru schimbare <-> responsabilitatea unei clase.
Fiecare resposabilitate va reprezenta o axa pentru schimbare.
Este similar cerintei de a creea clase cu coeziune ridicata.
O responsabilitate poate fi implementata folosind mai multe metode din aceeasi
clasa.
DE ce?
atunci cand se cere schimbarea unei functionalitati nu putem fi sigur de impactul
asupra altora care sunt implementate de aceeasi clasa
Necesar testarea tuturor caracteristicilor depenedente
Contraargument:
Daca avem teste automate si numarulmde teste nu este mare atunci numarul de
verificari nu este mare.
Raspuns:
Per global aceste verificari se acumuleaza si creste timpul de rezolvare. Codul ar
deveni fragil si rigid.
Solutie (de refactorizare):
Diviziunea functionalitatilor unei clase in clase diferite, care respecta fiecare
SRP.
OOP
16
Example
public class UserSettingService
{
public void changeEmail(User user)
{
if (checkAccess(user))
{
//Grant option to change
}
}
public boolean checkAccess(User user)
{
//Verify if the user is valid.
}
}
What if you would want to reuse the
checkAccess code at some other place OR
you want to make changes to the way
checkAccess is being done OR you want to
make change to the way email changes are
being approved.
One way to correct this is to decompose the
UserSettingService into UserSettingService
and SecurityService. And move the
checkAccess code into SecurityService.
public class UserSettingService
{
public void changeEmail(User user)
{
if(SecurityService.checkAccess(user))
{
//Grant option to change
}
}
}
public class SecurityService
{
public static boolean checkAccess(User user)
{
//check the access.
}
}
OOP
17
Principiul Open/Closed
Principiu:
Entitatile de programare (clase, module, functii) trebuie sa fie deschise pentru
extindere, dar inchise la modificare.
Consecinta:
=> O asemenea entitate poate permite modificarea comportamentului sau fara
modificarea codului sau sursa
Important pentru activitatea de productie
activitate de intretinere: code reviews, unit tests, si altele):
Daca se respecta acest principiu nu este nevoie de acest effort.
Doua variante:
Ambele se bazeaza pe mostenire
Au scopuri, tehnici si rezultate diferite
OOP
18
Principiul OCP al lui Meyer
(MeyersOpen/Closed Principle)
Bertrand Meyer, Object Oriented Software Construction. 1988
Odata ce implementarea unei clase a fost terminat, nu se permite
modificarea codului asociat decat pentru a corecta greseli.
Caracteristicile noi vor trebui introduse prin crearea de noi clase!
Clasele noi pot folosi clasa origina prin mostenire.
Nu este obligatorie folosirea aceleiasi interfete.
Aceasta cerinta implica refolosirea implementarii (mostenirea de
clasa; refolosirea codului)
Implementarea existenta este inchisa pentru modificari si noile clase
nu trebuie sa implementeze interfata existenta.
OOP
19
Principiul OCP Polimorfic
Programarea bazata pe interfete
Multiple implementari ale aceleiasi interfete
Substitutie polimorfica
Diferente fata de varianta lui Meyer:
Se recomanda mostinerea din clase abstracte/ interfete
Refolosirea interfetelor(tipului).
Interfata existenta este inchisa la modificari si noile implementari trebuie
doar sa implementreze acea interfata.
OOP
20
Example
public class LoanApprovalHandler
{
public void approveLoan(PersonalValidator validator)<br />
{
if ( validator.isValid())
{
//Process the loan.
}
}
}
public class PersonalLoanValidator
{
public boolean isValid()
{
//Validation logic
}
}
OOP
21
Incorrect adaptation - violates the OCP
public class LoanApprovalHandler
{
public void approvePersonalLoan
(PersonalLoanValidator validator)
{
if ( validator.isValid())
{
//Process the loan.
}
}
public void approveVehicleLoan
(VehicleLoanValidator validator )
{
if ( validator.isValid())
{
//Process the loan.
}
}
// Method for approving other loans.
}
public class PersonalLoanValidator
{
public boolean isValid()
{
//Validation logic
}
}
public class VehicleLoanValidator
{
public boolean isValid()
{
//Validation logic
}
}
OOP
22
Correct adaptation
/**
* Abstract Validator class
* Extended to add different
* validators for different loan type
*/
public abstract class Validator
{
public boolean isValid();
}
/**
* Personal loan validator
*/
public class PersonalLoanValidator
extends Validator
{
public boolean isValid()
{
//Validation logic.
}
}
/*
* Similarly any new type of validation can
* be accommodated by creating a new subclass
* of Validator
*/
public class LoanApprovalHandler
{
public void approveLoan(Validator validator)
{
if ( validator.isValid())
{
//Process the loan.
}
}
}
OOP
23
Reguli care conduc la respectarea OCP
Declararea tuturor variabilelor membru private => accesul la ele
doar via (getters).
Evitarea operatiilor de typecasts la runtime.
Acest lucru conduce la un cod fragil si dependent de clasele
considerate la momentul dezvoltarii.
OOP
24
Principiul Substitutiei
LSPThe Liskov Substitution Principle
Principiul:
Functiile care folosesc pointeri sau referinte catre clase de baza trebuie sa
poata folosi obiecte(instante) ale claselor derivate fara sa le stie
anterior!
Barbara Liskov first wrote it as follows:
What is wanted here is something like the following substitution property: If
for each object o1 of type S there is an object o2 of type T such that for all
programs P defined in terms of T, the behavior of P is unchanged when o1
is substituted for o2 then S is a subtype of T.
OOP
25
Principiul Segregarii Interfetelor
The Interface Segregation Principle (ISP)
Principiul:
Clientii nu trebuie sa fie fortati sa depinda de interfete pe care nu le
folosesc!
Fat interfaces nu sunt specifice unui singur client/responsabilitate.
Fat interfaces conduc la cuplari neadecvte intre clienti.
Solutii:
Folosirea sablonului ADAPTER
Fie prin delegare (object form) or
Mostenire multipla (class form),
Rezultat:
interfetele sunt separate in clase abstracte de baza.
OOP
26
Exemplu
Separation through Delegation
Consider a security system. In this system there
are Door objects that can be locked and
unlocked, and which know whether they are
open or closed.
TimedDoor needs to sound an alarm when the
door has been left open for too long. In order to
do this the TimedDoor object communicates with
another object called a Timer.
OOP
Separation through Multiple
Inheritance
27
Principiul inversarii dependentei DIP
The Dependency Inversion Principle
Principiul:
Modulele de nivel inalt nu trebuie sa depinda de modulele de nivel
scazut! Ambele trebuie sa depinda doar de abstractizari!
Abstractizarile nu trebuie sa depinda de detalii. Detaliile trebuie sa
depinda de abstractizari!
Explicarea termenilor
inversion.
In mod uzual (ex. in Analiza si Proiectarea Structurata) se
creeau module care depindeau de module de nivel mai scazut.
Se inverseaza structura de dependenta!
Necesitate: Dependenta este tranzitiva .
OOP
28
Layers
OOP
29
Layering
According to Booch , ...all well structured object-oriented architectures have
clearly-defined layers, with each layer providing some coherent set of
services though a well-defined and controlled interface.
A naive interpretation of this statement might lead a designer to produce a
structure similar to Figure 1. While this may look appropriate, it has the
insidious characteristic that the Policy Layer is sensitive to changes all the
way down in the Utility Layer.
Dependency is transitive . The Policy Layer depends upon something that
depends upon the Utility Layer, thus the Policy Layer transitively depends
upon the Utility Layer. This is very unfortunate.
Figure 2 shows a more appropriate model. Each of the lower level layers are
represented by an abstract class. The actual layers are then derived from
these abstract classes. Each of the higher level classes uses the next
lowest layer through the abstract interface.
Thus, none of the layers depends upon any of the other layers. Instead, the
layers depend upon abstract classes. Not only is the transitive dependency
of Policy Layer upon Utility Layer broken, but even the direct dependency of
Policy Layer upon Mechanism Layer is broken.
OOP
30
Example
OOP
31
Analiza si Proiectare
Cine va folosi sistemul?" (pentru a descoperi actorii)
Ce pot face acesti actori cu sistemul?"
Cum poate sistemul reactiona daca altcineva face acestea?"
(pentru a descoperi variatiile)
Ce probleme pot apare in sistem?"
(pentru a descoperi exceptiile)
1. Descoperirea obiectelor
2. Asamblarea obiectelor
3. Constructia sistemului
4. Extensia sistemului
5. Reutilizarea obiectelor
OOP
32
UML (Unified Modeling Language)
UML este un limbaj standard pentru specificarea,
vizualizarea, constructia si documentarea artefactelor
sistemelor software.
UML notatie standard pentru arhitecturile software
Online UML Resurse
Rational Software
-- UML Resource Center (http://www-306.ibm.com/software/rational/uml/),
The Object Management Group http://www.uml.org/
http://www.omg.org/cgi-bin/doc?ptc/2003-08-02
OOP
33
UML(2)
Tipuri de date: Integer, Real, String, Character, Boolean
OOP
34
UML(3)
OOP
35
UML(4)
OOP
36
UML(5)
OOP
37
Exemple UML - Asociere
Asociere simpla
Foloseste
Autor
Persoana
Computer
1..*
Detine
0..*
Este detinut de
Masina
Asociere navigabila
Detine
Persoana
OOP
0..*
Masina
38
Exemple UML - Asociere
Asociere calificata
Canvas
Contine
Figura
FiguraId
Asociere -OR
Company
0..*
0..*
Contract
0..*
de asigurare
0..*
de asigurari
(or)
1..*
1..*
Persoana
Companie
OOP
39
Exemple UML - Asociere
Asociere de tip clasa
Casatorie
Femeie
Barbat
Clasa de tip asociere
este folosita pentru a adauga informatie in plus legaturii.
OOP
40
Exemple UML - Agregare
Agregare simpla
Echipa
Formata din
Jucator
1..*
Agregare compozitie
TitleBar
Window
*
OOP
Menu
41
Exemple UML Generalizare/Specializare
Persoana
Student
OOP
42
UML Examples -Dependenta
Class A
Class B
Clasa A depinde de clasa B.
O modificare a clasei B poate conduce la modificari in
clasa dependenta.
OOP
43
Class stereotypes
OOP
44
Properties
OOP
45
Inner classes
OOP
46
Deep copy - example
OOP
47
OOP
48
UML(6)
Use-case diagrams
Collaboration diagrams
Sequence diagrams
OOP
49