50% reducereÎnscrie-te acum la orice curs și profită de reducerile de primăvară!
48:00:00

Design Patterns: Facade (fațadă)

Postat 22 Martie, 2026
Design Patterns: Facade (fațadă)

Facade, sau “fațada” e unul din cele mai comune design patterns, pentru că e folosit de o multitudine de biblioteci, indiferent care este platforma de dezvoltare sau limbajul de programare despre care vorbim.

Problema

Să zicem că avem următoarea situație: trebuie să scrii o bibliotecă, care să permită interacțiunea cu un serviciu sau componentă de infrastructură de cloud. O bază de date non-relațională, să spunem.

Vei lucra destul de intens în prima fază la funcționalitățile cheie, adică posibilitatea de a efectua acțiuni de citire, scriere, actualizare și ștergere pe baza de date respectivă.

Destul de simplu și la obiect până aici.

După aceste funcționalități de bază, realizezi că înainte de a permite interacțiunea cu baza de date trebuie să faci anumite verificări, sau pași intermediari, cum ar fi:

  • Autentificarea utilizatorului
  • Verificarea drepturilor pe tabela sau baza de date respectivă (acest proces poartă numele de autorizare)
  • Determinarea celei mai apropiate regiuni pentru eficientizarea rutei
  • Verificarea existenței bazei de date, etc.

Implementezi toți acești pași și începi să realizezi că utilizarea acestei biblioteci create de tine nu va fi deloc simplă, pentru că pașii trebuie executați într-o anumită ordine, altfel nu va funcționa.

Asta nu e o problemă neapărat, e normal ca anumite procese să depindă de o serie de pași secvențiali (adică unul după celălalt), dar asta va face utilizarea bibliotecii tale să fie greu de folosit și de înțeles.

Diagrama Facade Design Pattern
class Authenticator:
    getToken(username, password): string
        // verificarea credențialelor și generarea tokenului de acces

class Authorizer:
    authorize(token): boolean
        // verificarea drepturilor de acces pe baza tokenului

class DatabaseConnector:
    region: Region

    DatabaseConnector(region: Region)
       this.region = region

    connect(): void
        // realizarea conexiunii la baza de date

class RegionResolver:
    identifyRegion(): Region
        // identificarea celei mai apropiate regiuni pe baza locației clientului

class Application
    authenticator: Authenticator
    authorizer: Authorizer
    dbConnector: DatabaseConnector
    regionResolver: RegionResolver

    main()
       token = authenticator.getToken(username, password)
       isAuthorized = authorizer.authorize(token)

       if (!isAuthorized)
            // .. eroare de autorizare

       region = regionResolver.identifyRegion()

       // obținerea conexiunii
       dbConnector.connect()

       // .. acțiuni de citire, scriere etc. în baza de date

Soluția: fațada

Aici vine “fațada” să ne salveze.

Fațada presupune adăugarea unei clase de “fațadă” care va orchestra tot procesul cu efort minim din partea clientului. (în terminologia tehnică, termenul “client” face referire la codul apelant).

Simplu spus, fațada doar agreghează și execută pașii pe care clientul ar trebui să-i facă pentru a-i ușura efortul.

După implementarea fațadei, componentele noastre de cod din diagrama anterioară ar trebui să arate așa:

Diagrama Facade Design Pattern

Codul client folosește acum CloudDatabaseFacade pentru a comunica cu baza de date într-un mod mult mai simplificat față de cel anterior.

Sigur, exemplul este unul care omite multe alte detalii, pentru că în cele din urmă acea fațadă tot ar trebui să fie configurată cu toate elementele necesare, cum ar fi credențialele de acces, numele bazei de date șamd. pentru a funcționa, dar ideea principală este ca fațada să fie unicul punct de contact.

class Authenticator:
    getToken(username, password): string
        // verificarea credențialelor și generarea tokenului de acces

class Authorizer:
    authorize(token): bool
        // verificarea drepturilor de acces pe baza tokenului

class DatabaseConnector:
    region: Region

    DatabaseConnector(region: Region)
       this.region = region

    connect(): void
        // realizarea conexiunii la baza de date

class RegionResolver:
    identifyRegion(): Region
        // identificarea celei mai apropiate regiuni pe baza locației clientului

class CloudDatabaseFacade:
    authenticator: Authenticator
    authorizer: Authorizer
    dbConnector: DatabaseConnector
    regionResolver: RegionResolver

    connect(): void
       token = authenticator.getToken(username, password)
       isAuthorized = authorizer.authorize(token)
    
       if (!isAuthorized)
            // .. eroare de autorizare
        
       region = regionResolver.identifyRegion()
    
       // obținerea conexiunii
       dbConnector.connect()

class Application
    dbFacade: CloudDatabaseFacade

    main()
       dbFacade.connect()

       // .. acțiuni de citire, scriere etc. în baza de date

Exemplul dat, deși a fost simplificat, e unul cât se poate de real.

Toți furnizorii de servicii de cloud oferă astfel de biblioteci pentru interacțiunea cu serviciile lor care în spate ridică tot greul pentru tine, astfel să te poți concentra pe logica aplicației tale, nu pe configurarea infrastructurii.

Un alt exemplu, la fel de real, e următorul: servicii de back-end, cum ar fi web APIs, pun la dispoziția celor care trebuie să le apeleze biblioteci prin intermediul cărora se pot integra cu acele API-uri.

De multe ori, aceste biblioteci expun o clasă de tip “client” care intermediază toate operațiunile necesare pentru apelarea unui anume API, cât și procesele intermediare, cum ar fi autentificarea, autorizarea etc. făcând astfel procesul de interacțiune dintre diferite servicii în back-end extrem de simplu.

Când să folosești fațada

Cel mai evident semn că trebuie să folosești o fațadă în implementarea ta e situația de care îți povesteam mai devreme, în care ai mai multe componente de cod care trebuie să fie apelate într-un anume fel și într-o anumită ordine pentru a obține un rezultat.

În exemplul dat, rezultatul era conexiunea la o bază de date din cloud făcută în 4 pași:

  • Autentificarea și obținerea unui token
  • Verificarea drepturilor acelui token cu respectiva bază de date
  • Identificarea celei mai apropiate regiuni (furnizorii de servicii de cloud au mai multe regiuni pe glob, se folosește în general regiunea mai apropiată de locația clientului)
  • Realizarea conexiunii cu baza de date

Complexitatea asta a fost ascunsă în spatele fațadei, care a preluat responsabilitatea de la client.

Atât pentru azi, ne auzim data viitoare.

Hai în comunitate

Strategii de carieră și concepte tehnice explicate pe înțelesul tău.