Sobes.tech
Middle

Secondo quale principio i metodi sono raggruppati e separati nelle interfacce?

sobes.tech AI

Risposta dell'AI

I metodi nelle interfacce vengono raggruppati e separati secondo il principio di coesione del comportamento e il principio di contratto esplicito.

  • Coesione del comportamento: I metodi che rappresentano un insieme unico di operazioni con un'entità o che eseguono azioni simili in senso sono raggruppati in un'unica interfaccia. Ciò migliora la leggibilità del codice, facilita la comprensione dello scopo dell'interfaccia e ne aumenta la riutilizzabilità.
  • Contratto esplicito: L'interfaccia descrive un contratto esplicito che le classi che la implementano devono rispettare. Ogni metodo nell'interfaccia fa parte di questo contratto. I metodi vengono divisi tra diverse interfacce se rappresentano aspetti diversi del comportamento o se la loro implementazione può variare indipendentemente. Ad esempio, l'interfaccia Readable può contenere metodi per leggere dati, e Writable per scrivere. Una classe può implementare una o entrambe le interfacce a seconda delle sue capacità.

Questo approccio favorisce i principi SOLID, in particolare:

  • Principio di responsabilità singola: L'interfaccia ha una sola ragione per cambiare, ovvero la modifica del set di comportamenti che descrive.
  • Principio di segregazione delle interfacce: I clienti non devono dipendere da interfacce che non utilizzano. La suddivisione di grandi interfacce in più piccole e focalizzate permette alle classi di implementare solo quelle di cui hanno realmente bisogno.

Esempio:

Supponiamo di avere un'entità che può essere salvata e caricata. Invece di un'unica interfaccia Persistable con due metodi save() e load(), è meglio creare due interfacce separate:

// Interfaccia per entità salvabili
interface Savable
{
    public function save(): void;
}
// Interfaccia per entità caricabili
interface Loadable
{
    public function load(): void;
}

Una classe che può essere salvata e caricata implementa entrambe le interfacce:

// Classe che implementa entrambe le interfacce
class DataObject implements Savable, Loadable
{
    public function save(): void
    {
        // Logica di salvataggio
    }

    public function load(): void
    {
        // Logica di caricamento
    }
}

Una classe che viene salvata solo implementa solo Savable:

// Classe che implementa solo l'interfaccia Savable
class TempData implements Savable
{
    public function save(): void
    {
        // Logica di salvataggio dei dati temporanei
    }
}

Questo permette di progettare classi e le loro dipendenze in modo più flessibile.