Sunteți pe pagina 1din 20

Ministerul Educației al Republicii Moldova

Universitatea Tehnică a Moldovei


Facultatea Calculatoare, Informatică și Microelectronică
Catedra Automatică și Tehnologii Informaționale

RAPORT

Disciplina: Ingineria Produselor Program

Lucrare de laborator Nr. 2

Tema: Șabloane de proiectare creaționale

A efectuat :

A verificat:

Chișinău 2013
2
1. Scopul lucrării
Studierea șabloanelor de proiectare creaționale.

2. Sarcina lucrării
De realizat o aplicație utilizând șabloanele creaționale Abstract Factory, Factory Method, Builder,
Prototype și Singleton.

3. Șabloane de proiectare creaționale


Șabloane creaționale
Șabloanele creaționale sunt șabloane de proiectare care tratează mecanismele de creare a
obiectelor. Cu ajutorul lor obiectele pot fi create într-o manieră adaptabilă la diverse situații. Ele fac
sistemul independent de modul în care obiectele sunt create, compuse și reprezentate, încapsulând
cunoștințele privind clasele concrete pe care le utilizează sistemul și ascunzând modul în care
instanțele acestor clase sunt create și compuse.
Șabloanele creaționale devin importante când evoluția unui sistem se bazează mai mult pe
compunere decât pe moștenire. În locul unei ierarhii prestabilite, elementele unei mulțimi mici de
comportamente fundamentale pot fi combinate în orice număr de comportamente mai complexe.
Șabloanele de proiectare creaționale pot introduce constrângeri asupra următoarelor situații:
- cine poate crea obiecte;
- cum sunt create obiectele;
- când sunt create obiectele.

Abstract Factory
- Oferă o interfață pentru a crea familii de obiecte înrudite sau dependente fără a fi nevoiți
să specificăm clasa concretă;
- Oferă o ierarhie care încapsulează mai multe platforme posibile și posibilitatea de a
construi o suită de produse;
- Operatorul new devine dăunator în instanțiere (nu se mai face direct).
În figura 3.1 este prezentată diagrama de clase pentru șablonul de proiectare Abstract Factory.

3
Figura 3.1. Diagrama de clase pentru șablonul de proiectare Abstract Factory

Factory Method
- Definește o interfață de creare a unui obiect dar lasă clasele derivate (subclasele) să
decidă cum instanțiază obiectul. Factory Method lasă o clasă să cedeze modul de
instanțiere a subclaselor;
- Se definește un constructor “virtual”;
- Operatorul new devine dăunător, inutil;
- Exemplu de necesitate a acestui pattern: un framework trebuie să standardizeze modelul
arhitectural pentru o varietate mare de aplicații dar să permită aplicațiilor individuale să-
și definească propriile obiecte și să le implementeze modul de instanțiere.
Diagrama de clase pentru șablonul de proiectare Factory Method este prezentată în figura 3.2.

Figura 3.2. Diagrama de clase pentru șablonul de proiectare Factory Method


4
Builder
- Separă construirea unui obiect complex de reprezentarea, înfățisarea sa astfel încât
același proces de construire poate crea reprezentări, înfățișări diferite;
- Analiza unei reprezentări complexe, crearea uneia din mai multe obiecte dorite;
- Problema apare de obicei atunci când o aplicație trebuie să creeze elemente ale unui
ansamblu complex. Specifiicațiile pentru acest ansamblu sunt date într-un spațiu secundar
dar unul sau mai multe din reprezentări trebuiesc construite în spațiul primar.
Diagrama de clase pentru șablonul de proiectare Builder este prezentată în figura 3.3.

Figura 3.3. Diagrama de clase pentru șablonul de proiectare Builder

Prototype
- Specifică tipurile de obiecte ce se pot crea utilizând o instanță “prototip” și crează obiecte
noi copiind acest prototip;
- Se evită subclasele unui obiect “creator” în aplicația client, la fel cum face și abstract
factory;
- Evită costul crescut al creării unui obiect nou în modul standard (utilizând operatorul
new) când aceasta este foarte costisitoare și scumpă pentru o aplicație dată.
- Pentru a implementa acest pattern, se declară o clasă abstractă de bază care specifică o
metodă virtuală pura clone(). Orice clasă care este derivată din clasa de bază
implementează metoda clone().
- Clientul, în loc să scrie cod care invocă operatorul new, apelează metoda clone() a
prototipului sau apelează o metodă factory cu un parametru specificând clasa derivată
dorită.
Diagrama de clase pentru șablonul de proiectare Prototype este prezentată în figura 3.4.
5
Figura 3.4. Diagrama de clase pentru șablonul de proiectare Prototype

Singleton
- Modelul de proiectare singleton este un model creațional ce asigură faptul că avem o
singură instanță a unei clase particulare în timpul rulării programului și ne oferă un punct
global de acces la această singură instanță.
- Mecanismul prin care este posibilă impunerea unei singure clase este realizat prin
definirea constructorului clasei respective ca privat și furnizarea unei metode (care se
numește metodă singleton) care este apelată în momentul în care se dorește instanțierea.
Aceasta va verifica numărul de instanțe și va controla procesul de instanțiere.
Diagrama de clase pentru șablonul de proiectare Singleton este prezentată în figura 3.5.

Figura 3.5. Diagrama de clase pentru șablonul de proiectare Singleton

4. Realizarea sarcinii
6
Aplicația creată utilizând cele 5 șabloane de proiectare creaționale enunțate este un mini-joc în
care utilizatorul poate deplasa în stânga și în dreapta un jucător și poate “împușca” în sus, iar din sus în
jos vin inamicii care trebuie împușcați înainte de a ajunge jos. Atunci când unul din inamici ajunge jos,
jocul se termină. Pentru fiecare unitate de daună adusă inamicului, jucătorul primește câte un punct.
Atunci când utilizatorul începe un joc nou, el are de ales între a juca cu un jucător rapid sau cu
un jucător puternic. La jucătorul rapid patroanele zboară mai repede, însă produc mai puține pagube
inamicilor. Cel puternic are niște patroane care se mișcă mai încet, însă acestea sunt mai mari ca
dimensiuni și produc daune mai mari inamicilor.
Inamicii sunt și ei de 2 tipuri: de formă dreptunghiulară și mai ușor de ucis și de forma unei
elipse și mai dificil de ucis.
Se observă că un anumit tip de jucător este legat de un anumit tip de patron. Aici vine în ajutor
șablonul de proiectare AbstractFactory. Clasa PlayerAbstractFactory definește 2 metode:
CreateBullet() pentru crearea unui patron și CreatePlayer() pentru crearea jucătorului. Fabricile
concrete QuickPlayerFactory și StrongPlayerFactory implementează cele 2 metode pentru a crea tipuri
concrete ale clase Player, respectiv Bullet. Se observă, deci, și utilizarea șablonului Factory Method, în
care clasa de bază lasă clasele derivate să instanțieze obiecte concrete.
Deoarece pe parcursul jocului se crează multe patroane, am ales șablonul de proiectare Prototype
pentru instanțierea lor. Clasa Bullet, deci, definește metoda abstractă Clone() care este implementată de
clasele derivate. Mai este utilizată o clasă PrototypeManager care menține și gestionează prototipurile,
adică obiectele concrete care sunt clonate pentru a obține instanțe noi.
Clasa GameInfo menține și gestionează informațiile despre starea jocului, cum ar fi poziția
jucătorului, patroanele, inamicii. Funcția Change din această clasă realizează trecerea dintr-o stare a
jocului în următoarea stare, adică mișcarea inamicilor și a patroanelor și detectarea coliziunilor între
acestea.
Diagrama de clase ce prezintă cele expuse este prezentată în figura 4.1.

7
Figura 4.1. Prima diagramă de clase

Clasa GameInfo are o instanță păstrată într-o altă clasă – clasa Game. Această clasă pune la
dispoziție metode pentru pornirea și oprirea jocului, dar și obținerea diferitor informați despre starea
jocului prin accesarea instanței clasei GameInfo.
Clasa Game implementează șablonul de proiectare Singleton, deoarece există un singur joc și e
necesar să avem un punct global de acces la instanța jocului.
Clasa GameInfo este relativ complexă, fiind compusă din mai multe obiecte, din această cauză
pentru instanțierea ei a fost utilizat șablonul de proiectare Builder. Părțile create sunt fabrica
PlayerAbstractFactory, jucătorul Player și PrototypeManager-ul.
Diagrama de clase care ilustrează șabloanele enumerate este prezentată în figura 4.2.

8
Figura 4.2. A doua diagramă de clase

Pentru reprezentarea unui inamic mai este definită o clasă numită Enemy. Aici, la fel ca și în
cazul clasei Bullet, este utilizat șablonul de proiectare Prototype. Cele 2 clase derivate de la clasa
Enemy – HardEnemy și EasyEnemy implementează metoda Clone() din clasa părinte pentru a realiza
clonarea obiectelor.
Diagrama care include și clasele ce reprezintă inamicii este prezentată în figura 4.3. Codul sursă
poate fi găsit în anexa B. În anexa A poate fi găsit un screenshot de la execuția programului.

9
Figura 4.3. A treia diagramă de clase

Concluzii
La această lucrare de laborator am studiat șabloanele creaționale de proiectare. Aceste șabloane
au o mare importanță, mai ales în cazul unor proiecte mai mari, deoarece ele fac sistemul independent
de modul în care sunt create obiectele. Aceasta permite crearea unor aplicațiile flexibile, ce pot fi
modificate mai ușor.

10
Anexa A. Screenshot de la execuția aplicației

Figura A.1. Screenshot de la execuția aplicației

11
Anexa B. Codul sursă al aplicației
Bullet.cs
using System.Drawing;

public abstract class Bullet


{
protected Rectangle r;
protected int speed;
protected int force;

public abstract Bullet Clone();

public abstract void Draw(Graphics g);

public int GetForce() { return force; }

public Rectangle GetR() { return r; }

public void MoveUp() { r.Y -= speed; }

public void SetPosition(int x, int y)


{
r.X = x;
r.Y = y;
}
}

ConcreteGameInfoBuilder.cs
public class ConcreteGameInfoBuilder : GameInfoBuilder
{
private GameInfo gameInfo;

public ConcreteGameInfoBuilder() { gameInfo = new GameInfo(); }

public void BuildPlayer() { gameInfo.CreatePlayer(); }

public void BuildPlayerFactory(PlayerAbstractFactory playerFactory)


{ gameInfo.SetPlayerFactory(playerFactory); }

public void BuildPrototypeManager()


{
PrototypeManager pm = new PrototypeManager();
pm.SetBulletPrototype(gameInfo.GetPlayerFactory().CreateBullet());
pm.AddEnemyPrototype(new EasyEnemy());
pm.AddEnemyPrototype(new HardEnemy());
gameInfo.SetPrototypeManager(pm);
}

public GameInfo GetGameInfo() { return gameInfo; }


}

EasyEnemy.cs
using System.Drawing;

public class EasyEnemy : Enemy


{
public EasyEnemy() : base(2) { }

public override Enemy Clone()


{
EasyEnemy e = (EasyEnemy)this.MemberwiseClone();
e.r = new Rectangle(r.X, r.Y, r.Width, r.Height);
12
return e;
}

public override void Draw(Graphics g)


{
g.DrawRectangle(new Pen(Color.Red, health), r);
}
}

Enemy.cs
using System.Drawing;

public abstract class Enemy


{
protected int health;
protected Rectangle r;

public Enemy(int health)


{
this.health = health;
r = new Rectangle(0, 0, 90, 50);
}

public abstract Enemy Clone();

public void DecreaseHealth(int force)


{
health -= force;
if (health < 0) health = 0;
}

public abstract void Draw(Graphics g);

public int GetHealth() { return health; }

public Rectangle GetR() { return r; }

public void SetPosition(int x, int y)


{
r.X = x;
r.Y = y;
}

public void MoveDown(int dy) { r.Y += dy; }


}

Form1.cs
using System;
using System.Windows.Forms;

namespace SpaceInvaders
{
public partial class Form1 : Form
{
Game game = Game.GetInstance();
int dir = 0;
bool shooting = false;

public Form1()
{
InitializeComponent();
}

13
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (!game.IsConstructed()) return;
game.GetGameInfo().GetPlayer().Draw(e.Graphics);
foreach (var b in game.GetGameInfo().GetBullets()) b.Draw(e.Graphics);
foreach (var en in game.GetGameInfo().GetEnemies()) en.Draw(e.Graphics);
}

private void timer1_Tick(object sender, EventArgs e)


{
int level = game.GetGameInfo().GetScore() / 20 + 1;
if (!game.GetGameInfo().Change())
{
timer1.Enabled = false;
game.StopGame();
Text = "Game OVER - Level " + level + " - " + game.GetGameInfo().GetScore() +
" points";
}
else
{
int tmr = 200 - (level - 1) * 10;
if (tmr < 20) tmr = 20;
timer1.Interval = tmr;
Text = "Level - " + level + " - " + game.GetGameInfo().GetScore() + " points,
enemies: " + game.GetGameInfo().GetEnemies().Count;
}
pictureBox1.Invalidate();
}

private void Form1_KeyDown(object sender, KeyEventArgs e)


{
if (!game.IsStarted()) return;
switch (e.KeyCode)
{
case Keys.Left: dir = -1; break;
case Keys.Right: dir = 1; break;
case Keys.Space: shooting = true; break;
}
}

private void timer2_Tick(object sender, EventArgs e)


{
bool change = false;
if (dir == -1) { change = true; game.GetGameInfo().GetPlayer().MoveLeft(10); }
if (dir == 1) { change = true; game.GetGameInfo().GetPlayer().MoveRight(10); }
if (shooting) { change = true; game.GetGameInfo().Shoot(); }
if (change) pictureBox1.Invalidate();
}

private void Form1_KeyUp(object sender, KeyEventArgs e)


{
if (!game.IsStarted()) return;
switch (e.KeyCode)
{
case Keys.Left:
case Keys.Right: dir = 0; break;
case Keys.Space: shooting = false; break;
}
}

private void closeToolStripMenuItem_Click(object sender, EventArgs e)


{
Close();
}

private void quickPlayerToolStripMenuItem_Click(object sender, EventArgs e)


{
14
game.NewGame(new QuickPlayerFactory());
timer1.Enabled = true;
}

private void strongPlayerToolStripMenuItem_Click(object sender, EventArgs e)


{
game.NewGame(new StrongPlayerFactory());
timer1.Enabled = true;
}
}
}

Game.cs
public class Game
{
private GameInfo gameInfo;
private static Game instance;
public ConcreteGameInfoBuilder builder;
public bool started = false;
public bool constructed = false;

private Game() { }

public GameInfo GetGameInfo() { return gameInfo; }

public static Game GetInstance()


{
if (instance == null) instance = new Game();
return instance;
}

public bool IsStarted() { return started; }

public bool IsConstructed() { return constructed; }

public void NewGame(PlayerAbstractFactory factory)


{
constructed = false;
builder = new ConcreteGameInfoBuilder();
builder.BuildPlayerFactory(factory);
builder.BuildPlayer();
builder.BuildPrototypeManager();
gameInfo = builder.GetGameInfo();
constructed = true;
started = true;
}

public void StopGame() { started = false; }


}

GameInfo.cs
using System;
using System.Collections.Generic;
using System.Drawing;

public class GameInfo {


private List<Bullet> bullets = new List<Bullet>();
private List<Enemy> enemies = new List<Enemy>();
private Player player;
private PlayerAbstractFactory playerFactory;
private PrototypeManager pm;
private int score = 0;
private Random rand = new Random();

15
public bool Change() {
bool colesion = false;
for (int i = 0; i < enemies.Count; i++) enemies[i].MoveDown(2);
for (int i = 0; i < bullets.Count; )
{
bullets[i].MoveUp();
colesion = false;
for (int j = 0; j < enemies.Count; j++)
if (bullets[i].GetR().IntersectsWith(enemies[j].GetR()))
{
score += Math.Min(bullets[i].GetForce(), enemies[j].GetHealth());
enemies[j].DecreaseHealth(bullets[i].GetForce());
bullets.RemoveAt(i);
if (enemies[j].GetHealth() <= 0) enemies.RemoveAt(j);
colesion = true;
break;
}
if (!colesion) i++;
}
GenerateRandomEnemies();
for (int i = 0; i < bullets.Count; )
{
if (bullets[i].GetR().Y < -bullets[i].GetR().Height)
bullets.RemoveAt(i);
else i++;
}
for (int i = 0; i < enemies.Count; i++)
if (enemies[i].GetR().Y > 350) return false;
return true;
}

public void GenerateRandomEnemies()


{
int x;
bool inters;
for (int i = 0; i < 5; i++)
if (rand.Next(20) == 0)
{
x = rand.Next(810);
Rectangle r = new Rectangle(x, -50, 90, 50);
inters = false;
foreach (var en in enemies)
if (en.GetR().IntersectsWith(r))
{
inters = true;
break;
}
if (!inters)
{
Enemy en = pm.CreateRandomEnemy();
en.SetPosition(r.X, r.Y);
enemies.Add(en);
}
}
}

public void CreatePlayer() { this.player = playerFactory.CreatePlayer(); }

public List<Bullet> GetBullets() { return bullets; }

public List<Enemy> GetEnemies() { return enemies; }

public Player GetPlayer() { return player; }

public PlayerAbstractFactory GetPlayerFactory() { return playerFactory; }

16
public int GetScore() { return score; }

public void SetPlayerFactory(PlayerAbstractFactory playerFactory) { this.playerFactory =


playerFactory; }

public void SetPrototypeManager(PrototypeManager pm) { this.pm = pm; }

public void Shoot()


{
Bullet b = pm.CreateBullet();
b.SetPosition(player.GetR().X + 45 - b.GetR().Width / 2, 400 - b.GetR().Height);
foreach (var bl in bullets)
if (bl.GetR().IntersectsWith(b.GetR())) return;
bullets.Add(b);
}
}

GameInfoBuilder.cs
public interface GameInfoBuilder
{
void BuildPlayer();
void BuildPlayerFactory(PlayerAbstractFactory playerFactory);
void BuildPrototypeManager();
}

HardEnemy.cs
using System.Drawing;

public class HardEnemy : Enemy


{
public HardEnemy() : base(3) { }

public override Enemy Clone()


{
HardEnemy e = new HardEnemy();
e.SetPosition(r.X, r.Y);
e.health = health;
return e;
}

public override void Draw(Graphics g)


{
g.DrawEllipse(new Pen(Color.Red, health), r);
}
}

Player.cs
using System.Drawing;

public abstract class Player


{
protected Rectangle r;

public Player() { r = new Rectangle(445, 400, 90, 20); }

public abstract void Draw(Graphics g);

public Rectangle GetR() { return r; }

public void MoveLeft(int dx) { r.X -= dx; }

17
public void MoveRight(int dx) { r.X += dx; }
}

PlayerAbstractFactory.cs
public interface PlayerAbstractFactory
{
Bullet CreateBullet();
Player CreatePlayer();
}

PrototypeManager.cs
using System;
using System.Collections.Generic;

public class PrototypeManager


{
private Bullet bulletPrototype;
private List<Enemy> enemyPrototypes = new List<Enemy>();
private Random rand = new Random();

public void AddEnemyPrototype(Enemy enemy)


{
enemyPrototypes.Add(enemy);
}

public Bullet CreateBullet()


{
return bulletPrototype.Clone();
}

public Enemy CreateRandomEnemy()


{
if (enemyPrototypes.Count > 0) return
enemyPrototypes[rand.Next(enemyPrototypes.Count)].Clone();
return null;
}

public void SetBulletPrototype(Bullet bullet)


{
this.bulletPrototype = bullet;
}
}

QuickBullet.cs
using System.Drawing;

public class QuickBullet : Bullet


{
public QuickBullet()
{
r = new Rectangle(0, 0, 10, 20);
speed = 8;
force = 1;
}

public QuickBullet(QuickBullet b)
{
Rectangle br = b.GetR();
r = new Rectangle(br.X, br.Y, br.Width, br.Height);
speed = b.speed;
force = b.force;

18
}

public override Bullet Clone()


{
return new QuickBullet(this);
}

public override void Draw(Graphics g)


{
g.DrawRectangle(new Pen(Color.Black, 2), r);
}
}

QuickPlayer.cs
using System.Drawing;

public class QuickPlayer : Player {


public override void Draw(Graphics g)
{
g.DrawRectangle(new Pen(Color.Green, 2), r);
}
}

QuickPlayerFactory.cs
public class QuickPlayerFactory : PlayerAbstractFactory {
public Bullet CreateBullet(){
return new QuickBullet();
}

public Player CreatePlayer(){


return new QuickPlayer();
}
}

StrongBullet.cs
using System.Drawing;

public class StrongBullet : Bullet {


public StrongBullet() {
r = new Rectangle(0, 0, 15, 20);
speed = 5;
force = 2;
}

public StrongBullet(StrongBullet b)
{
Rectangle br = b.GetR();
r = new Rectangle(br.X, br.Y, br.Width, br.Height);
speed = 5;
force = 2;
}

public override Bullet Clone()


{
return new StrongBullet(this);
}

public override void Draw(Graphics g)


{
g.DrawRectangle(new Pen(Color.Black, 4), r);
}
19
}

StrongPlayer.cs
using System.Drawing;

public class StrongPlayer : Player {


public override void Draw(Graphics g)
{
g.DrawRectangle(new Pen(Color.Green, 4), r);
}
}

StrongPlayerFactory.cs
public class StrongPlayerFactory : PlayerAbstractFactory {
public Bullet CreateBullet()
{
return new StrongBullet();
}

public Player CreatePlayer()


{
return new StrongPlayer();
}
}

20

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

  • Exemplu Raport
    Exemplu Raport
    Document27 pagini
    Exemplu Raport
    Fil Gorea
    Încă nu există evaluări
  • Tema: Algoritmul de Criptografie RSA: Functionare
    Tema: Algoritmul de Criptografie RSA: Functionare
    Document2 pagini
    Tema: Algoritmul de Criptografie RSA: Functionare
    Ion Popescu
    Încă nu există evaluări
  • Instr CET08
    Instr CET08
    Document4 pagini
    Instr CET08
    Oleg Botnaru
    Încă nu există evaluări
  • Algoritmul de Criptografie DSA
    Algoritmul de Criptografie DSA
    Document2 pagini
    Algoritmul de Criptografie DSA
    DumitruGuba
    Încă nu există evaluări
  • Lab1 Pam
    Lab1 Pam
    Document9 pagini
    Lab1 Pam
    Ion Popescu
    100% (2)
  • Lab 3
    Lab 3
    Document8 pagini
    Lab 3
    Ion Popescu
    Încă nu există evaluări
  • Laboratorul nr.1
    Laboratorul nr.1
    Document1 pagină
    Laboratorul nr.1
    Ion Popescu
    Încă nu există evaluări
  • Plia 4 141
    Plia 4 141
    Document55 pagini
    Plia 4 141
    Ion Popescu
    Încă nu există evaluări
  • Functionare
    Functionare
    Document4 pagini
    Functionare
    Ion Popescu
    Încă nu există evaluări
  • Lab 2
    Lab 2
    Document2 pagini
    Lab 2
    Ion Popescu
    Încă nu există evaluări
  • Plia 4 14
    Plia 4 14
    Document34 pagini
    Plia 4 14
    Ion Popescu
    Încă nu există evaluări
  • Plia 4 14
    Plia 4 14
    Document34 pagini
    Plia 4 14
    Ion Popescu
    Încă nu există evaluări
  • Lab 1
    Lab 1
    Document6 pagini
    Lab 1
    Ion Popescu
    Încă nu există evaluări
  • Plia 4 141
    Plia 4 141
    Document55 pagini
    Plia 4 141
    Ion Popescu
    Încă nu există evaluări
  • Plia 7
    Plia 7
    Document53 pagini
    Plia 7
    Ion Popescu
    Încă nu există evaluări
  • Plia 4 14
    Plia 4 14
    Document34 pagini
    Plia 4 14
    Ion Popescu
    Încă nu există evaluări
  • Plia 4 141
    Plia 4 141
    Document55 pagini
    Plia 4 141
    Ion Popescu
    Încă nu există evaluări
  • Plia 1 15
    Plia 1 15
    Document53 pagini
    Plia 1 15
    Ion Popescu
    Încă nu există evaluări
  • Plia 3 15
    Plia 3 15
    Document37 pagini
    Plia 3 15
    Ion Popescu
    Încă nu există evaluări
  • Cuprins
    Cuprins
    Document3 pagini
    Cuprins
    Ion Popescu
    Încă nu există evaluări
  • Algoritmul de Criptografie DSA
    Algoritmul de Criptografie DSA
    Document2 pagini
    Algoritmul de Criptografie DSA
    DumitruGuba
    Încă nu există evaluări
  • Plia 2 15
    Plia 2 15
    Document40 pagini
    Plia 2 15
    Ion Popescu
    Încă nu există evaluări
  • Exemplu
    Exemplu
    Document1 pagină
    Exemplu
    Ion Popescu
    Încă nu există evaluări
  • Indrumar TAP
    Indrumar TAP
    Document120 pagini
    Indrumar TAP
    Ion Popescu
    Încă nu există evaluări
  • Rapot IOC
    Rapot IOC
    Document5 pagini
    Rapot IOC
    Ion Popescu
    Încă nu există evaluări
  • HGJHB
    HGJHB
    Document19 pagini
    HGJHB
    Ion Popescu
    Încă nu există evaluări
  • Else Fcim Utm MD PDF
    Else Fcim Utm MD PDF
    Document2 pagini
    Else Fcim Utm MD PDF
    Ion Popescu
    Încă nu există evaluări
  • Ciclu Prelegeri TVPP
    Ciclu Prelegeri TVPP
    Document100 pagini
    Ciclu Prelegeri TVPP
    Mihai Coșleț
    Încă nu există evaluări
  • SI Lab 1 Zubcov Olga
    SI Lab 1 Zubcov Olga
    Document17 pagini
    SI Lab 1 Zubcov Olga
    Ion Popescu
    Încă nu există evaluări
  • Laboratorul nr.1
    Laboratorul nr.1
    Document1 pagină
    Laboratorul nr.1
    Ion Popescu
    Încă nu există evaluări