Descărcați ca pdf sau txt
Descărcați ca pdf sau txt
Sunteți pe pagina 1din 25

Curs 6: Principii de proiectare

Diagrame UML
abloane GRASP
Arhitectur stratificat:
ui controller domain - repository

Curs 5: Tipuri definite de utilizator

Programare orientat obiect


Principii de definire a tipurilor utilizator

Diagrame UML
Unified Modeling Language (UML) - este un limbaj standardizat de
modelare destinat vizualizrii, specificrii, modelrii i documentrii
aplicaiilor.
UML include un set de notaii grafice pentru a crea modele vizuale ce
descriu sistemul.

Diagrame de clase
Diagrama UML de clase (UML Class diagrams) descrie structura
sistemului prezentnd clasele,atributele i relaiile intre aceste clase
class RationalNumber:
def __init__(self, a, b):
"""
Initialize a rational number
a,b integer numbers
"""
self.__nr = [a, b]
def getDenominator(self):
"""
Getter method return the
denominator
"""
return self.__nr[1]
def getNominator(self):
""""
Getter method return the nominator
"""
return self.__nr[0]
def add(self, a):

Clasele sunt reprezentate prin dreptunghiuri ce conin trei zone:


Partea de sus numele clasei
Partea din mijloc cmpurile/atributele clasei
Partea de jos metodele/operaiile

Relaii UML
O relaie UML este un termen general care descrie o legatur logic ntre
dou elemente de pe o diagram de clase.
Un Link este relaia ntre obiectele de pe diagram. Este reprezentat
printr-o linie care conecteaza dou sau mai multe dreptunghiuri.
Associeri
Asocierile binare se reprezint printr-o linie ntre dou clase.

O asociere poate avea nume, capetele asocieri pot fi adnotate cu nume de


roluri, multiplicitate, vizibilitate i alte proprieti. Asocierea poate fi unidirecional sau bi-direcional

Agregare
Agregarea este o asociere specializat. Este o asociere ce reprezint
relaia de parte-ntreg (part-whole) sau apartenena (part-of).

class Car:
def __init__(self,eng,col):
"""
Initialize a car
eng - engine
col - string, ie White
"""
self.__engine = eng
self.__color = col
def getColor(self):
"""
Getter method for color
return string
"""
return self.__color
def getEngine(self):
"""
Getter method for engine
return engine
"""
return self.__engine

class Engine:
def __init__(self,cap,type):
"""
initialize the engine
cap positive integer
type string
"""
self.__capacity = cap
self.__type = type
def getCapacity(self):
"""
Getter method for the capacity
"""
return self.__capacity
def getType(self):
"""
Getter method for type
return string
"""
return self.__type

Dependene, Pachete
Relaia de dependen este o asociere n care un element depinde sau
foloseste un alte element
Exemple de dependene:
creaz instane
are un parametru
foloseste un obiect n interiorul unei metode

Principii de proiectare
Creaz aplicaii care:
Sunt uor de neles, modificat, ntreinut, testat
Clasele abstracte, ncapsulare, ascunderea reprezentrii, uor de
testat, uor de folosit i refolosit
Scop general: gestiunea dependenelor
Single responsibility
Separation of concerns
Low Coupling
High Cohesion

Enun (Problem statement)


Scriei un program care gestiuneaz studeni de la o facultate
(operaii CRUD Create Read Update Delete)

Funcionaliti (Features)
F1

Adauga student

F2

vizualizare studeni

F3

caut student

F4

terge student

Plan de iteraii
IT1 - F1; IT2 F2; IT3 F3; IT4 - F4

Scenariu de rulare (Running scenario)


user

app

description
add a student

give student id
1
give name
Ion
new student added
a

add student
give student id

1
give name

id already exists, name can


not be empty

Arhitectur stratificat (Layered architecture)


Layer (strat) este un mecanism de structurare logic a elementelor ce
compun un sistem software
ntr-o arhitectur multi-strat, straturile sunt folosite pentru a aloca
responsabiliti n aplicaie.
Layer este un grup de clase (sau module) care au acelai set de
dependene cu alte module i se pot refolosi n circumstane similare.

User Interface Layer (View Layer, UI layer sau Presentation


layer)
Application Layer (Service Layer sau GRASP Controller
Layer)
Domain layer (Business Layer, Business logic Layer sau
Model Layer)
Infrastructure Layer (acces la date modaliti de
persisten, logging, network I/O ex. Trimitere de email,
sau alte servicii technice)

abloane Grasp
General Responsibility Assignment Software Patterns (or Principles)
conin recomandri pentru alocarea responsabilitilor pentru clase obiecte
ntr-o aplicaie orientat obiect.

High Cohesion
Low Coupling
Information Expert
Controller
Protected Variations
Creator
Pure Fabrication

High Cohesion
Aloc responsabilitile astfel nct coeziunea n sistem rmne
ridicat
High Cohesion este un principiu care se aplic pe pacursul dezvoltrii n
ncercarea de a menine elementele n sistem:
responsabile de un set de activiti nrudite
de dimensiuni gestionabile
uor de neles
Coeziune ridicat (High cohesion) nseamna ca responsabilitile pentru un
element din sistem sunt nrudite, concentrate n jurul aceluiai concept.
nprirea programelor n clase i starturi este un exemplu de activitate care
asigur coeziune ridicat n sistem.
Alternativ, coeziune slab (low cohesion) este situaia n care elementele
au prea multe responsabiliti, din arii diferite. Elementele cu coeziune
slab sunt mai greu de neles, reutilizat , ntreinut i sunt o piedic pentru
modificrile necesare pe parcursul dezvoltrii unui sistem

Low Coupling
Aloc responsabiliti astfel nct cuplarea rmne slab (redus)
Low Coupling ncurajeaz alocarea de responsabilitai astfel nct avem:
dependene puine ntre clase;
inpact sczut n sistem la schimbarea unei clase;
potenial ridicat de refolosire;
Forme de cuplare:
TypeX are un cmp care este de TypeY.
TypeX are o medod care refer o instan de tipul TypeY n orce
form (parameterii, variabile locale, valoare returnat, apel la
metode)
TypeX ete derivat direct sau indirect din clasa TypeY.

Information Expert
Aloc responsabilitatea clasei care are toate informaiile necesare
pentru a ndeplini sarcina
Information Expert este un principiu care ajut s determinm care este
clasa potrivit care ar trebui s primeasc responsabilitatea (o metod
noua, un cmp, un calcul).
Folosind principiu Information Expert ncercm sa determinm care sunt
informaiile necesare pentru a realiza ce se cere, determinm locul n care
sunt aceste informaii i alocm responsabilitatea la clasa care conine
informaiile necesare.
Information Expert conduce la alocarea responsabilitii n clasa care
conine informaia necesar pentru implementare. Ajut s rspundem la
ntrebarea Unde se pune metoda, cmpul

Information Expert
Point of Sale application
Cine este responsabil cu calcului
totalului?
Avem nevoie de toate SaleItems
pentru a calcula totalul.
Information Expert Sale

Conform Expert
SaleItem ar trebui sa fie responsabil
cu calculul subtotalului (quantity *
price)

1.
2.
3.
4.

Menine ncapsularea
Promoveaz cuplare slab
Promoveaz clase puternic coezive
Poate sa conduc la clase complexe - dezavantaj

Creator
Crearea de obiecte este o activitate important ntr-un sistem orientat
obiect. Care este clasa responsabil cu crearea de obiecte este o
proprietate fundabental care definete relaia ntre obiecte de diferite
tipuri.
ablonul Creator descrie modul n care alocm responsabilitatea de a crea
obiecte n sistem
n general o clasa B ar trebui s aib responsibilitatea de a crea obiecte de
tip A dac unul sau mai multe (de preferat) sunt adevrate:
Instana de tip B conine sau agreg instane de tip A
Instana de tip B gestioneaz instane de tip A
Instana de tip B folosete extensiv instane de tip A
Instana de tip B are informaiile necesare pentru a iniializa
instana A.

Work items
Task
T1

Create Student

T2

Validate student

T3

Store student (Create repository)

T4

Add student (Create Controller)

T5

Create UI

Task: create Student


def testCreateStudent():
"""
Testing student creation
"""
st = Student("1", "Ion", "Adr")
assert st.getId() == "1"
assert st.getName() == "Ion"
assert st.getAdr() == "Adr"

class Student:
def __init__(self, id, name, adr):
"""
Create a new student
id, name, address String
"""
self.id = id
self.name = name
self.adr = adr
def getId(self):
return self.id
def getName(self):
return self.name
def getAdr(self):
return self.adr

Protected Variations
Cum alocm responsabilitatea astfel nct variaiile curente i viitoare nu
vor afecta sistemul (nu va fi necesar o revizuire a sistemului, nu trebuie sa
facem schimbri majore n sistem)?
Protected variations: Crem o nou clas care ncapsuleaz aceste variaii.
ablonul Protected Variations protejeaz elementele sistemului de
variaiile/modificrile altor elemente din sistem (clase, obiecte, subsisteme)
ncapsulnd partea instabil ntr-o clas separat (cu o interfa public
bine delimitat care ulterior, folosind polimorfism, poate introduce variaii
prin noi implementri).

Task: Validate student


Design posibil pentru validare:
Algoritmul de validare:
Poate fi o metoda in clasa student
o metoda statica, o funcie
ncapsulat ntr-o clas separat
Poate semnala eroarea prin:
returnare true/false
returnare lista de erori
excepii care conin lista de erori

Clas Validator : aplic Principiu Protect Variation


def testStudentValidator():
class StudentValidator:
"""
"""
Test validate functionality
Class responsible with validation
"""
"""
validator = StudentValidator()
def validate(self, st):
st = Student("", "Ion", "str")
"""
try:
Validate a student
validator.validate(st)
st - student
assert False
raise ValueError
except ValueError:
if: Id, name or address is empty
assert True
"""
st = Student("", "", "")
errors = ""
try:
if (st.id==""):
validator.validate(st)
errors+="Id can not be empty;"
assert False
if (st.name==""):
except ValueError:
errors+="Name can not be empty;"
assert True
if (st.adr==""):
errors+="Address can not be
empty"
if len(errors)>0:
raise ValueError(errors)

Pure Fabrication
Cnd un element din sistem ncalc primcipiul coeziunii ridicate i cuplare
slab (n general din cauza aplicrii succesive a ablonului expert):
Aloc un set de responsabiliti la o clas artificial (clas ce nu reprezint
ceva n domeniul problemei) pentru a oferi coeziune ridicat, cuplare slab
i reutilizare
Pure Fabrication este o clas ce nu reprezint un concept din domeniul
problemei este o clas introdus special pentru a menine cuplare slab i
coeziune ridicat n sistem.

Problema: Stocare Student (in memorie, fiier sau baz de date)


Expert pattern Clasa Student este expert, are toate informaiile, pentru
a realiza aceast operaie

Pure Fabrication - Repository


Problema: Stocare Student (in memorie, fiier sau baz de date)
Expert pattern Clasa Student este expert, are toate informaiile, pentru
a realiza aceast operaie
Dac punem responsabilitatea persistenei in clasa Student, rezult o clas
slab coeziva, cu potenial limitat de refolosire
Soluie Pure Fabrication
Clas creat cu responsabilitatea de a
salva/persista obiecte Student
Clasa student se poate reutiliza cu uurin
are High cohesion, Low coupling
Clasa StudentRepository este responsabil cu
problema gestiunii unei liste de studeni (s
ofere un depozit - persistent pentru obiecte
de tip student)

ablonul Repository
Un repository reprezint toate obiectele de un anumit tip ca si o mulime
de obiecte.
Obiecte sunt adugate, terse, modificate iar codul din repository
insereaza, sterge obiectele dintr-un depozit de date persistent.

Task: Create repository


def testStoreStudent():
st = Student("1", "Ion", "Adr")
rep = InMemoryRepository()
assert rep.size()==0
rep.store(st)
assert rep.size()==1
st2 = Student("2", "Vasile", "Adr2")
rep.store(st2)
assert rep.size()==2
st3 = Student("2", "Ana", "Adr3")
try:
rep.store(st3)
assert False
except ValueError:
pass
class InMemoryRepository:
"""
Manage the store/retrieval of students
"""
def __init__(self):
self.students = {}
def store(self, st):
"""
Store students
st is a student
raise RepositoryException if we have a student with the same id
"""
if st.getId() in self.students:
raise ValueError("A student with this id already exist")
if (self.validator!=None):
self.validator.validate(st)
self.students[st.getId()] = st

GRASP Controller
Scop: decuplarea sursei de evenimente de obiectul care gestioneaz
evenimentul. Decuplarea startului de prezentare de restul aplicaiei.
Controller este definit ca primul obiect dup stratul de interfa utilizator.
Interfaa utilizator folosete un obiect controller, acest obiect este
responsabil de efectuarea operaiilor cerute de utilizator.
Controller coordoneaz (controleaz) operaiile necesare pentru a realiza
aciunea declanat de utilizator.
Controlerul n general folosete alte obiecte pentru a realiza operaia, doar
coordoneaz activitatea.
Controllerul poate ncapsula informaii despre starea curent a unui usecase. Are metode care corespund la o aciune utilizator

Task: create controller


def tesCreateStudent():
"""
Test store student
"""
rep = InMemoryRepository()
val = StudentValidator()
ctr = StudentController(rep, val)
st = ctr.createStudent("1", "Ion", "Adr")
assert st.getId()=="1"
assert st.getName()=="Ion"
try:
st = ctr.createStudent("1", "Vasile", "Adr")
assert False
except ValueError:
pass
try:
st = ctr.createStudent("1", "", "")
assert False
except ValueError:
pass
class StudentController:
"""
Use case controller for CRUD Operations on student
"""
def __init__(self, rep, validator):
self.rep = rep
self.validator = validator
def createStudent(self, id, name, adr):
"""
store a student
id, name, address of the student as strings
return the Student
raise ValueError if a student with this id already exists
raise ValueError if the student is invalid
"""
st = Student(id, name, adr)
if (self.validator!=None):
self.validator.validate(st)
self.rep.store(st)
return st

Application coordinator
Dependency injection (DI) este un principiu de proiectare pentru
sisteme orientat obiect care are ca scop reducerea cuplrii ntre
componentele sistemului.
De multe ori un obiect folosete (depinde de) rezultatele produse de alte
obiecte, alte pri ale sistemului.
Folosind DI, obiectul nu are nevoie s cunoasc modul n care alte pri ale
sistemului sunt implementate/create. Aceste dependene sunt oferite (sunt
injectate), inpreun cu un contract (specificaii) care descriu
comportamentul componentei
#create validator
validator = StudentValidator()
#crate repository
rep = InMemoryRepository(None)
#create console provide(inject) a validator and a repository
ctr = StudentController(rep, validator)
#create console provide controller
ui = Console(ctr)
ui.showUI()

Review aplicaia student manager de revazut abloanele ce apar

Curs 6: Principii de proiectare


Diagrame UML
abloane GRASP
Arhitectur stratificat:
ui controller domain - repository

Curs 7 Principii de proiectare


Enti, ValueObject, Agregate
Fiiere in python
Motenire refolosire de cod

S-ar putea să vă placă și