ResourceSerializable: un sostituto a ORM e ActiveRecord

2

Alcuni motivi per i quali non mi piacciono i tradizionali schemi ORM e ActiveRecord:

  • Funzionano solo con un database. A volte mi occupo di oggetti da un'API e altri oggetti da un database. Tutte le implementazioni che ho visto non lo consentono. Sentiti libero di identificarmi se mi sbaglio in questo.
    • Sono fragili. Le modifiche nel database potrebbero interrompere la tua implementazione. Alcune implementazioni possono aiutare a ridurre questo, ma alcuni di quelli che ho visto non lo fanno.
    • Il loro design è influenzato dal database. Se voglio passare all'utilizzo di un'API, dovrò riprogettare l'oggetto per farlo funzionare (probabilmente).
  • Sembra violare il modello di responsabilità singola. Sanno cosa sono e come agiscono, ma sanno anche come vengono creati, distrutti e salvati? Sembra un po 'troppo.

Che dire di un approccio che è un po 'più familiare in PHP: implementare un'interfaccia? In php 5.4, avremo l'interfaccia JsonSerializable che definisce i dati come json_encode d, così gli utenti si abitueranno a questo tipo di cose. Cosa accadrebbe se ci fosse un'interfaccia ResourceSerializable ? Questo è ancora un ORM per nome, ma certamente non per tradizione.

interface ResourceSerializable {
    /**
     * Returns the id that identifies the resource.
     */
    function resourceId();

    /**
     * Returns the 'type' of the resource.
     */
    function resourceType();

    /**
     * Returns the data to be serialized.
     */
    function resourceSerialize();
}

Le cose potrebbero essere scarsamente denominate, prenderò suggerimenti.

Note:

  • ResourceId funzionerà per API e database. Se la chiave primaria nel database è uguale all'ID risorsa nell'API, non c'è conflitto. Tutte le API con cui ho lavorato hanno un ID univoco per la risorsa, quindi non vedo alcun problema lì.
  • ResourceType è il gruppo o il tipo associato alla risorsa. Puoi utilizzare questo per associare la risorsa a una chiamata API oa una tabella di database. Se ResourceType era person , potrebbe mappare a /api/1/person/{resourceId} e la tabella persons (o people , se è abbastanza intelligente).
  • resourceSerialize () restituisce i dati da memorizzare. I tasti identificano i parametri API e le colonne della tabella del database.
  • Sembra anche più facile da testare rispetto alle implementazioni di ActiveRecord / Orm. Non ho eseguito molti test automatici sulle implementazioni di ActiveRecord / ORM tradizionali, quindi questa è solo un'ipotesi. Ma mi sembra di essere in grado di creare oggetti indipendentemente dalla libreria. Non devo usare load() per ottenere una risorsa esistente, posso semplicemente crearne una e impostare tutte le proprietà giuste. Questo non è così facile nelle implementazioni di ActiveRecord / Orm che ho affrontato.

Svantaggi:

  • Hai bisogno di un altro oggetto per serializzarlo. Questo significa anche che hai più codice in generale dato che devi usare più oggetti.
  • Devi mappare i tipi di risorse alle chiamate API e alle tabelle del database. Questo è ancora più lavoro, ma alcune implementazioni ORM e ActiveRecord richiedono comunque di associare gli oggetti ai nomi delle tabelle.

Ci sono altri aspetti negativi che vedi?

Ti sembra fattibile?

Come lo miglioreresti?

Nota: l'ho quasi chiesto su StackOverflow perché potrebbe essere troppo vago per i loro standard, ma non ho ancora familiarità con programmers.stackexchange.com, quindi per favore aiutami a migliorare la mia domanda se non lo fa t conformarsi agli standard qui.

    
posta Levi Morrison 18.11.2011 - 19:36
fonte

2 risposte

1

Non tutti gli ORM sono uguali. Ad esempio, (mi dispiace per il mio background non PHP qui - vedi più avanti) Hibernate e NHibernate fa una grande differenza dal fatto che le tue classi di entità sono" Plain Old Java Objects "o" Plain Old CLR Objects "(ovvero POJO's e POCO's). EntityFramework 4.0 consente anche a questo.

Ciò significa che non sanno nulla di persistere. Pertanto, se utilizzi il modello di repository , la logica di persistenza è completamente nascosta. All'interno dell'implementazione del repository crei una mappatura dalle tue entità a qualsiasi database / servizio / qualsiasi cosa tu voglia. (N) Hibernate ha opzioni per specificare questo in XML o fluentemente con un'API. Tuttavia, puoi sostituirlo con un repository che persiste le tue entità su un servizio web.

Svantaggi?

È più lavoro di entità generate automaticamente dal database, se il tuo database esiste già. (D'altra parte, (N) Hibernate può effettivamente generare il tuo schema di database per te in base al tuo mapping di entità.)

fattibile?

Sì, penso che sia solo il modello di repository con un altro nome. Tuttavia, non mi piace l'idea di dover derivare le mie classi di entità da una classe base speciale, come hai definito.

Migliora?

Attenzione a non reinventare la ruota qui. Assicurati di fare un primo sondaggio su tutte le opzioni, come Doctrine o Propel . Molte menti più brillanti di noi hanno lavorato per decenni a questo genere di cose, e hanno elaborato soluzioni molto avanzate e flessibili.

    
risposta data 18.11.2011 - 21:11
fonte
1

Si parla molto di ORM essendo indipendenti dall'archiviazione, in base alla teoria che si potrebbe voler cambiare l'archivio dati sottostante. In pratica, ciò accade quasi mai, ed è molto lavoro quando lo fa; non si tratta semplicemente di scollegare il RDBMS di un fornitore e collegarne un altro.

Puoi rimanere indipendente dal produttore attaccando un dialetto di SQL che funziona con tutti i fornitori, ma alla fine stai ancora parlando di un database SQL (al contrario di un archivio di valori-chiave come BigTable), e se hai bisogno di funzionalità uniche di SQL, allora sei praticamente bloccato con un RDBMS.

Si noti che quanto più lontano si ottiene da SQL, minore è la forma degli oggetti dati e più lavoro si deve fare da soli.

    
risposta data 18.11.2011 - 23:57
fonte

Leggi altre domande sui tag