Infocurci
* Claudio Curci  /  Php developer
* Claudio Curci  /  Php developer

4. lezione: Coupling e Cohesion nel codice reale


Oggi parliamo di due principi chiave di una buona programmazione ad oggetti: Coupling e Cohesion. Affrontare nel modo giusto questi due concetti ci aiuta a scrivere codice professionale e robusto.

Cosa si intende per Coupling?

Il coupling, ovvero "accoppiamento", indica la dipendenza di una classe da altre. Piu che dipendenza, si potrebbe parlare di "conoscenza". Ecco un esempio pratico:

<?php
class RisultatoService
                {
                    public function process($data)
                    {
                        $db = new MySQLConnection();
                        $mailer = new SmtpMailer();
                        $logger = new FileLogger();
                        
                        $db->save($data);
                        $mailer->send('Ecco il tabellino della partita');
                        $logger->log('Processato dato della partita');
                    }
                }
Questa classe "conosce" fin troppo delle altre. Se un domani il database anzichè MySql diventasse un PostgreSQL? Se domani la classe "SmtpMailer" venisse deprecata e non più aggiornata e volessimo rimpiazzarla? Non ci potremmo limitare a sostituire queste classi, ma dovremmo ricercare nel nostro codice tutte le altre che la utilizzano.

Come risolviamo il problema del Coupling?

Riscriviamo la classe precedente in questo modo:

<?php
class RisultatoService
                {
                    public function __construct
                    (
                        private RisultatoRepository $repository,
                        private MailerInterface $mailer,
                        private LoggerInterface $logger
                    ) {}

                    public function process(array $data): void
                    {
                        $this->repository->save($data);
                        $this->mailer->send("Ecco il tabellino della partita");
                        $this->logger->log("Processato dato della partita");
                    }
                }
Uno scenario decisamente diverso. L'utlizzo di interfaccie ci consente di sostituire facilmente le dipendenze ed evita di portar dietro delle classi concrete. Oltre alla flessibilità diventa più semplice anche il lavoro di test.

Cosa è invece la Cohesion?

Traduzione facilissima, la coesione indica la specializzazione di una classe, ovvero la sua capacità di far fronte ad un compito chiaro e coerente.
Prendiamo un esempio dal mondo del fantacalcio:

<?php
class UserManager
                {
                    public function createUser() {}
                    public function sendEmail() {}
                    public function setTeam() {}
                    public function setPoints() {}
                    public function printBadge() {}
                }
Una classe 'tuttofare' che esegue calcoli, invia email, genera pdf. Proviamo a separare i compiti:
<?php
class UserService
                {
                    public function createUser(array $data): User {}
                }
                
                class MailService
                {
                    public function sendEmail(User $user): void {}
                }
                
                class PdfGenerator
                {
                    public function printBadge(User $user): void {}
                }
Separare i compiti aumenta la coesione delle classi. Ogni oggetto si occupa di una sola responsabilità e diventa più semplice da comprendere, testare e modificare. Separare le responsabilità aumenta la coesione della singola classe. Inoltre, centralizzando l'invio delle email in un unico servizio, riduciamo l'accoppiamento tra il resto dell'applicazione e la libreria utilizzata per la spedizione dei messaggi.

Basso coupling, alta cohesion: oggi il software funziona cosi?

A questo proposito va citato l'esempio di Magento 2, dove si è intrapresa una strada interessante, quella di favorire controller molto piccoli e specializzati, spesso dedicati a una singola operazione.
Per cui è facile imbattersi in componenti con tanti controller, tutti molto leggeri, basati su un costruttore e un metodo execute(). Un controller che si limita a intercettare la richiesta http, validare i dati essenziali della richiesta, delegare la logica applicativa a servizi dedicati e restituire una risposta, magari attraverso un service Json.
Sono passati i tempi in cui trovavamo funzioni come questa:

<?php
public function execute()
                {
                    $data = $this->getRequest()->getPostValue();

                    $customer = new Customer();

                    $customer->setName($data['name']);

                    $this->connection->insert(...);

                    $this->mailer->send(...);

                    $this->logger->log(...);

                    // altre 200 righe
                }
oggi Magento, tanto per citarne uno, segue strade come questa:
<?php
public function execute()
                {
                    $this->customerRegistrationService->register(
                        $this->getRequest()->getPostValue()
                    );
                }
dove la logica è tutta altrove.

Come mi accorgo di usare codice sbagliato?

Posto che codice con alto coupling e bassa coesione può comunque funzionare benissimo, specie se si tratta di un applicativo che nel corso del tempo non è soggetto a modifiche, ci possiamo accorgere facilmente di aver intrapreso strade sbagliate grazie ad alcuni sintomi:

  • Dentro le classi troviamo frequenti istruzioni new per creare dipendenze applicative (repository, mailer, gateway, logger): significa che stiamo istanziando altre classi, con un alto coupling
  • Eccesso di dipendenze interne
  • Presenza di classi chiamate "manager", "service", "Helper" che anzichè fungere da servizi specializzati, contengono svariate ed eterogenee funzioni con compiti diversi
  • File/classi grandi sono di solito sintomo di bassa coesione

Il tuo Moodle è vulnerabile? Scoprilo in 10 secondi: scegli la tua versione e ottieni l’elenco delle falle di sicurezza note, con gravità e CVE. Verifica gratis ora →

Dal 1997, il Php a Roma!

Claudio Curci "La vera efficienza si trova nella serenità." (Henry David Thoreau)

"Guardati dalla sterilità di una vita sempre indaffarata." (Socrate)

Da quasi trent'anni mi dedico alla programmazione, con oltre 20 anni di esperienza come freelance. Certificato booking.com. Mi occupo di tutto quello che gravita attorno al Php: software custom, Magento, Woocommerce, Prestashop, Wordpress, Joomla!, Moodle.
Infocurci Questo sito rispetta gli utenti:
  • Non ospita nessuna pubblicità
  • Non utilizza cookie e non profila nulla
  • Non spreca risorse energetiche per asettiche illustrazioni AI
Navigate serenamente, siete i benvenuti.

Ambienti / piattaforme di sviluppo

Amazon Booking.com CodeIgniter Joomla Magento Moodle Kelkoo Kigo PayPal Symfony Wordpress Airbnb FormaLms Laravel Prestashop Shopify Whatsapp