I modelli di dati dovrebbero sapere dove / come sono memorizzati?

3

Ho alcune classi che rappresentano, per la maggior parte, dati deserializzati da XML. Hanno anche un certo comportamento in loro, perché non voglio soffrire di un modello di dominio anemico. Questi oggetti di dominio non hanno alcun codice XML specifico al loro interno, ma hanno proprietà che corrispondono esattamente ai tag e agli attributi nell'XML.

Molti comportamenti di queste classi si basano su risorse caricate dal disco, come le immagini. Per questo, alcuni attributi di proprietà / xml sono percorsi di file relativi a queste risorse. Ora iniziano i miei problemi. Il percorso assoluto da costruire per queste risorse è basato su una dipendenza separata - la radice del "progetto". Ecco a cosa sto combattendo:

  1. I miei oggetti di dominio dovrebbero memorizzare il percorso assoluto completo delle loro risorse? O solo i percorsi relativi? Se hanno il percorso assoluto, le classi che li caricano - i miei lettori XML - dovranno prendere una dipendenza dalla radice del progetto per costruire il percorso completo per loro. Altrimenti, dovrò fare un altro livello di classi per gestirlo. Ho già 3 livelli, non so se posso più gestirli!

  2. I miei oggetti di dominio dovrebbero memorizzare i propri percorsi per dove sono sul disco? Ha senso per loro sapere dove sono le loro dipendenze rispetto a loro, ma conoscere la loro posizione mi sembra semplicemente sbagliato in modo intuitivo. Questo è in qualche modo estraneo all'altra parte della domanda, ma penso che se mi fossi sbagliato in questo modo potrei mordermi più tardi.

posta Tesserex 06.05.2014 - 03:24
fonte

3 risposte

3

@teresko ti ha già dato una buona risposta per la tua domanda 2, e provo ad aggiungere una risposta per la parte 1:

Supponiamo che tu abbia un oggetto business Image con alcune proprietà, inclusa una proprietà (persistente) FilePath (presumo che l'oggetto Image non carichi automaticamente quei dati in memoria, semplicemente usando un riferimento ai dati o contenente metadati relativi al file immagine). Ovviamente, dato che hai diverse immagini da trattare, ognuna con i suoi dati nella stessa cartella radice del progetto (e questa cartella potrebbe cambiare in futuro), non vuoi memorizzare il percorso assoluto in ogni oggetto immagine, solo relativo percorsi. Supponiamo che tu abbia un oggetto business Project con una proprietà RootFolder . Anche questo oggetto business potrebbe essere un oggetto persistente o potrebbe essere creato e inizializzato in fase di esecuzione, qualunque sia la soluzione migliore per le tue esigenze.

Ora hai due opzioni per accedere ai file immagine:

  • o aggiungi una proprietà (derivata) AbsoluteFilePath alla tua classe Image. Per fare in modo che questa proprietà restituisca la concatenazione del percorso relativo e della cartella radice, i tuoi oggetti Image devono dipendere dall'oggetto Project . Questa dipendenza può essere costruita / iniettata durante il processo di costruzione dell'oggetto Image , oppure si ha un processo di costruzione a due fasi in cui dopo la deserializzazione la dipendenza viene iniettata in seguito, oppure può essere codificata in qualche modo nell'oggetto Image , ma non puoi evitarlo

  • oppure, non aggiungi tale proprietà alla classe Image e lascia che il codice client (il codice che utilizza l'oggetto Image ) gestisca il problema. In questo caso, potrebbe essere utile aggiungere un metodo helper GetAbsolutePath(relativePath) alla classe Project e riutilizzare questo metodo in tutto il codice. Questo ha il vantaggio di evitare la dipendenza tra Image e Project sopra, ma lo svantaggio che il codice client diventa un po 'più lungo: ad esempio, invece di

      ReadFile(image.AbsoluteFilePath) 
    

    dovrai scrivere

       ReadFile(project.GetAbsolutePath(image.FilePath))
    

Dovrai prendere una decisione tra queste due opzioni, e dalle informazioni che hai fornito nella tua domanda, è impossibile per me dire quale sia la migliore nel tuo caso - entrambe le opzioni sono a volte ragionevoli. Ma IMHO nessuna di queste due opzioni ti lascia con un "ulteriore livello" o un "modello di dominio anemico".

    
risposta data 06.05.2014 - 13:11
fonte
2

TL; DR

No.

Versione più lunga.

Quando parli di "modelli di dati" presumo che tu intenda gli oggetti di dominio . Perché "modello" non è un oggetto o una classe. È un livello di applicazione.

Ritorno al punto.

No. L'oggetto dominio non dovrebbe sapere "dove" viene archiviato o anche "se" è stato archiviato ovunque. La responsabilità dell'oggetto dominio è di rappresentare le regole aziendali, che si applicano a una parte specifica del modello di dominio (come definito in questo libro ).

Poiché la mia lingua primaria è PHP, l'esempio sarà in esso:

$user = new User;
$user->setId(42);

$mapper = new UserMapper($xmlFileHandler);
if ($mapper->fetch($user)) {
    $user->setName('Ford Prefect');
    $mapper->store($user);
}

La persistenza degli oggetti di dominio dovrebbe essere gestita dai mappatori di dati . E puoi avere più mappatori che agiscono sullo stesso oggetto di dominio.

For example: when you are loading data for "current user" domain object, it can be populated by the information that is in user's session, data from cache and info from one or more SQL tables.

    
risposta data 06.05.2014 - 10:51
fonte
1
  1. Non ho capito la parte "dipendenza dalla radice del progetto", ma sembra che tu voglia conservare i percorsi relativi negli attributi java properties / xml e introdurre una proprietà java che rappresenta il percorso alla radice del progetto e non ha un attributo xml corrispondente. Puoi inizializzare questa proprietà nel costruttore o tramite un metodo setter dopo aver deserializzato il modello.

  2. Supponendo che il percorso della radice del progetto non debba essere uguale al percorso di un modello serializzato, preferirei non archiviare il percorso di un modello serializzato nel modello stesso. Ciò impedirebbe potenzialmente di persistere il modello in un database o altro tipo di archiviazione, che suona male.

Non penso che tu abbia bisogno di un ulteriore strato di astrazione per risolvere entrambi questi problemi. Un percorso per il modello serializzato e una radice di progetto può essere fornito in una sorta di gestore di modelli o di una fabbrica.

Infine, penso che valga la pena avere dati e metodi per elaborarlo insieme, a meno che non si stia scrivendo una libreria ORM. Tuttavia, è importante mantenere solo quei metodi che sono direttamente destinati all'elaborazione dei dati e che fanno in modo che tutto il resto vada in altre classi per evitare di attribuire più responsabilità alla classe.

    
risposta data 06.05.2014 - 10:16
fonte

Leggi altre domande sui tag