C # .NET Architettura software MVVM e convenzioni di denominazione

4

Attualmente sto lavorando a un software che utilizza C # .NET e WPF con il pattern MVVM.

Sebbene il software sia quasi finito, ho discusso a lungo della nostra architettura e vorrei ricevere le vostre opinioni / consigli sul lato delle convenzioni / buone pratiche.

L'architettura corrente è la seguente:

  • Progetto /
    • DataContext /
    • Modelli /
      • Engine3D /
      • ...
    • Programmi di utilità /
      • Convertitori /
      • Statica /
    • ViewModels /
      • Griglie /
      • Menu /
      • di Windows /
      • ...
    • Vista /
      • Griglie /
      • Menu /
      • di Windows /
      • ...

Cartella Modelli:

Contiene i modelli dal modello MVVM.

La cartella Modelli è organizzata per caratteristica, il che significa che ha nidificato cartelle denominate in base a una funzionalità o contesto, ad esempio Modelli / Motore3D per ogni modello relativo al 3D.

Non aggiungiamo mai la parola "Modello" come suffisso, i file sono denominati [Feature].cs Ad esempio, Project.cs , Model3D.cs , Animation.cs , ecc.

Cartella visualizzazioni:

Contiene le viste dal pattern MVVM.

La cartella Views è organizzata da WPF Control, il che significa che ha nidificato le cartelle nominate dopo un controllo WPF, ad esempio Views / Windows per ogni vista relativa a una finestra WPF, o View / Grids, ecc ...

I file sono denominati [Caratteristica] [ControlType] .xaml con:

  • [Caratteristica]: la "funzionalità" implementata / descritta dalla vista, ad esempio "CreateProject" per una funzione che crea un progetto, Display3DModel per una griglia che visualizza un Model3D (utilizzando librerie 3D), ecc ...
  • [ControlType]: il tipo di controllo "xaml" rappresentato dal file, che è una finestra, un UserControl, una griglia, ecc. Ad esempio, una finestra che visualizza le preferenze di sistema si chiamerà SystemPreferencesWindow.xaml, e una griglia che contiene l'elenco di tutti i progetti sarebbe ProjectsListGrid.xaml. Ad esempio, CreateProjectWindow.xaml, SystemPreferencesWindow.xaml, Display3DModelGrid.xaml, ProjectsListGrid.xaml

Cartella ViewModels:

Contiene i ViewModels dal pattern MVVM.

La cartella ViewModels copia la cartella Views in termini di architettura, il che significa che ha nidificato cartelle denominate in seguito a un controllo WPF, ad esempio ViewModels / Windows per ogni ViewModel correlato a una finestra WPF o ViewModels / Grids.

Un file ViewModel ha lo stesso nome del relativo file View, con il suffisso "ViewModel": i file sono denominati [Feature] [ControlType] ViewModel.cs con:

Ad esempio, in base a View = > ViewModel: CreateProjectWindow.xaml = > CreateProjectWindowViewModel.cs, OpenProjectWindow.xaml = > OpenProjectWindowViewModel.cs, etc ...

Cartella DataContext:

Contiene i file DataContext, es. file relativi a un determinato contesto nel software; queste sono classi che non sono ViewModels o Models, sono per lo più accessibili "staticamente" e corrispondono a un contesto molto specifico nel flusso di esecuzione del software, quindi non appartengono alla cartella Utilities. Queste classi sono ad esempio la classe Session che tiene i valori delle sessioni riguardanti l'utente come le sessioni delle tecnologie web.

Cartella Utilità:

Contiene un set di strumenti file / classi di vari obiettivi:

  • Classi di definizione, che forniscono meccanismi di sistema all'intero software come ObservableObject.cs, DelegateCommand.cs e RelayCommand.cs che consentono l'associazione dati MVVM, ecc ...
  • Cartella Utilities / Converters: Classi convertitori ...
  • Cartella Utilities / Statices: contiene classi di operazioni statiche che accettano un input e restituiscono un output, ad esempio FileOperations.cs, XWindow.cs (non preoccuparsi del nome, è specifico del progetto) che raggruppa System.Windows come InvokeWindow () e CloseWindow () in modo che sia più facile manipolare System.Windows nel codice, Model3DImporter.cs che importa facilmente i modelli 3D, SerializationManager.cs per le operazioni di serializzazione, ecc ...

Classi con costanti:

Alcune classi hanno bisogno di valori di costanti e poiché questi valori devono essere accessibili praticamente ovunque nel codice, non abbiamo archiviato questi valori costanti nelle classi correlate ma in una classe "sorella".

Queste classi "sorelle" sono le seguenti:

// The sister class
public static class Model3DConstants
{
    private static readonly IList<String> supportedFileExtensions = ...
}

// The original class
public class Model3D
{
}

Come ho detto all'inizio del mio messaggio, mi piacerebbe le tue idee / consigli sulle nostre convenzioni di architettura / denominazione, perché sono certo che ci manca qualcosa ma non sappiamo cosa.

Stiamo facendo l'esatto contrario di ciò che dovrebbe essere fatto in un software MVVM C # .NET corretto usando WPF, quali sono i difetti e / o cose che dovremmo modificare

Non esitare a partecipare al dibattito né a porre domande né a chiedermi se non sono chiaro riguardo la descrizione di cui sopra.

    
posta Rashimov Azarov 13.10.2015 - 15:27
fonte

2 risposte

6

Questo potrebbe non rispondere a tutto ciò che stai chiedendo, ma è troppo per un commento.

L'organizzazione della tua soluzione (utilizzo il termine organizzazione piuttosto che architettura) dovrebbe riflettere il modo in cui la utilizzi. Dovrebbe essere efficiente per il tuo uso. Ad esempio, quando vuoi apportare una modifica a un menu, uno sviluppatore deve aprire i file da Visualizza / Menu e anche da ViewModels / Menu per apportare le modifiche? (Questo è inefficiente.) Oppure hai designer che aprono sempre Views e sviluppatori che aprono sempre ViewModels?

Questo è il motivo per cui i singoli progetti di team potrebbero preferire un approccio orientato alle funzionalità (con viste correlate e modelli di vista nella stessa cartella di caratteristiche) mentre i progetti di grandi dimensioni con più team potrebbero preferire un approccio orientato ai componenti come la struttura attuale. (Questo potrebbe anche essere il motivo della legge di Conway .)

Faccio una distinzione (almeno mentalmente) tra Utilities e Infrastructure. Il codice dell'infrastruttura è una parte fondamentale del funzionamento interno dell'applicazione utilizzato dalla politica (ad esempio "Utilizziamo sempre RelayCommand su questi controlli WPF". - Infrastruttura UI). Mentre le Utilità sono generalmente utili funzioni appositamente create come forse FileOperations. Non sto suggerendo di creare un nuovo progetto Infrastruttura o rinominare nulla. Assicurati che tutti i componenti "da utilizzare" siano in un luogo facilmente accessibile, come sembra.

Il codice di utilità è a maggior rischio di essere dimenticato o ignorato. Quindi assicurati che ciò che hai messo lì è veramente utile e veloce. Se lo inquini con un sacco di piccoli aiutanti, altri sviluppatori non prenderanno il tempo necessario per familiarizzarsi e perdere l'opportunità di risparmiare tempo.

E poi ci sono Helpers che sono quelli che reputo il codice riutilizzabile che è utile in alcuni componenti specifici. Forse è il codice condiviso utilizzato per le funzionalità correlate. In genere, tengo questi vicini al codice chiamante, se possibile, e non nelle Utilità. In questo modo, il codice non è lontano quando uno sviluppatore deve lavorare su quella funzione e non aggiunge cruft alle utility più riutilizzabili.

Lo considero come segue: gli sviluppatori devono avere familiarità con Infrastructure, dovrebbe avere familiarità con le utility e potrebbe avere familiarità con un determinato Helpers della funzione (se funzionano su quella funzione).

    
risposta data 13.10.2015 - 20:49
fonte
2

La struttura di un progetto dovrebbe riflettere lo scopo e l'intenzione del progetto.

Dalla tua domanda e dalla struttura del tuo progetto, non ho idea di quale sia lo scopo e l'intenzione del tuo progetto. Ma se potessi far luce su cosa sia il progetto sono sicuro di poter dare alcuni suggerimenti per una struttura di directory.

Avendo una directory Views , una directory ViewModels e una directory Models , stai organizzando il tuo codice in base ai ruoli delle classi nel pattern MVVM. Questa struttura per modello di progettazione rende il progetto simile a un progetto di esempio su come utilizzare il modello MVVM.

Un progetto dovrebbe essere modulare.

Sfortunatamente, la struttura dei pattern in-a-design-pattern impedisce la modularità, ovvero non è possibile avere AwesomeModel , AwesomeView e AwesomeViewModel insieme in una directory Awesome (e se fosse necessario un speciale AwesomeCollection di classe troppo?).

Una struttura del progetto dovrebbe ridimensionare.

Affinché la struttura di un progetto si riduca, dovrebbe consentire al progetto di avere più classi senza apparire più disordinato. Una directory ViewModels con 20 view-model in esso è un disastro, quindi anche questa parla contro la struttura dei pattern in-a-design-pattern.

Una struttura di progetto scalabile non può essere un gruppo statico di directory.

Tuttavia, mettere da parte i dettagli generici in qualche directory Shared , Common o Utilities è di grande aiuto. Tieni i tuoi quadri fatti in casa lì. Se si finisce per avere 10 o più sottodirectory nella directory Utilities , così sia, almeno non ingombrano la directory radice. Cerca di non esagerare, perché ciò che entra nella directory Utilities è ciò che diventa il più difficile da eliminare. Mentre alcune classi di utilità sono mature per essere utilizzate in più di un'applicazione, potrebbe anche andare avanti con la sua applicazione iniziale.

    
risposta data 04.01.2016 - 23:25
fonte

Leggi altre domande sui tag