2013-03-18 8 views
5

Ho studiato e letto molto sul lavoro con livelli separati in PHP per creare codice manutenibile e leggibile. Tuttavia, vedo un sacco di codice in cui l'entità e l'accesso al database sono collocati in una classe. Per esempio:php DAL - entità e database separati?

class User{ 
    public $id; 
    public $username; 
    public $database; 

    function add(){ 
      $database->query .... 
    } 
} 

trovo questo piuttosto strano perché qui si stia mescolando la classe utente con elementi di database che lo rende più difficile da mantenere.

Mi piace lavorare in questo modo:

  • un database separato classe classe
  • un utente
  • un userData

Questo funziona in questo modo:

$database = new Database(); 
$database->openConnection(); 
$dataUser = new DataUser($db); 
$user = new User(1,"myname"); 
$dataUser->saveUser($user); 

Quindi mi chiedo, sto lavorando nel modo giusto o è il primo modo un modo migliore per creare il codice? Trovo che sia molto semplice da mantenere perché hai un'entità separata e una classe di database separata per gestire le azioni del database.

+0

+1 bella domanda :) –

+1

+1 anche per bella domanda ... –

risposta

1

facile da mantenere perché avete un'entità separata ed un separato classe banca dati

Sembra che stai dicendo che si desidera allontanarsi da un approccio Active Record ad un approccio Data Mapper/Entity/Repository. Questa è una buona direzione da seguire perché impiega una migliore separazione delle preoccupazioni. Si può costruire da soli, ma si potrebbe desiderare di dare un'occhiata a soluzioni come Doctrine dove ti permette di fare qualcosa sulla falsariga di:

$product = new Product(); 
$product->setName($newProductName); 
$entityManager->persist($product); 

L'entità $product è solo un (Object Plain Old PHP) Popo che contiene i dati del record e non è a conoscenza di come è persistito e, quando è necessaria la persistenza, viene passato al gestore dell'entità per occuparsi dell'archiviazione.

+0

Grazie, voglio solo separare le entità in modo da poterle recuperare come un oggetto e non come una matrice con i dati, ad esempio. Guarderò in Dottrina. – randomizer

1

Personalmente, penso che l'astrazione dellodal User rischia di essere eccessivo. Come, in questo caso, UserData è probabile che sia molto simile a ProductData per esempio - sono ancora in corso per contenere un add($data), find($id) ecc

Nel tuo caso, User è un modello nell'approccio MVC, ed è totalmente accettabile per contenere la logica di archiviazione/recupero del database. Tuttavia, probabilmente lo scoprirai, ricreando di nuovo gli stessi metodi DB nella classe User che hai in altri modelli. Qui è dove si può iniziare a guardare un'implementazione ORM. In base al quale i metodi di accesso DB comuni sono definiti in una classe astratta che quindi tutti i modelli si estendono e sovrascrivono se necessario.

+0

Stavo leggendo di nuovo questo argomento e non capisco davvero la tua ultima riga. Non è normale che i miei Userdata, ProductData, ecc. Contengano tutti una funzione "salva", "trova" e "cancella" perché devono eseguire una query su una tabella diversa. Non ho il vantaggio di una classe astratta qui, vorrei usare una classe astratta per dire istanziare la mia scheda di database in modo che sia utilizzabile in tutte le mie classi xData. – randomizer

1

quello che faccio:

I miei modelli non sono entità legate al database (quando non sto usando la dottrina), in modo che nessun metodi "record attivo". Un oggetto non sa come recuperare le sue dipendenze (per esempio, un utente può avere n commenti, il mio modello non sa come ottenere commenti).

class User{ 
private $name; 
private $password; 
// getter and setters 
} 

devo servizi che tengono una certa logica di business in grado di recuperare modelli da fornitori, un servizio può avere molti fornitori.

class UserService{ 
    function __construct(IUserProvider $userProvider){ 
     $this->userProvider = $userProvider 
    } 
    function getUsers(){ 
     // return an array of user objects 
     return $this->userProvider->getUsers(); 

    } 
} 

finalmente ho un provider di dati che sa come richiedere dati dal database, un file di testo, un file JSON, un webservice:

class UserProvider implements IUserProvider{ 
     function __construct(Connection $connection){ 
     $this->connection = $connection; 
     } 
     function getUsers(){ 
     return $this->toUsers($this->connection->fetchAssoc("Select * from users")); 
     } 
     function toUsers(array $datas){ 
      // convert user records to an array of User 
      (...) 
      return $users; 
     } 
} 

poi l'interfaccia

interface IUserProvider{ 
    /**@return array an array of User */ 
    function getUsers(); 
} 

se ho bisogno di ottenere un commento utente, il mio servizio di commento sa come recuperare i commenti da un id utente. Quindi per ottenere un utente e i suoi commenti, ho bisogno di 2 richieste al database. uno da UserProvider, l'altro da CommentProvider.

così ho 3 strati:

  • il mio livello di applicazione (utenti di visualizzazione, rispondere alle richieste di qualunque cosa ...)
  • il mio livello di servizio (che deve lavorare con un'interfaccia a riga di comando e non è consapevole della mia applicazione web, fatta eccezione per la codifica della password che di solito è binded al quadro che uso, e ACL infila forse ...)
  • il mio livello di accesso ai dati, che non sa nulla degli altri strati,

l'unico modo in cui i miei livelli comunicano è attraverso i Modelli che passo da un livello all'altro.

E tutte le mie classi sono costruite con un contenitore di iniezione dipendente, quindi il cablaggio non è un problema.

Ecco un esempio di un app che ho fatto, è open source: https://github.com/Mparaiso/silex-bookmarkly

Ogni pensiero di benvenuto.

Problemi correlati