---
title: Principi de la inversió de la dependència i accés a dades
tags: daw
---
# Inversió de la dependència (DiP: Dependency inversion principle).
[Vincle a font en MarkDown](https://hackmd.io/@JdaXaviQ/HJV_WvH0K)
La inversió de la dependència és la 'D' dels principis 'SOLID': 'Dependency inversion principle', que ens diu que hem de dependre d'abstraccions i no pas d'implementacions.
Una de les característiques on queda molt clar l'ús d'aquest principi és a l'accés a dades: imaginem que tenim una classe 'Client' i hem de desar la informació dels objectes instàncies d'aquesta classe a la nostra base de dades. Seria molt temptador afegir un mètode a la nostra classe Client que passant-li una connexió a la nostra base de dades executés les consultes SQL de tipus 'INSERT' per desar la seva informació i les de tipus 'SELECT' per recuperar la informació de la base de dades. Aquesta solució faria que la nostra classe Client depengui fortament del motor i tipus de base de dades utilitzada i dificultaria moltíssim la reutilització del codi en projectes que utilitzin un altre tipus de persistència.
Un disseny millor pot consistir en que la classe 'Client' tingui una propietat del tipus 'PersistenciaClient' i que la classe PersistènciaClient tingui dos mètodes desaClient():void i recuperaClient():Client i que sigui aquesta classe la que s'encarregui de la implementació del accés a la base de dades. En aquest darrer disseny no hem guanyat gaire en reusabilitat del codi, perquè encara depenem d'una classe que depèn formament d'una altra que està molt lligada al nostre motor de base de dades actual.
El pas següent pot consistir en convertir la classe 'PersistenciaClient' en una interface, d'aquesta forma podem tenir diferents implementacions per diferents motors de base de dades i fins i tot per diferents tipus de persistència.

Amb aquest disseny, podriem per exemple tenir una classe Client de la següent forma:
```php=
<?php
class Client {
protected $persistencia = new PersistenciaClientMySql('cadena connexió a mySql');
...
}
?>
```
però seria molt millor '_injectar_', la dependència a la classe concreta des de fora de la classe Client, amb un '_setter_' o des del propi _constructor_ de la classe:
```php=
<?php
class Client {
protected $persistencia;
function __construct(PersistenciaClient $persistencia) {
this->$persistencia = $persistencia;
}
...
}
?>
```
Arribats a aquest punt tenim una classe Client totalment desacoblada del motor de base de dades utilitzat i podriem crear una classe 'PersistenciaClientFactory' que basant-se en un fitxer de configuració generès el tipus adient de PersistenciaClient per a cada projecte.
```php=
<?php
class PersistenciaClientFactory {
public static function makeClient(String $tipusClient, String $connectionString){
$resultat = null;
switch ($tipusClient) {
case strtolower("mySql"):
$resultat = new PersistenciaClientMySql($connectionString);
break;
case strtolower("mongoDB"):
$resultat = new PersistenciaClientMongoDb($connectionString);
break;
default:
$resultat = null;
break;
}
}
?>
```