Python 3
Machine Learning

PENTRU ELEVII DE LICEU

APLICAȚIE
PAG. 1 / 1
Sistem de notificări
Acasă >>> Lecții online



Un scenariu extrem de des întâlnit în dezvoltarea de aplicații este cel al trimiterii de notificări. Fie că este vorba de un mesaj email, un SMS sau o alertă push, acțiunea este aceeași din punct de vedere logic: "trimite notificare". Modul în care aceasta este livrată însă diferă în funcție de canalul de comunicare.

Folosind polimorfismul, putem defini o interfață comună pentru toate aceste tipuri de notificări, fără a fi nevoiți să scriem cod repetitiv sau ramificat în stilul clasic if/else:

Să analizăm cu atenție codul următor, executându-l acum:
Editor - citire_lista.py
       
Rezultatul în consolă done
DETALII

Astfel, avem trei clase complet independente (Email, SMS, NotificarePush), care nu moștenesc de la vreo clasă comună și nici nu au o relație formală între ele. Totuși, fiecare dintre acestea implementează o metodă cu același nume: trimite().

Funcția trimite_notificare() este generică. Ea nu are idee ce tip concret de obiect primește – știe doar că obiectul respectiv trebuie să aibă o metodă trimite(). Dacă acel obiect o conține, funcția o va apela. Dacă nu, va apărea o eroare la execuție.

Aceasta este esența a ceea ce numim în Python polimorfism prin duck typing: nu ne interesează tipul obiectului, ci doar comportamentul său.

Ce rezolvă această abordare?

Fără polimorfism, ai fi fost tentat să scrii ceva de genul:

def trimite_notificare(tip, mesaj):
    if tip == "email":
        print(f"Trimit prin email: {mesaj}")
    elif tip == "sms":
        print(f"Trimit SMS: {mesaj}")
    elif tip == "push":
        print(f"Trimit notificare push: {mesaj}")


Dar această variantă:

  • este mai greu de întreținut (fiecare nou tip impune o modificare în cadrul acestei funcții);
  • încalcă principiul Open/Closed (codul trebuie să fie deschis extinderii, dar închis modificării);
  • nu se bazează pe obiecte, ci pe ramuri de control.
Observație. Prin polimorfism, codul este mult mai flexibil. Dacă mâine ai adăuga o clasă Telegrama, nu trebuie să modifici deloc logica funcției trimite_notificare(). Doar adaugi un nou obiect care are metoda trimite() și totul va funcționa ca înainte.

Haideți să extindem puțin aplicația…

Putem adăuga complexitate fără să stricăm structura. De exemplu:

class Email:
    def trimite(self, destinatar, mesaj):
        print(f"Email către {destinatar}: {mesaj}")

class SMS:
    def trimite(self, destinatar, mesaj):
        print(f"SMS către {destinatar}: {mesaj}")

class NotificarePush:
    def trimite(self, destinatar, mesaj):
        print(f"Push către {destinatar}: {mesaj}")

def trimite_notificare(n, destinatar, mesaj):
    n.trimite(destinatar, mesaj)

lista = [Email(), SMS(), NotificarePush()]

for notif in lista:
    trimite_notificare(notif, "Ion Popescu", "Ai mesaj nou.")


Nimic nu s-a schimbat din punctul de vedere al structurii — doar că metoda trimite() primește acum parametri personalizați. Evident, codul rămâne clar, coerent și extensibil.

CONCLUZIE

Polimorfismul nu înseamnă doar economie de cod. Este o formă de gândire orientată spre comportament, nu spre tipuri. Acolo unde poți trata obiectele în mod uniform, fă-o. Codul tău va fi mai ușor de testat, mai ușor de extins, și mai apropiat de modelul logic al realității pe care o simulezi.
Aplicația s-a încheiat acum.
 home   list  LECȚII   perm_identity   arrow_upward