2012-10-26 4 views
1

Je démarre une application basée sur zend framework; cette application devrait pouvoir utiliser plusieurs sources de données autres qu'une base de données; un webservice par exemple.Utilisation de plusieurs sources de données avec Zend Framework

J'ai lu sur la façon de structurer mon modèle afin de permettre ce scénario. J'ai rencontré divers concepts qui semblent apporter une solution à cela (modèle DataMapper, modèle de service, couche adaptateur, etc.). Cependant, je suis toujours confus sur la façon de mettre tout cela ensemble dans une base de code réutilisable et évolutive.

J'ai déjà travaillé avec zend framework et je travaillerai normalement avec une table mysql. Si par exemple, j'ai une table Users ... J'ai simplement une classe Users dans mon modèle qui contient la logique métier du domaine utilisateur et une classe User qui étend Zend_Db_Table_Row_Abstract représentant une ligne dans la table user. Comment mieux organiser mon modèle et ma base de code de telle sorte que je puisse toujours appeler $ users-> fetchAll() et obtenir une collection d'objets utilisateur quelle que soit ma source de données?

Répondre

4

Il fonctionne fondamentalement le même que vous avez fait avant, juste qu'au lieu d'un Zend_Db_Table_Gateway vous utilisez un My_UserGateway_Whatever, par exemple. créer une première interface:

interface UserGateway 
{ 
    /** 
    * @return array 
    * @throws UserGatewayException 
    */ 
    public function findAll(); 
} 

Nous ne voulons pas des exceptions du béton Passerelles à apparaître dans le code la consommation, donc nous ajoutons la UserGatewayException comme un fourre-tout:

class UserGatewayException extends RuntimeException 
{} 

Ensuite, ajoutez une classe d'implémentation Interface:

class My_UserGateway_Webservice implements UserGateway 
{ 
    public function findAll() 
    { 
     try { 
      // insert logic to fetch from the webservice 
      return $userData; 
     } catch (Exception $e) { 
      throw new UserGatewayException($e->getMessage(), $e->getCode, $e); 
     } 
    } 

    // … more code 
} 

de même, si vous souhaitez utiliser une source de base de données, vous pouvez écrire un adaptateur pour les classes Zend_Db_ *, par exemple

class My_UserGateway_Database implements UserGateway 
{ 
    private $tableDataGateway; 

    public function __construct(Zend_Db_Table_Abstract $tableDataGateway) 
    { 
     $this->tableDataGateway = $tableDataGateway; 
    } 

    public function findAll() 
    { 
     try { 
      return $this->tableDataGateway->select()->blah(); 
     } catch (Exception $e) { 
      throw new UserGatewayException($e->getMessage(), $e->getCode, $e); 
     } 
    } 

    // … more code 
} 

Si vous besoin d'un autre fournisseur de données, assurez-vous qu'ils mettent en œuvre cette interface, vous pouvez compter sur la méthode findAll d'être là. Faites dépendre votre classe consommatrice de l'interface, par ex.

class SomethingUsingUsers 
{ 
    private $userGateway; 

    public function __construct(UserGateway $userGateway) 
    { 
     $this->userGateway = $userGateway; 
    } 

    public function something() 
    { 
     try { 
      $users = $this->userGateway->findAll(); 
      // do something with array of user data from gateway 
     } catch (UserGatewayException $e) { 
      // handle Exception 
     } 
    } 

    // … more code 
} 

Maintenant, lorsque vous créez SomethingUsingUsers vous pouvez facilement injecter un ou l'autre passerelle dans le constructeur et votre code ne fonctionnera quelle que soit la passerelle que vous avez utilisé:

$foo = SomethingUsingUsers(
    new My_UserGateway_Database(
     new Zend_Db_Table('User') 
    ) 
) 

ou, pour le Webservice:

$foo = SomethingUsingUsers(
    new My_UserGateway_Webservice(
     // any additional dependencies 
    ) 
) 
Questions connexes