24
Extras Curs ISw-2007 2007-2008 1/25 11/22/2007 2007 Extras curs ISw.doc ______ Proces de construcţie prin descompunere-reunire (top-down) generic Descompunere (funcţională / OO) Analiză (funcţională / OO) Construcţie a componentelor Produs Compunere (integrare) Specificatii Proiect Componente Descompunere funcţională ierarhică Descompunere în “societati” de obiecte Func ţ ie principal ă Sub-func ţie B Sub-funcţ ie A Sub-func ţie A1 Sub-func ţie A2 Sub-func ţie B1 Sub-func ţie B2 Buton Cabină Uşă Bec Aprindere Deschidere Deplasare Actionare Lift (sistem) Utilizator 1. Clasa = tipul (domeniul de definitie) pentru variabile numite obiecte 2. Obiectul = reprezentare abstractă a unor entităţi reale sau virtuale, caracterizată de: - identitate, prin care e deosebit de alte obiecte, implementata ca variabila referinta la obiect, - comportament (vizibil), accesibil altor obiecte, implementata ca set de functii membru = operatii, metode, - stare internă (ascunsă), proprie obiectului, implementata ca set de variabile membru = atribute, campuri. 3. Definitia clasei in Java: 1 2 3 4 5 6 7 class Nume { // declaratie tip de date / structura de date tip atribut; // declaratie variabila membru, camp Java tipReturnat operatie (tipParametru parametruFormal) { // semnatura metoda Java // corpul functiei membru (metodei) – returneaza valoare de tipul tipReturnat } } 4. Declararea variabilei referinta la un obiect Java si crearea dinamica a obiectului : NumeClasa numeObiect; // declararea variabilei referinta la obiect numeObiect = new NumeClasa(tipParametru parametruActual); // crearea dinamica a obiectului - UML: clasa obiectul: Declaratii (specificare) variabile 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class Point { // atribute (variabile membru) private int x; private int y; // operatie care initializeaza atributele = constructor Java public Point (int abscisa, int ordonata) { x = abscisa; y = ordonata; } // operatii care modifica atributele = metode (functii membru) public void moveTo (int abscisaNoua, int ordonataNoua) { x = abscisaNoua; y = ordonataNoua; } public void moveWith (int deplasareAbsc, int deplasareOrd) { x = x + deplasareAbsc; y = y + deplasareOrd; } // operatii prin care se obtin valorile atributelor = metode Java public int getX () { return x; } public int getY () { return y; } } Semnaturi (declaratii, specificari) operatii + Implementari (corpuri) operatii 1 2 3 4 5 6 7 8 9 public class RunPoint { // clasa de test pentru clasa Point private static Point punctA; // atribut de tip Point public static void main (String[] args) { // declaratie metoda // corp metoda punctA = new Point (3, 4); // alocare si initializare atribut punctA punctA.moveTo (3, 5); // trimitere mesaj moveTo () catre punctA punctA.moveWith (3, 5); // trimitere mesaj moveWith () catre punctA } numeObiect : NumeClasa Nume atribut : tip operatie(parametruFormal : tipParametru) : tipReturnat

ţie prin descompunere-reunire top-down) genericdiscipline.elcom.pub.ro/isw/2007 Extras curs ISw pag 1-24.pdf · } // Alti constructori, alte metode... // Returneaza adresa IP a masinii

  • Upload
    vudiep

  • View
    225

  • Download
    0

Embed Size (px)

Citation preview

Extras Curs ISw-2007 2007-2008 1/25 11/22/2007 2007 Extras curs ISw.doc

______

Proces de construcţie prin descompunere-reunire (top-down) generic

Descompunere (funcţională / OO)

Analiză (funcţională / OO) Construcţie a

componentelor

Produs

Compunere (integrare)

Specificatii Proiect Componente

Descompunere funcţională ierarhică Descompunere în “societati” de obiecte

Funcţie principală

Sub-funcţie B Sub-funcţie A

Sub-funcţie A1 Sub-funcţie A2 Sub-funcţie B1 Sub-funcţie B2

Buton

Cabină Uşă

Bec Aprindere

Deschidere

Deplasare

Actionare

Lift (sistem)

Utilizator

1. Clasa = tipul (domeniul de definitie) pentru variabile numite obiecte

2. Obiectul = reprezentare abstractă a unor entităţi reale sau virtuale, caracterizată de: - identitate, prin care e deosebit de alte obiecte, implementata ca variabila referinta la obiect, - comportament (vizibil), accesibil altor obiecte, implementata ca set de functii membru = operatii, metode, - stare internă (ascunsă), proprie obiectului, implementata ca set de variabile membru = atribute, campuri.

3. Definitia clasei in Java:

1 2 3 4 5 6 7

class Nume { // declaratie tip de date / structura de date tip atribut; // declaratie variabila membru, camp Java tipReturnat operatie(tipParametru parametruFormal) { // semnatura metoda Java // corpul functiei membru (metodei) – returneaza valoare de tipul tipReturnat } }

4. Declararea variabilei referinta la un obiect Java si crearea dinamica a obiectului:

NumeClasa numeObiect; // declararea variabilei referinta la obiect numeObiect = new NumeClasa(tipParametru parametruActual); // crearea dinamica a obiectului

- UML: clasa obiectul:

Declaratii (specificare) variabile

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22

public class Point { // atribute (variabile membru) private int x; private int y; // operatie care initializeaza atributele = constructor Java public Point(int abscisa, int ordonata) { x = abscisa; y = ordonata; } // operatii care modifica atributele = metode (functii membru) public void moveTo(int abscisaNoua, int ordonataNoua) { x = abscisaNoua; y = ordonataNoua; } public void moveWith(int deplasareAbsc, int deplasareOrd) { x = x + deplasareAbsc; y = y + deplasareOrd; } // operatii prin care se obtin valorile atributelor = metode Java public int getX() { return x; } public int getY() { return y; } }

Semnaturi (declaratii, specificari) operatii + Implementari (corpuri) operatii

1 2 3 4 5 6 7 8 9

public class RunPoint { // clasa de test pentru clasa Point private static Point punctA; // atribut de tip Point public static void main(String[] args) { // declaratie metoda // corp metoda punctA = new Point(3, 4); // alocare si initializare atribut punctA punctA.moveTo(3, 5); // trimitere mesaj moveTo() catre punctA punctA.moveWith(3, 5); // trimitere mesaj moveWith() catre punctA }

numeObiect : NumeClasa

Nume atribut : tip

operatie(parametruFormal : tipParametru) : tipReturnat

Extras Curs ISw-2007 2007-2008 2/25 11/22/2007 2007 Extras curs ISw.doc

______

10 }

5. Crearea unui obiect p1 de tip Point ale carui atribute au valorile x=3 si respectiv y=4 :

Point p1 = new Point(3, 4);

Obiectul p1 de tip Point incapsuleaza informatiile unui punct in plan de coordonate {3, 4}. Starea obiectului p1 este perechea de coordonate {3, 4}.

6. Schimbarea starii obiectului p1 in {3, 5}, prin deplasarea ordonatei (departarea cu 1 de abscisa).

Point p1 = new Point(3, 4); p1.moveTo(3, 5);

7. Mesajul selecteaza operatia si declanseaza comportamentul (activeaza operatia, prin invocarea / apelul metodei / functiei membru):

8. Starea si comportamentul sunt dependente. Comportamentul la un moment dat depinde de starea curenta. Starea poate fi modificata prin comportament.

In starea “In zbor” doar comportamentul Aterizare e posibil. El duce la schimbarea starii (in “La sol”). Dupa aterizare, starea fiind “La sol”, operatia Aterizare nu mai are sens.

9. Sistemele software OO sunt societăţi de obiecte care colaborează pentru a realiza funcţiile aplicaţiei.

Obiect utilizator

Mesaj

Legătură

Interacţiune a obiectelor Comunicaţie între obiecte

Colaborare între obiecte

Decuplare intre obiecte

Declanşare (executie)

Referinţă

Obiect tinta comportament global

al sistemului (scenarii =

secvenţe de mesaje = colaborări între obiecte) Operaţie

punctA : PointRunPoint

moveTo()

Mesajul selecteaza

comportamentul

1: moveTo(3, 5)2: moveWith(3, 5)

moveWith()

RunPoint

+ main()

Point- x : int- y : int

+ Point(abscisa : int, ordonata : int)+ moveTo(abscisaNoua : int, ordonataNoua : int) : void + getX() : int+ getY() : int+ moveWith(deplasareAbsc : int, deplasareOrd : int) : void

-punctA

p1 : Point

x = 3y = 5

p1 : Point x = 3 y = 4

dupa operatia moveTo(3,5)

p1 : Point

x = 3y = 4

: Turn de control

: Avion

In zbor

: Avion La sol

Aterizare

Decolare

Extras Curs ISw-2007 2007-2008 3/25 11/22/2007 2007 Extras curs ISw.doc

______

Elementele declaratiilor: 1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

import java.util.Vector; // clase importate import java.util.EmptyStackException; public class Stack // declaratia clasei { // inceputul corpului clasei private Vector elemente; // atribut (variabila membru) public Stack() { // constructor elemente = new Vector(10); // (functie de initializare) } public Object push(Object element) { // metoda elemente.addElement(element); // (functie membru) return element; } public synchronized Object pop(){ // metoda int lungime = elemente.size(); // (functie membru) Object element = null; if (lungime == 0) throw new EmptyStackException(); element = elemente.elementAt(lungime - 1); elemente.removeElementAt(lungime - 1); return element; } public boolean isEmpty(){ // metoda if (elemente.size() == 0) // (functie membru) return true; else return false; } } // sfarsitul corpului clasei

Declaratia de clasa [public] [abstract] [final] class NumeClasa [extends NumeSuperclasa] [implements NumeInterfata [, NumeInterfata]] { // Corp clasa }

Declaratia de camp (atribut) [nivelAcces] [static] [final] tipAtribut numeAtribut;

Declaratia de constructor [nivelAcces] NumeClasa( listaParametri ) { // Corp constructor }

Declaratia de metoda (operatie) [nivelAcces] [static] [abstract] [final] [synchronized] tipReturnat numeMetoda (

[listaDeParametri] ) [throws NumeExceptie [,NumeExceptie] ] { // Corp metoda }

Scopul variabilelor

Extras Curs ISw-2007 2007-2008 4/25 11/22/2007 2007 Extras curs ISw.doc

______

Exemplu

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

public class Complex // declaratia clasei { // inceputul corpului clasei private double real; // real = atribut (camp) private double imag; // imag = atribut (camp) public void setReal(double real) { // metoda, real = parametru this.real = real; // real = atributul, real = parametrul } public void.setImag(double imag) { // metoda, imag = parametru this.imag = imag; // imag = atributul, imag = parametrul } public static void main(String[] args) { // metoda, args = parametru double real = Double.parseDouble(args[0]); // real = variabila locala double imag = Double.parseDouble(args[1]); // imag = variabila locala Complex c = new Complex(); // c = variabila locala c.setReal(real); // c, real = variabilele locale c.setImag(imag); // c, imag = variabilele locale System.out.println("{" + c.real + // c.real = atributul lui c ", " + c.imag + "}"); // c.imag = atributul lui c } } // sfarsitul corpului clasei

Clasa contine generalitatile (abstractiile generale), obiectele contin particularitatile (detaliile particulare).

Obiect Obiect

Clasă

Obiect

= generalităţi (elemente, aspecte, caracteristici comune)

= particularităţi (elemente, aspecte, caracteristici diferite)

O parte din codul clasei DatagramPacket (continuturile anumitor metode au fost simplificate):

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

package java.net; // Importul pachetulului de clase Java pentru comunicatii IP public final class DatagramPacket { // incapsuleaza pachete UDP (datagrame) // Atribute, accesibile tuturor claselor din pachetul (directorul) java.net byte[] buf; // tabloul de octeti care contine datele pachetului int offset; // indexul de la care incep datele pachetului int length; // numarul de octeti de date din tabloul de octeti int bufLength; // lungimea tabloului de octeti InetAddress address; // adresa IP a masinii sursa/destinatie a pachetului int port; // portul UDP al masinii sursa/destinatie a pachetului // Constructori – initializeaza obiectele de tip DatagramPacket // Initializeaza un DatagramPacket pentru pachete de receptionat, public DatagramPacket(byte buf[], int length) { this.buf = buf; this.length = length; this.bufLength = length; this.offset = 0; this.address = null; this.port = -1; } // Initializeaza un DatagramPacket pentru pachete de trimis public DatagramPacket(byte buf[], int length, InetAddress address, int port) { this.buf = buf; this.length = length; this.bufLength = length; this.offset = 0; this.address = address; this.port = port; } // Alti constructori, alte metode... // Returneaza adresa IP a masinii sursa/destinatie a acestui pachet public synchronized InetAddress getAddress() { return this.address; } // Stabileste adresa IP a masinii sursa/destinatie a acestui pachet public void setAddress(InetAddress iaddr) { this.address = iaddr; } }

Extras Curs ISw-2007 2007-2008 5/25 11/22/2007 2007 Extras curs ISw.doc

______

Cod care utilizeaza clasa DatagramPacket:

byte[] buffer = new byte[1024]; // buffer date (de trimis/primit)

DatagramPacket packetDeTrimis = new DatagramPacket(buffer, buffer.length, InetAddress.getByName(“nume.elcom.pub.ro”), 2000);

DatagramPacket packetDeReceptionat = new DatagramPacket(buffer, buffer.length);

Specificatia generala a unei clase Complex (interfata publica) = API-ul (Application Programming Interface):

1 2 3 4 5 6 7 8 9

public class Complex { // Atribute private (ascunse, inaccesibile din exteriorul clasei) // Constructor – initializeaza obiectele de tip Complex public Complex(double real, double imag) { // Implementare } public double getReal() { // Implementare } // Returneaza partea reala public double getImag() { // Implementare } // Returneaza partea imaginara public double getModul() { // Implementare } // Returneaza modulul public double getFaza() { // Implementare } // Returneaza faza }

Urmatorul cod Java va conduce la acelasi rezultat, indiferent de implementarea clasei Complex:

Complex c1 = new Complex(2, -2);

System.out.println(“Coordonatele carteziene: {” + c1.getReal() + “, ” + c1.getImag() + “}”);

System.out.println(“Coordonatele polare: {” + c1.getModul() + “, ” + c1.getFaza() + “}”);

Implementarea carteziana a clasei Complex (atributele ascunse sunt coordonatele carteziene):

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16

public class Complex { private double real; // partea reala (abscisa) private double imag; // partea imaginara (ordonata) public Complex(double real, double imag) { this.real = real; this.imag = imag; } public double getReal() { return this.real; } public double getImag() { return this.imag; } public double getModul() { return Math.sqrt(this.real*this.real + this.imag*this.imag); } public double getFaza() { return Math.atan2(this.real, this.imag); } }

Implementarea polara a clasei Complex (atributele ascunse sunt coordonatele polare):

1 2 3 4 5 6 7 8 9

10 11 12

public class Complex { private double modul; // modulul (raza) private double faza; // faza (unghiul) public Complex(double real, double imag) { this.modul = Math.sqrt(real*real + imag*imag); this.faza = Math.atan2(real, imag); } public double getReal() { return this.modul*Math.cos(this.faza); } public double getImag() { return this.modul*Math.sin(this.faza); } public double getModul() { return this.modul; } public double getFaza() { return this.faza; } }

In cazul de mai sus: • specificaţia nu este afectată de schimbarea reprezentării interne (polară sau carteziană), • obiectele utilizator al obiectelor instanţe ale clasei numerelor complexe cunosc doar specificaţia şi nu sunt nici ele

afectate de schimbarea reprezentării interne.

Agregarea exprimă cuplajul strâns între clase (subordonare: “master-slave”, “întreg-părţi”, “ansamblu-componentă”).

In UML: Exemplu:

java.lang.System

java.io.PrintStream

+ println()

+out

ClasaSubordonata

ClasaAgregat

Extras Curs ISw-2007 2007-2008 6/25 11/22/2007 2007 Extras curs ISw.doc

______

Mostenirea in UML: Declaratia:

class NumeClasa { // urmeaza corpul clasei ... este echivalenta cu:

class NumeClasa extends Object { // urmeaza corpul clasei ...

Metoda toString()

1 2 3 4 5 6

// Implementarea implicita a metodei toString(), mostenita de la clasa Object public String toString() { // (nu returneaza continutul ci numele clasei si codul obiectului!) return getClass().getName() + "@" + Integer.toHexString(hashCode()); }

Metoda equals() implicita

1 2 3 4 5

// Implementarea implicita a metodei equals(), mostenita de la clasa Object public boolean equals(Object obj) { return (this == obj); // (nu compara continutul ci referintele!!!) }

Metoda equals() din clasa String

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20

// Implementarea explicita a metodei equals() in clasa String public boolean equals(Object obj) { // se verifica existenta unui parametru (obiect) non-null // si faptul ca parametrul e obiect al clasei String if ((obj != null) && (obj instanceof String)) { String otherString = (String)obj; // conversie de tip int n = this.count; if (n == otherString.count) { // se compara numarul de caractere char v1[] = this.value; char v2[] = otherString.value; int i = this.offset; int j = otherString.offset; while (n-- != 0) if (v1[i++] != v2[j++]) return false; // se compara caracterele return true; } } return false; }

Clasa abstracta, de baza

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18

public abstract class Multime { // clasa declarata abstract protected Object[] elemente; // campuri declarate protected pentru a protected byte numarElem; // putea fi reutilizate in clasa derivata public Multime(Object[] elemente) { // parametru generic tip Object[] this.elemente = elemente; // acces la obiectul curent cu this numarElem = (byte) elemente.length; // conversie de tip de la int la byte } public abstract Multime intersectieCu(Multime m); // declarata abstract (NEIMPLEMENTATA) // valoare returnata generica tip Multime public Object[] obtinereElemente() { // valoare returnata generica tip Object[] return elemente; // (MOSTENITA in clasa MultimeIntregi) } public byte numarElemente() { // implementare de baza return numarElem; // (RESCRISA in clasa MultimeIntregi) } }

java.lang.Object

+ toString() + equals() + ...()

ClasaNoua

ClasaAbstracta

+ metodaNeimplementata() : void

ClasaConcreta

+ metodaNeimplementata() : void

metodaNeimplementata() este aici implementata!

Extras Curs ISw-2007 2007-2008 7/25 11/22/2007 2007 Extras curs ISw.doc

______

Clasa concreta, derivata

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

public class MultimeIntregi extends Multime { public MultimeIntregi(Integer[] elemente) { // parametru concret tip Integer[] super(elemente); // apelul constructorului clasei de baza Multime } public final Multime intersectieCu(Multime m) { // declarata abstract in clasa de baza Integer[] elementeIntersectie; // aici devine concreta (IMPLEMENTATA) int nrElemente = 0; for (int i=0; i< elemente.length; i++) for (int j=0; j< m.elemente.length; j++) if (elemente[i].equals(m.elemente[j])) nrElemente++; int index = 0; elementeIntersectie = new Integer[nrElemente]; for (int i=0; i< elemente.length; i++) for (int j=0; j< m.elemente.length; j++) if (elemente[i].equals(m.elemente[j])) elementeIntersectie[index++] = new Integer(elemente[i].toString()); return new MultimeIntregi(elementeIntersectie); } public byte numarElemente() { // reimplementare cod (RESCRIERE) return (byte) elemente.length; // conversie de tip de la int la byte } public boolean contine(int intr) { // metoda noua (EXTENSIE) for (int i=0; i< elemente.length; i++) { Integer inte = (Integer) elemente[i]; if (inte.intValue() == intr) { return true; } } return false; } }

Extindere prin mostenire, supraincarcare a metodelor, rescriere a metodelor, ascundere a atributelor:

1 2 3 4 5 6 7 8 9

10 11 12 13 14

public class ClasaDeBaza { protected int atributMostenit; // atribut partajat cu subclasa protected byte atributAscuns; // atribut corespunzator clasei de baza public void metodaMostenitaSupraincarcata() { // implementare corespunzatoare lipsei parametrilor } public void metodaMostenitaSupraincarcata(int argument) { // implementare corespunzatoare parametrului de tip int } public void metodaRescrisa() { // implementare de baza } }

1 2 3 4 5 6 7 8 9

10 11

public class ClasaCareExtinde extends ClasaDeBaza { protected byte atributAscuns; // atribut corespunzator subclasei protected long atributNou; // atribut nou, nepartajat cu clasa de baza public void metodaRescrisa() { // reimplementare (rescriere a codului) } public void metodaNoua() { // metoda noua, nepartajata cu clasa de baza } }

1 2 3 4 5 6 7 8 9

10 11 12 13 14

public class UtilizareClase { public static void main(String[] args) { ClasaDeBaza obiectDeBaza = new ClasaDeBaza(); // clasa de baza (extinsa) obiectDeBaza.atributMostenit // utilizarea atributului partajat cu subclasa obiectDeBaza.atributAscuns // utilizarea atributului din clasa de baza // apelurile metodelor (din clasa de baza) care supraincarca acelasi nume obiectDeBaza.metodaMostenitaSupraincarcata() obiectDeBaza.metodaMostenitaSupraincarcata(1000) // apelul metodei din clasa de baza (implementare de baza) obiectDeBaza.metodaRescrisa()

Extras Curs ISw-2007 2007-2008 8/25 11/22/2007 2007 Extras curs ISw.doc

______

15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

ClasaCareExtinde obiectExtins = new ClasaCareExtinde(); // subclasa obiectExtins.atributNou // utilizarea atributului nou obiectExtins.atributMostenit // utilizarea atributului partajat obiectExtins.atributAscuns // utilizarea atributului din subclasa super.atributAscuns // utilizarea atributului din clasa de baza // apelul metodei noi din subclasa obiectExtins.metodaNoua() // apelurile metodelor (din clasa de baza) care supraincarca acelasi nume obiectExtins.metodaMostenitaSupraincarcata() obiectExtins.metodaMostenitaSupraincarcata(1000) // apelul metodei din subclasa (implementarea noua, rescrisa) obiectExtins.metodaRescrisa() // apelul metodei din clasa de baza (implementare de baza) super.metodaRescrisa() } }

Implementarea unei interfete de tip stiva: 1 2 3 4 5 6

public interface StackInterface { boolean empty(); void push( Object x); Object pop() throws EmptyStackException; Object peek() throws EmptyStackException; }

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15

public class Stack implements StackInterface { private Vector v = new Vector(); // utilizeaza clasa java.util.Vector public void push(Object item) { v.addElement(item); } public Object pop() { Object obj = peek(); v.removeElementAt(v.size() - 1); return obj; } public Object peek() throws EmptyStackException { if (v.size() == 0) throw new EmptyStackException(); return v.elementAt(v.size() - 1); } public boolean empty() { return v.size() == 0; } }

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16

public class Stack extends Vector implements StackInterface { public Object push(Object item) { addElement(item); return item; } public Object pop() { Object obj; int len = size(); obj = peek(); removeElementAt( len - 1); return obj; } public Object peek() { int len = size(); if (len == 0) throw new EmptyStackException(); return elementAt( len - 1); } public boolean empty() { return size() == 0;} }

1 2 3 4

Vector v = new Stack(); // cod legal – referinta la clasa de baza // poate fi initializata cu obiect din subclasa v.insertElementAt(x, 2); // cod legal – dar inserarea unui obiect in stiva // incalca principiul de functionare al stivei

Constrangeri ale tipurilor valorilor returnate (constrangeri similare exista pentru tipurile parametrilor)

Tip posibil

public Number returnANumber() { // . . .}

Tip nepermis

Subclasa

Superclasa

Extras Curs ISw-2007 2007-2008 9/25 11/22/2007 2007 Extras curs ISw.doc

______

Asocierile bidirectionale intre doua clase corespund situatiei in care ambele clase au referinte una catre cealalta. Diagrama UML:

ConstructiePachet

+ crearePachet()

LivrarePachet

+ trimiterePachet()

consumatorproducator

public void crearePachet() { // creare consumator.trimiterePachet()}

public void TrimiterePachet() { // trimitere producator.crearePachet()}

are drept corespondent codul Java:

public class ConstructiePachet { LivrarePachet consumator; public void crearePachet( /* eventuali parametri */ ) { // creare consumator.trimiterePachet() } }

public class LivrarePachet {

ConstructiePachet producator; public void trimiterePachet( /* eventuali parametri */ ) { // trimitere producator.crearePachet() } }

Generalizarea = extragerea elementelor comune (atribute, operaţii şi constrângeri) ale unui ansamblu de clase într-o nouă clasă mai generală, denumită superclasă,

- superclasa este o abstracţie a subclaselor ei, - arborii de clase sunt construiţi pornind de la frunze - utilizată cand elementele modelului au fost identificate, pentru a obţine o descriere detaşată a soluţiilor - semnifică "este un (fel de)" sau "este ca", şi priveşte doar clasele, adică nu este instanţiabilă

Obiect

Clasă

Obiect

Obiect

Clasă nouă = superclasă (generalităţi, elemente comune)

Obiect

Obiect

Clasă

Obiect

Obiect

Obiect

De fapt, generalizarea actioneaza in OO la doua niveluri: - clasele sunt generalizari ale ansamblurilor de obiecte (un obiect este de felul specificat de o clasa), - superclasele sunt generalizari de clase (obiectele de felul specificat in clasa sunt si de felul specificat in superclasa).

Limbajele OO ofera ambele mecanisme de generalizare. Limbajele care ofera doar constructii numite obiecte (si eventual clase) se pot numi limbaje care lucreaza cu obiecte (si eventual clase).

Specializarea = capturarea particularităţilor unui ansamblu de obiecte ale unei clase existente, noile caracteristici fiind reprezentate într-o nouă clasă mai specializată, denumită subclasă,

- utilă pentru extinderea coerentă a unui ansamblu de clase - bază a programării prin extindere şi a reutilizării, noile cerinţe fiind încapsulate în subclase care extind în mod

armonios (coerent) funcţiile existente

Obiect

Clasă

Obiect Obiect

Clasă nouă = subclasă (particularităţi, specializare)

Obiect Obiect

Obiect Obiect

Obiect

Extras Curs ISw-2007 2007-2008 10/25 11/22/2007 2007 Extras curs ISw.doc

______

Moştenirea = tehnică de generalizare oferită de limbajele OO pentru a construi o clasă pornind de la una sau mai multe alte clase, partajând atributele, operaţiile şi uneori constrângerile, într-o ierarhie de clase.

Diagramei UML:

Multime# elemente : Object[]# numarElem : byte

+ Multime(elemente : Object[])+ intersectieCu(m : Multime) : Multime+ obtinereElemente() : Object[]+ numarElemente() : byte

ii corespunde codul Java:

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20

public abstract class Multime { // clasa declarata abstract protected Object[] elemente; protected byte numarElem; public Multime(Object[] elemente) { // parametru generic tip Object[] this.elemente = elemente; // acces la obiectul curent cu this numarElem = (byte) elemente.length; // conversie de tip de la int la byte } public abstract Multime intersectieCu(Multime m); // metoda declarata abstract // valoare returnata generica tip Multime public Object[] obtinereElemente() { // valoare returnata generica tip Object[] return elemente; } public byte numarElemente() { // implementare de baza return numarElem; } }

Diagramei UML:

Multime# elemente : Object[]# numarElem : byte

+ Multime(elemente : Object[])+ intersectieCu(m : Multime) : Multime+ obtinereElemente() : Object[]+ numarElemente() : byte

MultimeIntregi

+ MultimeIntregi(elemente : Integer[])+ intersectieCu(m : Multime) : Multime+ numarElemente() : byte+ contine(intr : int) : boolean

MultimeDouble

+ MultimeDouble(elemente : Double[])+ intersectieCu(m : Multime) : Multime

ii corespunde codul Java:

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18

public class MultimeIntregi extends Multime { public MultimeIntregi(Integer[] elemente) { // parametru concret tip Integer[] super(elemente); // apelul constructorului clasei de baza Multime cu super } public final Multime intersectieCu(Multime m) { // implementarea metodei // declarata abstract in clasa de baza Multime mNoua; Integer[] elementeIntersectie; int nrElemente = 0; for (int i=0; i< elemente.length; i++) { for (int j=0; j< m.elemente.length; j++) { if (elemente[i].equals(m.elemente[j])) { nrElemente++; } }

Extras Curs ISw-2007 2007-2008 11/25 11/22/2007 2007 Extras curs ISw.doc

______

19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

} int index = 0; elementeIntersectie = new Integer[nrElemente]; for (int i=0; i< elemente.length; i++) { for (int j=0; j< m.elemente.length; j++) { if (elemente[i].equals(m.elemente[j])) { elementeIntersectie[index++] = new Integer(elemente[i].toString()); } } } mNoua = new MultimeIntregi(elementeIntersectie); return mNoua; } public byte numarElemente() { // reimplementare (rescriere cod) return (byte) elemente.length; // conversie de tip de la int la byte } public boolean contine(int intr) { // metoda noua for (int i=0; i< elemente.length; i++) { Integer inte = (Integer) elemente[i]; if (inte.intValue() == intr) { return true; } } return false; } }

Diagramei UML:

ii corespund codurile Java: - ale unei clase care extinde prin mostenire (extindere):

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15

public class MultimeIntregiExtinsaPrinMostenire extends MultimeIntregi { public MultimeIntregiExtinsaPrinMostenire(Integer[] elemente) { super(elemente); } public int sumaElemente() { // metoda noua int suma = 0; Integer[] ti = (Integer[]) elemente; // utilizare atribut mostenit elemente for (int i=0; i< ti.length; i++) { suma = suma + ti[i].intValue(); } return suma; } }

- ale unei clase care extinde prin delegare (compunere):

MultimeIntregi

+ MultimeIntregi(elemente : Integer[])+ intersectieCu(m : Multime) : Multime+ numarElemente() : byte+ contine(intr : int) : boolean

MultimeIntregiExtinsaPrinCompunere

+ MultimeIntregiExtinsaPrinCompunere(elemente : Integer[])+ sumaElemente() : int

TestMultimeIntregi

+ main(args : String[]) : void+ afisare(ia : Integer[]) : void+ afisareDouble(da : Double[]) : void

MultimeIntregiExtinsaPrinMostenire

+ MultimeIntregiExtinsaPrinMostenire(elemente : Integer[]) + sumaElemente() : int

+$intregiDerivati

+intregi +intregi

+$intregiCompusi

Extras Curs ISw-2007 2007-2008 12/25 11/22/2007 2007 Extras curs ISw.doc

______

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15

public class MultimeIntregiExtinsaPrinCompunere { public MultimeIntregi intregi; // obiect componenta public MultimeIntregiExtinsaPrinCompunere(Integer[] elemente) { intregi = new MultimeIntregi(elemente); } public int sumaElemente() { // metoda noua int suma = 0; Integer[] ti = (Integer[]) intregi.obtinereElemente(); for (int i=0; i< ti.length; i++) { suma = suma + ti[i].intValue(); } return suma; } }

- ale unei clase care permite testarea comportamentului (si compararea modului de utilizare) in cele doua cazuri:

1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20

public class TestMultimeIntregi { public MultimeIntregi intregi; public static MultimeIntregiExtinsaPrinMostenire intregiDerivati; public static MultimeIntregiExtinsaPrinCompunere intregiCompusi; public static void main(String[] args) { int i; Integer[] tablouA = { new Integer(1), new Integer(3), new Integer(5) }; MultimeIntregi multimeA = new MultimeIntregi(tablouA); intregiCompusi = new MultimeIntregiExtinsaPrinCompunere(tablouA); int suma = intregiCompusi.sumaElemente(); System.out.println("Suma elementelor " + suma); intregiDerivati = new MultimeIntregiExtinsaPrinMostenire(tablouA); suma = intregiDerivati.sumaElemente(); System.out.println("Suma elementelor " + suma); } }

Subclasele (clasele care extind prin mostenire) pot sa:

- mareasca gradul de detaliere al obiectelor:

- adaugand noi atribute, inexistente in clasa de baza (detaliere mai mare a starilor obiectelor in subclasa)

- adaugand noi metode, inexistente in clasa de baza (detaliere mai mare a comportamentului in subclasa)

- mareasca gradul de concretete a obiectelor: - implementand eventualele metode abstracte din clasa de baza (mai multa concretete a comportamentului)

- introduca diferentieri ale obiectelor: - redeclarand unele atribute existente in clasa de baza (ascunderea – hiding - atributelor cu acelasi nume),

adica introducerea unei diferentieri a starii obiectelor din subclasa fata de cele din clasa de baza,

- reimplementand unele metode existente in clasa de baza (rescrierea – overriding - metodelor cu acelasi nume) adica introducerea unei diferentieri a comportamentului obiectelor din subclasa fata de clasa de baza

Subclasele mostenesc toate: - atributele din clasa de baza care nu sunt ascunse prin redeclarare,

- metodele din clasa de baza care nu sunt rescrise prin reimplementare.

Obiectele din subclasa au toate atributele declarate in clasa de baza, si pot utiliza toate metodele declarate in clasa de baza. Aceasta reutilizare a codului clasei de baza de catre subclase este principalul beneficiu al mostenirii.

Subclasele nu mostenesc

- constructorii clasei de baza (au constructori proprii), dar pot face apel la constructorii clasei de baza (daca se intampla acest lucru, apelul la constructorul clasei de baza, realizat prin apelul super(), trebuie sa fie prima declaratie din corpul constructorului subclasei),

- atributele cu caracter global (static),

- metodele cu caracter global (static).

Membrii globali (statici) ai clasei de baza nu pot fi mosteniti de obiectele din subclasa (tin strict de clasa in care au fost declarati).

Extras Curs ISw-2007 2007-2008 13/25 11/22/2007 2007 Extras curs ISw.doc

______

Descrierea unui caz de utilizare trebuie sa cuprinda urmatoarele elemente: 1. Numele cazului de utilizare (cat mai sugestiv, pentru a sintetiza cazul de utilizare).

Ex. Autentificarea utilizatorului 2. Scurta descriere a cazului de utilizare.

Ex. Utilizatorul ii transmite sistemului datele necesare autentificarii, si in caz de succes capata drept de acces la sistem. 3. Actori (entitati exterioare sistemului modelat, implicate in cazul de utilizare).

Ex. Utilizatorul 4. Preconditii (conditiile necesare pentru declansarea cazului de utilizare).

Ex. Sistemul e aflat in executie, cunoaste datele necesare autentificarii Utilizatorului si ii ofera Utilizatorului o modalitate de a-i transmite aceste date.

5. Evenimentul care declanseaza cazul de utilizare (modul in care incepe cazul de utilizare). Ex. Utilizatorul cere autentificarea de catre sistem.

6. Descriere a interactiunii dintre actori si fiecare caz de utilizare (scenariul principal). Ex. I. Utilizatorul transmite datele necesare autentificarii de catre sistem. II. Sistemul verifica autenticitatea datelor primite de la Utilizator. III. Sistemul prezinta un mesaj de confirmare catre Utilizator. IV. Utilizatorul capata acces la sistem.

7. Alternative la cazul de utilizare principal (scenariile alternative si situatiile exceptionale). Ex. 1. Daca sistemul nu este lansat, autentificarea nu poate avea loc. 2. Daca sistemul nu cunoaste datele de autentificare, autentificarea esueaza. 3. Daca utilizatorul transmite in mod eronat datele de autentificare, autentificarea esueaza.

8. Evenimentul care produce oprirea cazului de utilizare (modul in care se incheie cazul). Ex. Utilizatorului i se prezinta un mesaj de confirmare.

9. Postconditii (efectele incheierii cazului de utilizare). Ex. Utilizatorul are acces la sistem. Este important sa fie clar prezentate:

- schimburile de informatii (parametrii interactiunilor) Ex. datele necesare autentificarii, mesaj de confirmare - originea informatiilor si ordinea schimbarii lor Ex. Utilizatorul transmite datele necesare autentificarii - repetitiile comportamentului, prin constructii pseudocod - situatiile optionale Ex. Utilizatorul alege unul dintre a) optiunea X,

b) optiunea Y, apoi continua cu …

Caz de utilizare - Conectare

1. Nume (cat mai sugestiv, pentru a sintetiza cazul de utilizare). Ex. Conectare 2. Scurta descriere. Ex. Clientul se conecteaza la server, care accepta conexiunea si se pregateste pentru tratarea clientului. 3. Actori (entitati exterioare sistemului modelat, implicate in cazul de utilizare).

Ex. Utilizator. 4. Preconditii (conditiile necesare pentru declansarea cazului de utilizare).

Ex. Serverul e aflat in executie. Clientul cunoaste adresa si numarul de port pe care asculta serverul. 5. Evenimentul care declanseaza cazul de utilizare.

Ex. Utilizatorul lanseaza componenta client a sistemului. 6. Descriere a interactiunii dintre actori si fiecare caz de utilizare. Ex. I. Utilizatorul lanseaza componenta client a sistemului, care se conecteaza la serverul

cunoscut. Serverul accepta conexiunea si se pregateste pentru tratarea clientului. II. Clientul ofera o interfata grafica utilizatorului

7. Alternative la cazul de utilizare principal. Ex. Daca serverul nu este lansat, conectarea esueaza, iar clientul anunta acest lucru utilizatorului.

8. Evenimentul care produce oprirea cazului de utilizare. Ex. Clientul prezinta utilizatorului o interfata grafica.

9. Postconditii (efectele incheierii cazului de utilizare) Ex. Sistemul este pregatit pentru ca utilizatorul sa poata conversa cu alti utilizatori prin interfeta grafica

Utilizator

Conversatie

Conectare

AltUtilizator

Extras Curs ISw-2007 2007-2008 14/25 11/22/2007 2007 Extras curs ISw.doc

______

Caz de utilizare - Conversatie

1. Nume

Conversatie 2. Scurta descriere.

Clientii preiau mesaje de la utilizatori, le trimit catre server, care le difuzeaza catre toti clientii, iar acestia le prezinta catre utilizatori.

3. Actori Utilizatori

4. Preconditii Cazul de utilizare Conversatie s-a incheiat cu succes.

5. Evenimentul care declanseaza cazul de utilizare. Un utilizator scrie un mesaj in interfata grafica a clientului sau.

6. Descriere a interactiunii dintre actori si cazul de utilizare (Transmisie si receptie). I. Utilizatorul scrie mesajul in interfata grafica a clientului sau, clientul trimite mesajul la server. II. Clientul primeste inapoi mesajul difuzat de server, si prezinta mesajul in interfata grafica a utilizatorului

7. Alternativa la cazul de utilizare principal (Doar receptie). Clientul primeste mesajul trims de alt utilizator, mesaj difuzat de server, si prezinta mesajul in interfata grafica a utilizatorului sau.

8. Evenimentul care produce oprirea cazului de utilizare. Clientul a prezentat utilizatorului mesajul primit.

9. Postconditii Sistemul este pregatit pentru ca utilizatorul sa poata continua conversatia cu alti utilizatori prin intermediul interfetei grafice, sau pentru a incheia conversatia prin inchiderea interfetei grafice. Diagrama de secventa (MSC) si diagrama de comunicatie echivalenta – faza de analiza, nivel sistem

: Utilizator : SistemChat : AltUtilizator

mesaj

mesaj mesaj

: Utilizator

: SistemChat

: AltUtilizator

1: mesaj

2: mesaj

3: mesaj

Diagrama de secventa (MSC) – faza de analiza, nivel subsisteme

: Utilizator : Client : Server : Client : AltUtilizator

mesaj

mesaj

mesajmesaj

mesajmesaj

Extras Curs ISw-2007 2007-2008 15/25 11/22/2007 2007 Extras curs ISw.doc

______

Diagrama de secventa (MSC) – faza de analiza, nivel subsisteme, detaliere suplimentara

Diagrama de secventa (MSC) – faza de proiectare, nivel subsisteme, detaliere suplimentara

firTratare : TratareClientDeChat_v1 : Utilizator client :

ClientDeChat_v1server :

ServerDeChat_v1altClient :

ClientDeChat_v1 : AltUtilizatoraltFirTratare : TratareClientDeChat_v1

main() conectare run( )

mesajtransmisie(mesaj)

transmisie(mesaj) transmisie(mesaj)mesaj mesaj

difuzare()

mesajtransmisie(mesaj) difuzare() transmisie(mesaj)

mesajtransmisie(mesaj)mesaj

ConectareConversatie

Trimitere si receptieReceptie

: Utilizator

: Client

: TratareClient

: Server : TratareClient : Client : AltUtilizator

creare

lansare conectare

mesajmesaj mesaj

mesajmesaj

mesaj

mesaj

mesaj

ConectareConversatie

Extras Curs ISw-2007 2007-2008 16/25 11/22/2007 2007 Extras curs ISw.doc

______

Diagrama de secventa (MSC) – faza de proiectare, subsistemul client

Diagrama de secventa (MSC) – faza de proiectare, subsistemul client

Diagrama de clase – subsistemul client

DataInputStream

+ readUTF()

(from io)

DataOutputStream

+ writeUTF()+ flush()

(from io)

Socket (from net)

JTextArea

+ append()

(from swing)

JTextField

+ getText()

(from swing)

ClientDeChat_v1- proprietatiSistem : Logical View::java::util::Properties- numeUser : Logical View::java::lang::String- adresaLocala : Logical View::java::lang::String- portLocal : int

+ run() + ClientDeChat_v1() + main()

-inRetea

-outRetea

-$socket

-outTextGrafic

-inTextGrafic

: ServerDeChat_v1

firTratare : TratareClientDeChat_v1

inRetea : DataInputStream

outRetea : DataOutputStream

firDestinatie : TratareClientDeChat_v1

firDestinatie.outRetea : DataOutputStream

ServerDeChat_v1(int)

start run( )

readUTF( )

difuzare()

writeUTF( )flush( )

writeUTF( ) flush( )

ConectareConversatie

: ClientDeChat_v1

: Thread inRetea : DataInputStream

outRetea : DataOutputStream

outTextGrafic : JTextArea

inTextGrafic : JTextField

start( )

main()

run( )

ClientDeChat_v1()

getText( ) writeUTF( )

flush( )

readUTF( )

append( )

readUTF( )

append( )

ConectareConversatie

Trimitere si receptie

Receptie

Extras Curs ISw-2007 2007-2008 17/25 11/22/2007 2007 Extras curs ISw.doc

______

Diagrama de clase – subsistemul client

Diagrama masinii de stari a clientului: 1. Firul de executie care trateaza evenimentele din interfata grafica:

Conversatie

StareInitiala

StareFinala

conectare

terminare

new Socket()

2. Firul de executie care trateaza receptia mesajelor de la server:

Diagrama masinii de stari (FSM) a serverului, firul de executie principal (acceptor de conexiuni)

server.accept()

AsteptareCereri

CreareFirServireClient

StareInitiala

StareFinala

acceptareClient

AsteptareDateRetea

ReceptieMesaj

do/ ^outTextGrafic.append(mesaj)

IOException

mesaj = inRetea.readUTF()

IOException

TrimitereMesaj

entry/ mesaj = inTextGrafic.getText()do/ ^outRetea.writeUTF(mesaj)

AsteptareEveniment

^inTextGrafic().setText("")

IOException

ActionEvent

IOException

Socket (from net)

ServerDeChat_v1

+ ServerDeChat_v1()+ main()

-socket

DataInputStream

+ readUTF()

(from io)

DataOutputStream

+ writeUTF()+ flush()

(from io)

TratareClientDeChat_v1 - listaFire : Logical View::java::util::Vector = new Vector ()

+ TratareClientDeChat_v1()+ run()- difuzare()

-firTratare

-socket -inRetea -outRetea

Extras Curs ISw-2007 2007-2008 18/25 11/22/2007 2007 Extras curs ISw.doc

______

Diagrama masinii de stari (FSM) a serverului, firul de tratare a clientilor:

Diagrama de activitati (organigrama) a clientului, cu firele de executie pe “coridoare de activitate” separate:

Citire intrare grafica de text

do/ mesaj = inTextGrafic.getText()

AsteptareEveniment

ActionEvent

Trimitere mesaj catre server

do/ outRetea.writeUTF(mesaj)

Scriere in intrarea grafica de text

do/ inTextGrafic.setText("")

AsteptareDateRetea

Citire intrare retea

do/ mesaj = inRetea.readUTF()

Scriere in iesirea grafica de text

do/ outTextGrafic.append(mesaj)

Creare socket

Creare fluxuri IO

Creare intrare grafica

Creare iesire grafica

Initializari conexiune

Initializari grafice

Lansare interfata grafica

Lansare fir receptie

IOException

FirReceptieFirGrafic

StareInitiala

StareFinala

DifuzareMesaj

entry/ conditie = listaFire.hasMoreElements()

AsteptareDateRetea

[ conditie = true ] / firDestinatie = listaFire.nextElement ^firDestinatie.writeUTF(mesaj)

IOException

[ conditie = false ]

mesaj = inRetea.readUTF()

IOException

Extras Curs ISw-2007 2007-2008 19/25 11/22/2007 2007 Extras curs ISw.doc

______

Extras Curs ISw-2007 2007-2008 20/25 11/22/2007 2007 Extras curs ISw.doc

______

Diagrama de clase actualizata a clientului:

DataInputStream

+ readUTF()

(from io)

JTextArea

+ append()

(from swing)

JTextField

+ getText()()

(from swing)

DataOutputStream

+ writeUTF()+ flush()

(from io)

ClientDeChat_v2- numeUser : Logical View::java::lang::String- adresaLocala : Logical View::java::lang::String- portLocal : int- altiClienti : Logical View::java::util::Vector = new Vector ()

+ run()+ ClientDeChat_v2()+ main()

-inRetea

-outTextGrafic-inTextGrafic

-outRetea

Socket(from net)

-$socket

Diagrama de clase actualizata a serverului:

InfoClientnume : Logical View::java::lang::Stringadresa : Logical View::java::lang::Stringport : int

+ InfoClient()+ toString()+ equals()

DataInputStream

+ readUTF()

(from io)

DataOutputStream

+ writeUTF()+ flush()

(from io)

ServerDeChat_v2

+ ServerDeChat_v2()+ main()

Socket(from net)

-socket

TratareClientDeChat_v2- listaClienti : Logical View::java::util::Vector = new Vector ()

+ TratareClientDeChat_v2()+ run()- difuzare()

-firTratare

-client

-inRetea -outRetea

-socket

Extras Curs ISw-2007 2007-2008 21/25 11/22/2007 2007 Extras curs ISw.doc

______

Extras Curs ISw-2007 2007-2008 22/25 11/22/2007 2007 Extras curs ISw.doc

______

Extras Curs ISw-2007 2007-2008 23/25 11/22/2007 2007 Extras curs ISw.doc

______

Extras Curs ISw-2007 2007-2008 24/25 11/22/2007 2007 Extras curs ISw.doc

______