Sabloane creationale
Cuprins
Aceasta sectiune cuprinde cateva dintre cele mai utilizate sabloane de proiectare de tipul "Creational" (creare de obiecte). Aceste sabloane sunt esentiale pentru a intelege cum sa gestionam instantierea si ciclul de viata al obiectelor in aplicatiile noastre.
Șablon de proiectare Singleton
Nume: Singleton
Problemă: Este necesară existența unei singure instanțe a unei clase în întreaga aplicație, cu acces global la această instanță. Situații tipice sunt: gestionarea conexiunilor la baze de date, configurații globale, sau servicii care trebuie să fie disponibile într-un singur exemplar.
Soluție: Asigurarea că o clasă are o singură instanță și oferirea unui punct global de acces la aceasta. Se implementează prin: constructori privați care previn instantierea externă, o metodă statică care returnează instanța unică și o variabilă statică care stochează instanța.
Structură:
O clasă cu constructor privat
O metodă statică publică (
getInstance()
)O variabilă statică privată care păstrează instanța unică
Implementare:
public class Singleton {
// Variabila statică privată pentru stocarea instanței
private static Singleton instance;
// Constructor privat pentru a preveni instanțierea din exterior
private Singleton() {
// Inițializări necesare
}
// Metoda statică publică pentru obținerea instanței
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
// Alte metode publice
public void serviceMethod() {
// Funcționalitate oferită de Singleton
}
}
Consecințe:
Avantaje: Control strict asupra instanței unice, reducerea utilizării memoriei, evitarea variabilelor globale.
Dezavantaje: Poate ascunde dependențe între componente, poate fi mai dificil de testat, potențiale probleme în medii multi-thread dacă nu e implementat corect.
Șablon de proiectare Factory Method
Nume: Factory Method
Problemă: Necesitatea de a crea obiecte fără a specifica exact clasa obiectului care va fi creat. Se dorește delegarea instantierii către subclase, permițând aplicației să determine dinamic ce tipuri de obiecte să creeze în funcție de context sau configurație.
Soluție: Definirea unei interfețe pentru crearea unui obiect, dar lăsarea subclaselor să decidă ce clasă să instanțieze. Factory Method permite unei clase să delege instantierea către subclase și elimină dependențele directe de implementări concrete.
Structură:
O interfață sau clasă abstractă Creator cu o metodă abstractă de fabrică
Subclase ConcreteCreator care implementează metoda de fabrică
O interfață sau clasă abstractă Product
Subclase ConcreteProduct care sunt create de metodele de fabrică
Implementare:
// Interfața produsului
interface Product {
void operation();
}
// Implementări concrete ale produsului
class ConcreteProductA implements Product {
@Override
public void operation() {
System.out.println("Operație executată de Produsul A");
}
}
class ConcreteProductB implements Product {
@Override
public void operation() {
System.out.println("Operație executată de Produsul B");
}
}
// Clasa Creator cu metoda Factory
abstract class Creator {
// Factory Method
public abstract Product createProduct();
// Metodă care utilizează produsul
public void anOperation() {
Product product = createProduct();
product.operation();
}
}
// Implementări concrete ale creatorului
class ConcreteCreatorA extends Creator {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
class ConcreteCreatorB extends Creator {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
Consecințe:
Avantaje: Elimină dependența de clase concrete specifice, oferă flexibilitate în crearea obiectelor, promovează principiul deschis-închis prin permiterea extinderii fără modificarea codului existent.
Dezavantaje: Poate rezulta în crearea multor subclase pentru implementarea diferențelor minore, complexitate suplimentară în comparație cu crearea directă a obiectelor.
Șablon de proiectare Abstract Factory
Nume: Abstract Factory
Problemă: Necesitatea de a crea familii de obiecte înrudite sau dependente fără a specifica clasele lor concrete. Este utilă când sistemul trebuie să fie independent de modul în care produsele sale sunt create, compuse și reprezentate.
Soluție: Furnizarea unei interfețe pentru crearea de familii de obiecte înrudite sau dependente, fără a specifica clasele lor concrete. Abstract Factory permite crearea de obiecte care urmează un model comun și care sunt proiectate să lucreze împreună.
Structură:
O interfață AbstractFactory care declară metode pentru crearea fiecărui tip de produs
Clase ConcreteFactory care implementează metodele de creare
Interfețe de produs pentru fiecare tip de produs din familie
Clase concrete pentru fiecare variație de produs
Implementare:
// Interfețe pentru produse
interface ButtonProduct {
void render();
}
interface CheckboxProduct {
void check();
}
// Implementări concrete pentru familia "Windows"
class WindowsButton implements ButtonProduct {
@Override
public void render() {
System.out.println("Renderizare buton Windows");
}
}
class WindowsCheckbox implements CheckboxProduct {
@Override
public void check() {
System.out.println("Bifat checkbox Windows");
}
}
// Implementări concrete pentru familia "MacOS"
class MacOSButton implements ButtonProduct {
@Override
public void render() {
System.out.println("Renderizare buton MacOS");
}
}
class MacOSCheckbox implements CheckboxProduct {
@Override
public void check() {
System.out.println("Bifat checkbox MacOS");
}
}
// Abstract Factory
interface GUIFactory {
ButtonProduct createButton();
CheckboxProduct createCheckbox();
}
// Fabrici concrete pentru fiecare familie
class WindowsFactory implements GUIFactory {
@Override
public ButtonProduct createButton() {
return new WindowsButton();
}
@Override
public CheckboxProduct createCheckbox() {
return new WindowsCheckbox();
}
}
class MacOSFactory implements GUIFactory {
@Override
public ButtonProduct createButton() {
return new MacOSButton();
}
@Override
public CheckboxProduct createCheckbox() {
return new MacOSCheckbox();
}
}
// Cod client
class Application {
private ButtonProduct button;
private CheckboxProduct checkbox;
public Application(GUIFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}
public void render() {
button.render();
checkbox.check();
}
}
Consecințe:
Avantaje: Izolează codurile concrete, promovează coerența între produse, facilitează schimbarea familiilor de produse, asigură compatibilitatea produselor din aceeași familie.
Dezavantaje: Adăugarea de noi tipuri de produse este dificilă (trebuie modificate toate fabricile), poate introduce complexitate suplimentară dacă familia de produse este mică.
Șablon de proiectare Builder
Nume: Builder
Problemă: Necesitatea de a construi obiecte complexe pas cu pas, separând procesul de construcție de reprezentarea finală. Este util când un obiect trebuie creat cu numeroase parametri opționali sau când procesul de construcție implică mai mulți pași.
Soluție: Separarea construcției unui obiect complex de reprezentarea sa, astfel încât același proces de construcție să poată crea reprezentări diferite. Permite crearea obiectelor în etape și oferă control fin asupra procesului de construcție.
Structură:
O interfață Builder care definește pașii de construcție
Clase ConcreteBuilder care implementează pașii pentru crearea și asamblarea produsului
Clasa Director care coordonează procesul de construcție
Clasa Product care reprezintă obiectul complex creat
Implementare:
// Produsul complex
class House {
private String foundation;
private String structure;
private String roof;
private boolean furnished;
private boolean painted;
@Override
public String toString() {
return "House [foundation=" + foundation + ", structure=" + structure + ", roof=" + roof +
", furnished=" + furnished + ", painted=" + painted + "]";
}
// Setteri
public void setFoundation(String foundation) { this.foundation = foundation; }
public void setStructure(String structure) { this.structure = structure; }
public void setRoof(String roof) { this.roof = roof; }
public void setFurnished(boolean furnished) { this.furnished = furnished; }
public void setPainted(boolean painted) { this.painted = painted; }
}
// Interfața Builder
interface HouseBuilder {
void buildFoundation();
void buildStructure();
void buildRoof();
void furnish();
void paint();
House getResult();
}
// Builder concret
class StandardHouseBuilder implements HouseBuilder {
private House house;
public StandardHouseBuilder() {
this.house = new House();
}
@Override
public void buildFoundation() {
house.setFoundation("Standard Foundation");
}
@Override
public void buildStructure() {
house.setStructure("Brick Walls");
}
@Override
public void buildRoof() {
house.setRoof("Standard Roof");
}
@Override
public void furnish() {
house.setFurnished(true);
}
@Override
public void paint() {
house.setPainted(true);
}
@Override
public House getResult() {
return house;
}
}
// Director
class ConstructionDirector {
public House constructStandardHouse(HouseBuilder builder) {
builder.buildFoundation();
builder.buildStructure();
builder.buildRoof();
return builder.getResult();
}
public House constructFullyFurnishedHouse(HouseBuilder builder) {
builder.buildFoundation();
builder.buildStructure();
builder.buildRoof();
builder.furnish();
builder.paint();
return builder.getResult();
}
}
// Client
class BuilderDemo {
public static void main(String[] args) {
HouseBuilder builder = new StandardHouseBuilder();
ConstructionDirector director = new ConstructionDirector();
// Construiește o casă standard
House standardHouse = director.constructStandardHouse(builder);
System.out.println("Standard House: " + standardHouse);
// Construiește o casă complet mobilată
House furnishedHouse = director.constructFullyFurnishedHouse(builder);
System.out.println("Fully Furnished House: " + furnishedHouse);
}
}
Consecințe:
Avantaje: Permite variații ale produselor, izolează codul pentru construcție de reprezentare, oferă control fin asupra procesului de construcție, ascunde detaliile interne ale produselor.
Dezavantaje: Necesită crearea mai multor clase noi, poate fi prea complex pentru produse simple, uneori necesită mai mult cod decât alte alternative (cum ar fi constructori cu parametri).
Last updated