You are on page 1of 61

Objektno orijentirano

programiranje

OOP design patterns


2

OOP design patterns

Objektno orijentirano programiranje


3

OOP design patterns


Često, kad pišemo aplikaciju, ne znamo odakle početi
DESIGN PATTERNS:
– predstavljaju "najbolju praksu"
– općenita rješenja koja imaju čvrste temelje i
provjereni su
– bilo da se radi aplikacija od početka ili se dodaju novi
feature-i

Objektno orijentirano programiranje


4

OOP design patterns


• Ipak, postoje i kontraverze
– često se pretjeruje s njihovim korištenjem
– izgubi se u "ljepoti koda"
– design patterni neće "sami riješiti" osnovni problem

važno je da developer zna kada i zašto koristi određeni


pattern

Objektno orijentirano programiranje


5

design patterns

creational structural behavioral

factory method adapter observer

builder decorator strategy

abstract factory facade command

singleton proxy state

prototype chain of responsability

visitor

OOP
6

design patterns

creational design patterns

• patterni koji "brinu" o instanciranju klasa


• možemo ih podijeliti u patterne koji se koriste za:
– kreiranje klasa
– kreiranje objekata
• ponekad postoje elegantniji načini za kreiranje objekata
osim korištenja new operatora

OOP
7

design patterns

creational

factory method

builder

abstract factory

singleton

prototype

OOP
8

design patterns

creational design patterns

abstract factory

OOP
9

design patterns

creational design patterns

abstract factory

• predstavlja sučelje za kreiranje obitelji srodnih ili povezanih objekata


– bez potrebe da se specificiraju konkretne klase
• U sljedećem primjeru:
– ShapeFactory se može koristiti da se kreiraju objekti na temelju stringa
shapeType
– nije potrebno specificirati klasu, već samo proslijediti string
• Ovaj pattern koristi nasljeđivanje za definiranje tvornica koje kreiraju
objekte
• Često se prihvaća kaosolucija za depeondency injection (DI)

OOP
abstract factory
10

public abstract class AbstractFactory {


abstract Color getColor(String color);
abstract Shape getShape(String shape);
}

Objektno orijentirano programiranje


abstract factory
11
public class ShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
} else if (shapeType.equalsIgnoreCase("SQUARE")) {
return new Square();
}
return null;
}

@Override
Color getColor(String color) {
return null;
}
}

Objektno orijentirano programiranje


abstract factory
12

public class ColorFactory extends AbstractFactory {


@Override
public Shape getShape(String shapeType) {
return null;
}

@Override
Color getColor(String color) {
if (color == null) {
return null;
}
if (color.equalsIgnoreCase("RED")) {
return new Red();
} else if (color.equalsIgnoreCase("GREEN")) {
return new Green();
} else if (color.equalsIgnoreCase("BLUE")) {
return new Blue();
}
return null;
}
}

Objektno orijentirano programiranje


13

design patterns

creational design patterns

factory method

• predstavlja sučelje za kreiranje objekata, ali daje podklasi da odluči


koji točno objekt kreirati
• Poput agencije za zapošljavanje:
– netko treba zaposliti nekoliko ljudi
– taj netko nazove agenciju za zapošljavanje i objasni što želi
– da bi uistinu zaposlio nekoga, potrebno je puno stvari obaviti i
znati
• doprinosi, porezi,...
– u ovom slučaju to ne trebamo znati

OOP
14

design patterns

creational design patterns

factory method

public interface IThingFactory


{
Thing GetThing(string theString);
}

public class ThingFactory : IThingFactory


{
public Thing GetThing(string theString)
{
return new Thing(theString, firstDependency, secondDependency);
}
}

OOP
15

design patterns

creational design patterns

factory method

• U sljedećem primjeru:
– Encryptor objekt zahtjeva algoritam za enkripciju
– kroz getEncryptionAlgorithm() se garantira da Encryptor uistinu
dobija EncryptorAlgorithm
– ipak, svaki Encryptor odlučuje koji se konkretno
EncryptionAlgorithm koristi

OOP
factory method
16

public interface EncryptionAlgorithm {


public String encrypt(String plaintext);
}

public abstract class Encryptor {


public void writeToDisk(String plaintext, String filename) {
EncryptionAlgorithm encryptionAlgorithm =
getEncryptionAlgorithm();
String cyphertext = encryptionAlgorithm.encrypt(plaintext);
try (FileOutputStream outputStream = new FileOutputStream(filename)){
outputStream.write(cyphertext.getBytes());
}
catch (IOException e) {
e.printStackTrace();
}
}
public abstract EncryptionAlgorithm getEncryptionAlgorithm();
}

Objektno orijentirano programiranje


factory method
17
public class Sha256CEncryptionAlgorithm implements EncryptionAlgorithm {
@Override
public String encrypt(String plaintext) {
return DigestUtils.sha256Hex(plaintext);
}
}

public class Sha512EncryptionAlgorithm implements EncryptionAlgorithm {


@Override
public String encrypt(String plaintext) {
return DigestUtils.sha512Hex(plaintext);
}
}

public class Sha256Encryptor extends Encryptor {


@Override
public EncryptionAlgorithm getEncryptionAlgorithm() {
return new Sha256CEncryptionAlgorithm();
}
}

public class Sha512Encryptor extends Encryptor {


@Override
public EncryptionAlgorithm getEncryptionAlgorithm() {
return new Sha512EncryptionAlgorithm();
}
}

Objektno orijentirano programiranje


18

design patterns

creational design patterns

builder

• odvaja konstrukciju objekta od njegove reprezentacije


• kod klasa koje imaju puno polja, često posegnemo za time da
imamo puno konstruktora
• Ovaj pattern omogućuje čitljiviji kod prilikom kreiranja ovih objekata
– omogućuje specificiranje koja polja su potrebna
• U sljedećem primjeru:
– DataFetcher objekt se može kreirati prosljeđivanjem polja koja
su u konkretnom slučaju potrebna
• Čitljiviji kod, uz korištenje samo jednog konstruktora

OOP
builder
19
class DataFetcher(){
// sva privatna polja
public class DataFetcher(String dataType, long limit, String orderBy) {
// pridjeljivanje svim privatnim poljima
}
}

class DataFetcherBuilder {
private String dataType;
private long limit;
private String orderBy;

public DataFetcherBuilder(String dataType) {


this.dataType = dataType;
}
public DataFetcherBuilder limitedBy(long limit) {
this.limit = limit;
return this;
}
public DataFetcherBuilder orderedBy(String orderBy) {
this.orderBy = orderBy;
return this;
}
public DataFetcher create() {
return new DataFetcher(dataType, limit, orderBy);
}
}

public class Client() {


DataFetcher dataFetcher =
new DataFetcherBuilder("users").limitedBy(10).orderedBy("username").create();
}

Objektno orijentirano programiranje


20

design patterns

creational design patterns

builder

• u biti, omogućuje nam da kreiramo objekte korak po korak

OOP
21

design patterns

creational design patterns

prototype

• potpuno inicijalizirana instanca se klonira ili kopira


• pattern koristan kad je kreiranje objekata skupo, a novi objekti su
slični postojećima
– koristi se clone metoda za dupliciranje postojećih instanci (koje
se koriste kako prototip za nove instance)
• U sljedećem primjeru:
– Access control objekti se dohvaćaju korištenjem key-a

OOP
prototype
22
public interface Prototype extends Cloneable {
public AccessControl clone() throws CloneNotSupportedException;
}

Objektno orijentirano programiranje


prototype
23
public class AccessControl implements Prototype {
private final String controlLevel;
private String access;

public AccessControl(String controlLevel, String access) {


this.controlLevel = controlLevel;
this.access = access;
}

@Override
public AccessControl clone() {
try {return (AccessControl) super.clone();} catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}

public String getControlLevel() {


return controlLevel;
}

public String getAccess() {


return access;
}

public void setAccess(String access) {


this.access = access;
}
}

Objektno orijentirano programiranje


prototype
24
public class AccessControlProvider {
private static Map<String, AccessControl> map = new HashMap<String, AccessControl>();

static {
map.put("USER", new AccessControl("USER", "DO_WORK"));
map.put("ADMIN", new AccessControl("ADMIN", "ADD/REMOVE USERS"));
map.put("AUDITOR", new AccessControl("ADMIN", "READ REPORTS"));
}

public static AccessControl getAccessControlObject(String controlLevel) {


AccessControl ac = null;
ac = map.get(controlLevel);
if (ac != null) {
return ac.clone();
}
return null;
}
}

Objektno orijentirano programiranje


25

design patterns

creational design patterns

singleton

• pattern koji garantira da postoji samo jedna instanca objekta i da je


ta instanca globalno dostupna

OOP
singleton
26

class Logger {
private static Logger instance;
private Logger() {}
public static Logger getInstance() {
if(instance == null) {
instance = new Logger();
}
return instance;
}
}

Objektno orijentirano programiranje


27

design patterns

structural design patterns

• patterni čiji je fokus kreiranje objekata u veće strukture


• služi za dizajniranje odnosa među objektima!

OOP
28

design patterns

structural

adapter

decorator

facade

proxy

OOP
29

design patterns

structural design patterns

adapter

• sparivanje interface-a različitih klasa


• koristi se između dva nezavisna i nekompatibilna interface-a
– na primjer, ako se koristi third-party kod, a ne smijemo ga
modificirati
• u sljedećem primjeru:
– imamo aplikaciju koja sortira nizove. Ovo je definirano kroz Sorter
interface
– NumberSorter je third-party biblioteka, i ona prihvaća samo Lists
– SortListAdapter prihvaća nizove, ali interno koristi NumberSorter

OOP
30

design patterns

structural design patterns

adapter

OOP
adapter
31
public class NumberSorter { //third party
public List<Integer> sort(List<Integer> numbers) {
//sortiraj i vrati
return new ArrayList<Integer>();
}
}

public interface Sorter {


public int[] sort(int[] numbers);
}

Objektno orijentirano programiranje


adapter
32

public class SortListAdapter implements Sorter {


private List<Integer> listNumbers;
private int[] arrayNumbers;
private NumberSorter numberSorter;
public int[] sort(int[] numbers) {
numberSorter = new NumberSorter();
return convertListToArray(numberSorter.sort(convertArrayToList(numbers)));
}
private List<Integer> convertArrayToList(int[] numbers) {
listNumbers = new ArrayList<Integer>();
for (int i = 0; i < numbers.length; i++) {
listNumbers.add(numbers[i]);
}
return listNumbers;
}
private int[] convertListToArray(List<Integer> numbers) {
arrayNumbers = new int[numbers.size()];
for (int i = 0; i < numbers.size(); i++) {
arrayNumbers[i] = numbers.get(i);
}
return arrayNumbers;
}
}

Objektno orijentirano programiranje


adapter
33

public class Client implements Sorter {


private SortListAdapter adapter;
public int[] sort(int[] numbers) {
adapter = new SortListAdapter();
return adapter.sort(numbers);
}
}

Objektno orijentirano programiranje


34

design patterns

structural design patterns

bridge

OOP
35

design patterns

structural design patterns

bridge

• služi za odvajanje interface-a od implementacija ukoliko postoji


hijerarhija
• Smatra se starijim patternom kod kojeg vrijedi "kompozicija je bolja
od nasljeđivanja".

OOP
36

design patterns

structural design patterns

composite

• omogućuje da se grupa objekata tretira kao jedan objekt

OOP
composite
37

interface Node {
long getSize();
}

public class File implements Node {


private long size;

public long getSize() {


return size;
}
}

public class Folder implements Node {


private List<Node> children = new ArrayList<Node>();
private long size;
public long getSize() {
long totalSize = this.size;
for(Node child in children) {
totalSize += child.getSize();
}
return totalSize;
}
}

Objektno orijentirano programiranje


38

design patterns

structural design patterns

decorator

• dodavanje funkcionalnosti objektu za vrijeme runtime-a bez


mijenjanja njegove strukture
facade

• jedna klasa koja predstavlja cijeli podsustav


• predstavlja jedan ili više objekata "iza fasade"

OOP
39

design patterns

structural design patterns

proxy

• objekt koji predstavlja drugi objekt

OOP
40

design patterns

behavioral design patterns

• patterni koji vode računa o komunikaciji među objektima


• u većini slučajeva, smanjuju se ovistnosti među
objektima koji međusobno komuniciraju

OOP
41

design patterns

behavioral

observer

strategy

command

state

chain of responsability

visitor

OOP
42

design patterns

behavioral design patterns

chain of responsability

• način prenošenja zahtjeva u lancu objekata

OOP
chain of responsability
43

public abstract class Middleware {


private Middleware next;

public Middleware linkWith(Middleware next) {


this.next = next;
return next;
}

public abstract boolean check(String email, String password);

protected boolean checkNext(String email, String password) {


if (next == null) {
return true;
}
return next.check(email, password);
}
}

Objektno orijentirano programiranje


chain of responsability
44

public class UserExistsMiddleware extends Middleware {


public boolean check(String email, String password) {
if (!UserService.exists(email, password)) {
return false;
}
return checkNext(email, password);
}
}

public class RoleCheckMiddleware extends Middleware {


public boolean check(String email, String password) {
if (email.equals("admin@example.com")) {
System.out.println("Hello, admin!");
return true;
}
System.out.println("Hello, user!");
return checkNext(email, password);
}
}

Objektno orijentirano programiranje


chain of responsability
45

public class client {

public static void main(String[] args) throws IOException {


Middleware middleware = new UserExistsMiddleware();
middleware.linkWith(new RoleCheckMiddleware());

boolean canUserLoginAsAdmin =
middleware.check("admin@example.com", "S3cret");
}
}

Objektno orijentirano programiranje


46

...

Objektno orijentirano programiranje


47

nost sustava
Kompleks

Objektno orijentirano programiranje


48

Kompleksnost
„The more complex the system, the more open it is to total
breakdown”

• Naknadni zahtjevi – npr. građevinski radovi dodavanja podruma


ispod zgrade od 100 katova
• Prilikom izrade softvera korisnici često traže upravo nešto slično
– „sve je to samo malo isprogramirati”
• Problemi kod savladavanja kompleksnosti softvera dovode do:
– kašnjenja projekata
– povećanja cijene
– lošeg softvera

Objektno orijentirano programiranje


49

Kompleksnost
• Loša organizacija kompleksnih projekata vodi:
– neučinkovitom korištenju ljudskih resursa
– gubitak prilika na tržištu

• Nema dovoljno dobrih developera da bi se loše vodilo projekt


• Dio snaga je često samo posvećen održavanju i nadogradnjama
• Najbitnije je u startu početi s ispravnim konceptom i dizajnom
arhitekture našeg softvera
• Naknadne promjene vode velikim troškovima i softverom teškim za
održavanje

Objektno orijentirano programiranje


50

Definiranje kompleksnosti sustava


• Postoje određene kategorije softvera koji nisu kompleksni
• Obično su to aplikacije koje je napravila, održava i koristi ista osoba
• Takav softver ima ograničenu svrhu i životni vijek
• Možemo priuštiti odbacivanje takvog softvera i iznova napraviti
novi ako nam zatreba drukčija funkcionalnost
• S druge strane postoji tzv. industrijski softver
• Sadrži vrlo bogatu lepezu ponašanja!
– npr. reagira na događaje iz stvarnog svijeta
• Primjer: sustav za kontrolu leta
• Takav tip softvera ima dug životni vijek

Objektno orijentirano programiranje


51

Definiranje kompleksnosti sustava


• Veliki broj ljudi ovisi o ispravnom funkcioniranju softvera!
• Kod industrijskog softvera postoji i framework za izradu
komponenti za određenu domenu
• Framework olakšava izradu softvera korištenjem već dizajniranih
funkcionalnosti
• Kod industrijskog softvera velikih razmjera nemoguće je da
developer (pojedinac) razumije cjelokupni sustav u potpunosti
• Kompleksnost cjelokupnog takvog sustava nadilazi kapacitet
pojedinog čovjeka
• Možemo savladati ovakvu kompleksnost apstrakcijom, ali ona i
dalje postoji

Objektno orijentirano programiranje


52

Kompleksnost problemske domene


• Problemi koje rješavamo prilikom dizajna softvera često uključuju
neizbježne elemente kompleksnosti, gdje nailazimo na veliku
količinu zahtjeva koji su čestu neusklađeni, a ponekad i
kontradiktorni
• Uzmimo probleme autonomnih robota, ili centrale za mobitele –
osnovna funkcionalnost je u startu kompleksna –
– sada treba dodati i nefunkcionalne zahtjeve kao što su usability,
performanse, cijena, pouzdanost…
• Ovakvi zahtjevi se često sami po sebi podrazumijevaju
• Korisnici često ne znaju ni jasno artikulirati svoje zahtjeve
– „komunikacijski jaz”

Objektno orijentirano programiranje


53

Kompleksnost problemske domene


• Često korisnici imaju samo nejasnu ideju što žele u softverskom
sustavu
• Nemogućnost potpune komunikacije nije greška ni korisnika ni
developera
• Oboje često nemaju znanja o domeni onog drugog i imaju drukčiju
perspektivu o problemu i potencijalom rješenju
• Dodatnu kompleksnost uvodi i činjenica da se zahtjevi mijenjaju
tijekom razvoja
• Rani prototipovi često korisnika natjeraju da preispita, promjeni ili
nadopuni svoje zahtjeve te bolje artikulira svoje potrebe

Objektno orijentirano programiranje


54

Poteškoće upravljanja razvojnim procesom


• Koristimo različite mehanizme (framework i sl.) da bi reducirali broj
linija koda i povećali jednostavnost
• Danas nije neuobičajeno da se broj linija koda mjeri u stotinama
tisuća ili milijunima (i to u high-order programskim jezicima)
• Pojedina osoba ne može toliki sustav u cijelosti poznavati
• Timski rad – po mogućnosti manji timovi
• Veliki timovi: otežana komunikacija, koordinacija, geografska
ograničenja

Objektno orijentirano programiranje


55

Objektno orijentirano programiranje


56

Nošenje s kompleksnošću
• Razvoj kompleksnih sustava je iznimno zahtjevan
• System architects – ljudi koji definiraju arhitekturu novog sustava
• Uloga procesa dekompozicije
– „podijeli pa vladaj”
• Algoritamska dekompozicija
– problem razlaže na slijed događaja ili funkcija
• Objektno-orijentirana dekompozicija
– definira povezanost i međusobnu komunikaciju među
objektima u sustavu

Objektno orijentirano programiranje


57

Algoritamska dekompozicija
• Većina ljudi za dekompoziciju koristi pristup algoritamske
dekompozicije gdje se važniji procesi definiraju kao veće cjeline u
sustavu
Naruči i plati karticom

Provjera narudžbe Provjera kartice Obavljanje narudžbe Izvršenje

Postoji li Provjeri Ažuriraj


Dovoljna Provjeri Ažuriraj Ažuriraj Pošalji
roba u valjanost knjigu
količina? CVC skladište karticu knjige
skladištu? kartice računa

Provjeri Provjeri
valjanost stanje na
u banci računu

Objektno orijentirano programiranje


58

OOP dekompozicija
• Umjesto dekompozicije u korake/procese, radi se dekompozicija u objekte
• Oba pristupa rješavaju problem, ali na različite načine
• U OO pristupu gledamo na svijet kao na skup autonomnih agenata koji
surađuju da bi odradili kompleksnije zadatke
Provje
ra
Narudžba na skl stanja
adištu
Aktivi
ti

ra
os

nje na
rudžb Skladište
n

Pro račun

e
lja
va

vje

e
jig
a

ra s a
jer

k n Is
po
ov

je na
ta n

n ru
Pr

r ira aču ka
ja

u r

Kartica
Bankovni
račun Knjiga Kupac
računa

Objektno orijentirano programiranje


59

Algoritamska ili OO dekompozicija


• Oba pristupa su važna
• Algoritamska dekompozicija naglašava redoslijed događaja u
nekom procesu
• OO dekompozicija naglašava koji su agenti (objekti) inicijatori neke
aktivnosti, a koji su oni na kojima odrađuju radnje
• Ne možemo dizajnirati sustav simultano koristeći oba procesa
• Za kompleksne sustave uobičajeno je koristiti OO dekompoziciju
budući da je na takav načni lakše organizirati kompleksne sustave
• OO dekompozicija rezultira manjim sustavima (code reuse)
• OO sustavi su otporniji na buduće promjene i bolje evoluiraju kroz
vrijeme zbog stabilnih među-faza

Objektno orijentirano programiranje


60

Zaključak
• Većina sustava je u svojoj biti kompleksna
• Kompleksnost sustava često nadmašuje ljudsku
intelektualnu sposobnost
• Zadatak razvojnog tima je stvoriti sliku jednostavnosti
• Kompleksni sustavi često dolazi u formi hijerarhije
• Kompleksnost nastaje tijekom vremena. Razvojem nastaju
stabilne među faze sustava

Objektno orijentirano programiranje


Objektno orijentirano
programiranje

KRAJ

You might also like