Modelli per tabella di database?


11

Sto usando codeigniter e mi sono trovato in una situazione simile in cui ho ripetuto i metodi del modello. Sto creando un modello per controller. Ma la creazione di un modello per tabella di database sarebbe considerata una buona pratica? In questo modo i metodi non vengono scritti due volte.

Invece di Modello per controller o Diversi piccoli modelli condivisi.

Esempio se ho un metodo modello get_user ($ user_id) potrei scriverlo su users_models.php ...

Uno degli aspetti negativi che vedo di questo è che potrei dover chiamare diversi modelli, piuttosto che solo controllerername_models.php.

Il caricamento di più modelli in cui diversi metodi non possono essere utilizzati da un controller potrebbe influire sulle prestazioni e sulla velocità? Quale potrebbe essere il modo migliore per affrontare questo problema?

Nota: ci sono domande simili, ma non coprono il terreno del modello per tabella del database.

Risposte:


8

Dico che un modello per tabella sta semplicemente ricreando il database in una struttura di classe. È noto come un modello anemico e considerato un anti-pattern. Questo perché le classi devono avere sia dati che comportamento. Se limiti i tuoi modelli a una singola tabella, dove inserisci il codice (comportamento) che deve gestire dati e comportamento da più tabelle? I tuoi controller avrebbero quindi bisogno di modelli che utilizzino uno o più di questi modelli "da tavolo" ... Quindi, a parte le app più elementari, guadagni poco o niente da questo approccio.


Solo un po 'di un addendum - è considerato un anti-pattern da Martin Fowler. Fullstop qui. Ha qualche informazione su questo caso, ma questo non significa che è male - diversamente da Dio Object, che è quasi sempre male, una struttura come questa è a volte incredibili utile e facilmente maitenable. Non lo considero affatto un anti-pattern.
T. Sar

1
Ad esempio, il "modello anemico" è conforme a SOLID - è davvero male avere un oggetto con un unico scopo (memorizzare i dati)? Mentre rispetto molte cose che dice il signor Fowler, questa è stata una cazzata.
T. Sar

7

In generale, è necessario creare i modelli non per tabella o per controller ma per oggetto business. A volte può essere una relazione 1: 1 con la struttura delle tabelle o con i controller, ma non è necessario.

Nel tuo esempio potresti avere una users_modelclasse chiamata da più controller. Questo va bene e talvolta anche desiderabile. Tuttavia, nella maggior parte dei casi, la users_modelclasse otterrà i suoi dati da diverse tabelle.
Ad esempio, la last_login_dateproprietà della users_modelclasse può ( non deve ) essere ottenuta da una user_audittabella separata che ha una relazione uno-a-molti con la userstabella principale .

E direi che se si dispone di una tabella SQL per oggetto business, è molto probabile che la struttura del database non sia normalizzata.


3

Concordo principalmente con la risposta di Dime che desideri creare i tuoi modelli per oggetto di business - i problemi che l'azienda sta cercando di risolvere dovrebbero guidare il modo in cui crei le classi del modello. In pratica, ho scoperto che la creazione di un modello per tabella è un buon punto di partenza. È probabile che uno schema correttamente progettato imiti i processi aziendali che è necessario modellare nel codice dell'applicazione, chiamato anche modello di dominio.

L'uso di un livello Mappatura oggetto / relazionale è utile, pertanto il modello di dominio contiene le stesse relazioni dello schema del database senza la necessità di chiamate ripetitive a un livello di accesso ai dati. Dai un'occhiata a Eloquent per PHP come esempio. Sia lo schema che il modello di dominio devono essere progettati per supportare i processi aziendali.

Questo porta alla prima parte della risposta di Marjan Venema:

Dico che un modello per tabella sta semplicemente ricreando il database in una struttura di classe. È noto come un modello anemico e considerato un anti-pattern.

Un modello di dominio anemico è un anti-schema. Un "modello per tabella" come suggerisce Venema potrebbe essere visto come "ricreare il database", tuttavia è assolutamente errato affermare che questo da solo è un modello di dominio anemico.

Da Martin Fowler:

Il sintomo di base di un modello di dominio anemico è che a prima vista sembra la cosa reale. Esistono oggetti, molti dei quali prendono il nome dai nomi nello spazio del dominio e questi oggetti sono collegati con le ricche relazioni e la struttura che hanno i veri modelli di dominio. La cattura viene quando si osserva il comportamento e ci si rende conto che non c'è quasi alcun comportamento su questi oggetti, rendendoli poco più che sacchi di getter e setter.

(enfasi, mia)

Il fattore chiave in un modello di dominio anemico è la mancanza di comportamento o metodi nelle classi del modello di dominio.

Questo perché le classi devono avere sia dati che comportamento. Se limiti i tuoi modelli a una singola tabella, dove inserisci il codice (comportamento) che deve gestire dati e comportamento da più tabelle?

Ancora una volta, puoi e dovresti inserire il comportamento nei tuoi modelli di dominio, anche se mappano solo su una tabella. Il comportamento che influisce su più tabelle influisce realmente su più oggetti associati a più tabelle. Domain Driven Design è un approccio esattamente allo stesso problema menzionato da Venema: "dove metti il ​​codice (comportamento) che deve gestire dati e comportamento da più tabelle?"

E la risposta è una radice aggregata . Martin Fowler afferma:

Aggregate è un modello in Domain-Driven Design. Un aggregato DDD è un cluster di oggetti dominio che possono essere trattati come una singola unità. Un esempio può essere un ordine e i suoi elementi pubblicitari, questi saranno oggetti separati, ma è utile trattare l'ordine (insieme ai suoi elementi pubblicitari) come un unico aggregato.

(enfasi, mia)

Un "cluster di oggetti di dominio" può anche essere visualizzato come "Modelli di dominio associati a più tabelle". Il comportamento che influenza più tabelle dovrebbe essere definito sulla radice aggregata - Una classe che incapsula la "cosa" che influenza più tabelle o oggetti:

Ancora una volta, da Martin Fowler:

Un aggregato conterrà spesso raccolte multiple, insieme a campi semplici.

Per rispondere alla domanda originale del PO:

... la creazione di un modello per tabella di database sarebbe considerata una buona pratica? In questo modo i metodi non vengono scritti due volte.

Direi che questo è un buon punto di partenza, ma tieni presente che lo schema e il modello a oggetti non devono corrispondere al 100%. Il modello a oggetti dovrebbe riguardare maggiormente l'implementazione e l'applicazione delle regole aziendali. Lo schema dovrebbe essere maggiormente focalizzato sulla memorizzazione dei dati aziendali in modo modulare e scalabile.

Un modello per controller non sarebbe una buona pratica, anche se esiste una variante del modello chiamata View Model che si adatta al livello Controller. Un modello di visualizzazione è una riorganizzazione del modello di dominio per adattarsi a un determinato tipo di visualizzazione, sia essa una pagina Web o un modulo in un'applicazione GUI.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.