Oggetto separato utilizzato nel livello aziendale, nel livello dati e nel livello presentazione

8

Sto costruendo un'applicazione responsabile della lettura dei dati dai file e della loro visualizzazione nei grafici. L'intera applicazione è responsabile della manipolazione dei dati da file, il che significa che devo utilizzare diverse parti dello stesso oggetto in quasi tutte le parti del mio progetto. I grafici hanno bisogno di dati reali, l'elenco dei file aperti ha bisogno di nomi e stati di dati, ecc. Inoltre, la mia applicazione utilizza MEF , quindi altri possono aggiungere nuove funzionalità e modificare i moduli correnti.

Il mio problema più grande è come separare i dati, in modo che ogni livello della mia applicazione abbia accesso solo a parte dei dati necessari per il loro funzionamento. Quello che intendo per dati è:

  1. Nome del file
  2. Id guida
  3. List<IColumn> dati o byte[] dati
  4. Altre variabili future

Ho deciso di utilizzare tutta la mia applicazione IDocument . Questa è la mia rappresentazione personalizzata di un file che può essere letto e visualizzato nel grafico. Ogni IDocument deve avere un Id e Name perché ogni file del computer ha un nome. Questo ha tutte le informazioni necessarie per un semplice elenco di file che sono stati importati nell'applicazione. Ma non ha i dati effettivi che voglio visualizzare, quindi uso il database NoSQL per archiviare IDocumentData che ha List<IColumn> Columns che posso inserire in un grafico. IColumn ha solo List<object> Rows che sostanzialmente riproduce una tabella.

Quindi ho separato il mio file in IDocument e IDocumentData , ora come faccio a tenere traccia di quali dati appartengono a quale documento? Ottengo IDocumentData dal modulo IReader e ottengo IWizardData dal modulo IFileImporterWizard . Stavo pensando di creare un qualche tipo di builder che assegnerebbe lo stesso Id a IDocument e IWizardData (contiene% importato% co_de e Name ) e quando vorrei accedere ai dati vorrei passare Id da% codice%. È un buon approccio?

Quindi ad esempio:

public class DocumentBuilder {

  private IDocumentFactory _documentFactory;
  private IDocumentDataRepository _documentDataRepository;

  public DocumentBuilder(IDocumentFactory documentFactory, IDocumentDataRepository documentDataRepository)
  {
     _documentFactory = documentFactory;
     _documentDataRepository = documentDataRepository;
  }

  public IDocument Build(IWizardData wizardData, IDocumentData documentData) 
  {
      var document = _documentFactory.Create();
      document.Id = wizardData.Id;
      documentData.Id = wizardData.Id;

      _documentDataRepository.Add(documentData);
      return document;
  }
}

Quindi il mio modo di pensare è il seguente: Apri procedura guidata file restituisce Id (nome, filePath) - > IDocument restituisce IWizardData ( IReader colonne) - > IDocumentData build List<IColumn> e salva i dati

Modifica

Quindi ho capito come separare i livelli aziendali e di dati creando

interface IDocument : IDocumentData, IDocumentInformation 

DocumentBuilder ha un nome e altre informazioni. IDocument ha IDocumentInformation e IDocumentData . Posso salvare Id e DataTable Data { get; set; } separatamente e avere ancora IDocumentData uguale per entrambi.

Ho deciso di cambiare IDocumentInformation e Id , perché spero che IColumn causerà meno problemi. Anche se mi chiedo ancora se List<object> Rows sia una buona scelta, perché probabilmente ridurrà le prestazioni durante il caricamento dei dati. Ho pensato che sarebbe una buona idea caricare da DataTable solo un paio di record e poi aggiungerli al grafico e farlo scorrere fino alla fine.

Quindi ora DataTable restituisce NoSQL , IFileWizard prende IDocumentInformation e restituisce IReader e quindi vengono combinati.

Il nome di queste cose richiede un po 'di tempo, perché tutte usano parti dello stesso oggetto, ma vedere IDocumentInformation che restituisce IDocumentData è un po' strano. D'altra parte per renderli facilmente intercambiabili dovrei dichiarare interfacce ancora più comuni e creare IFileWizard e avere IDocumentInformation e quindi restituire interface IFileWizardResult:IInfo e lanciarlo a interface IDocumentInformation:IInfo , ecc. Io non sapere se questo è troppo disaccoppiato o meno. Voglio che questa applicazione sia facilmente scalabile, ma creare molte interfacce non significa sempre un migliore disaccoppiamento.

    
posta FCin 10.12.2016 - 13:57
fonte

1 risposta

2

La risposta alla tua domanda dipende principalmente da due fattori:

La complessità complessiva dell'applicazione

Per essere estremi, se stai semplicemente scrivendo uno script per elaborare una serie di file, probabilmente dovresti fare un overboard con più livelli alla tua applicazione in primo luogo.

D'altra parte, se stai scrivendo un'applicazione aziendale in piena regola, la separazione dei livelli e la rappresentazione dei dati tra questi livelli garantiranno la manutenzione e la stabilità a lungo termine dell'applicazione.

Ci sono molte varianti e compromessi tra questi livelli.

Le differenze di rappresentazione necessarie per ogni livello

Da una parte, potresti avere un'applicazione che ha bisogno del formato JSON fino in fondo, dal client all'archiviazione dei dati. Se non sono previsti requisiti futuri che potrebbero cambiarlo, è possibile utilizzare JSON sul client, elaborare il JSON nel livello aziendale e scrivere il JSON in un file o in un database NoSQL.

D'altra parte, ogni livello potrebbe funzionare meglio con un formato diverso. Supponiamo che i tuoi requisiti di archiviazione siano file binari, quindi dovresti leggerlo sul livello dati e convertirlo in oggetti sensibili che possono essere elaborati dal livello aziendale e quindi quel livello aziendale elabora e riepiloga i dati a sua volta nei grafici. Proprio per la virtù di ciò avrebbe senso avere una rappresentazione diversa.

Ci sono molte varianti nel mezzo, ma nel tuo caso sembra che sia il caso, ma se hai la possibilità puoi anche rivedere la memorizzazione dei tuoi dati in un formato che è più utile per gli altri livelli.

Note sul livello di presentazione

In pratica ho imparato quasi sempre a conferire al Presentation Layer il proprio modello, separato da quello che usano il datastore e il livello aziendale. Questo è per più motivi:

  1. Il livello di presentazione non dovrebbe eseguire alcuna logica di business. Tuttavia, se il modello non corrisponde a ciò che deve essere mostrato, inizi a trovare pezzi divertenti di logica aziendale che si insinuano nel codice di presentazione.

  2. Linguaggi typesafe come C # e Java sono molto più facili da refactare rispetto ai linguaggi di template e JavaScript. Pertanto, se ti accoppi strettamente in queste lingue, perderesti gran parte del vantaggio di aver usato un linguaggio tipografico in primo luogo.

  3. Da quello che ho visto la tecnologia dell'interfaccia utente cambia ancora drasticamente, negli ultimi 7 anni sono passato da Flash / Flex a semplice JS a jQuery, a Backbone a React. In altre parole, l'interfaccia utente ha visto molte più riscritture rispetto al codice back-end. Anche in questo caso, se sei strettamente collegato, è molto più facile da gestire.

risposta data 15.12.2016 - 20:48
fonte

Leggi altre domande sui tag