Come creare modelli di viste - Costruttore, Metodo di fabbrica, ...?

4

Sto cercando di guidare un'accusa per aver ridimensionato i nostri controller piuttosto gonfiati. Al momento disponiamo di un BaseModel da cui ereditano tutti gli altri modelli. Il BaseModel contiene elementi comuni a tutte le pagine, come il titolo della pagina, i file css necessari, l'utente corrente.

Ogni costruttore ha un metodo privato per costruire un particolare ViewModel (essenzialmente un metodo factory)

BaseModel.cs

Class BaseModel {
    public string title {get; set;}
    public List<String> cssFiles {get;set;}
    // More Properties
}

HomeModel.cs

Class HomeModel : BaseModel {
    public List<News> LatestNews {get;set;}
}

ExtendedHomeModel.cs

Class ExtendedHomeModel : HomeModel {
    public List<RSSItem> Twitter {get;set;}
}

HomeController.cs

public ActionResult Index(int userid) {
    return View(MakeExtendedHomeModel(userid));
}

private ExtendedHomeModel MakeExtendedHomeModel(int userid) {
    var model = new ExtendedHomeModel();

    InitialiseBaseModel(model, userid);
    InitialiseExtendedBaseModel(model);

    model.Twitter = DomainModel.Twitter.GetLatestItems();
}

private HomeModel MakeHomeModel() {
    var model = new HomeModel();
    InitialiseBaseModel(model);
    InitialiseHomeModel(model);
}

private void InitialiseHomeModel(HomeModel model) {
    model.LatestItems = DomainModel.GetLatestItems;
}

private void InitialiseBaseModel(BaseModel model, int userid) {
    model.PageTitle = "Home"
    model.UserId = userid
}

Quindi, la mia domanda è: qual è il modo migliore di inizializzare questo tipo di modelli base? Per quanto posso dire che cosa fa essenzialmente il costruttore è il metodo factory, e per lo meno dovrebbe essere spostato fuori dal costruttore.

Tuttavia, sono convinto che ci sia un modo più elegante per farlo. Il problema principale che vedo è che il codice dipende interamente dal fatto che chiami i metodi di inizializzazione nell'ordine corretto. Un'idea che ho avuto è di usare i costruttori, passando i parametri necessari lungo la catena, se necessario. Ci sono delle insidie a questo approccio che non ho visto? (Tenendo presente che ho iniziato ad usare mvc solo sei mesi fa). Ci sono dei modi migliori?

Grazie per la lettura

    
posta berkeleybross 03.01.2013 - 05:00
fonte

1 risposta

4

Lo schema su cui ho optato per la creazione dei miei modelli di visualizzazione è SomeViewModel creato da un metodo statico (o metodo di istanza, se appropriato) su SomeViewModelFactory. Non eredito dai modelli di base per i membri duplicati. Io uso interfacce e metodi di setter esterni che operano su quelle interfacce per impostare le proprietà. Ciò astrae la creazione del modello di vista in una singola chiamata di funzione per un modello a vista singola e una funzione di setter chiamata internamente per ogni interfaccia implementata dal modello di vista. Come puoi vedere, preferisco la composizione sull'ereditarietà in questo caso. Per me, è meno complesso e più riutilizzabile dell'eredità.

Potresti essere interessato a Automapper se stai facendo una mappatura tra il tuo modello di dominio per il tuo database e i tuoi modelli di vista. Spero che questo aiuti a stimolare qualsiasi idea che possa essere dormiente nella tua mente.

Modifica: ho dimenticato di menzionare che è possibile definire i metodi di estensione su quelle interfacce per prendere input e fare da sé l'impostazione sull'oggetto. Questa tecnica è chiamata "mixin". In questo modo non hai bisogno di creare classi per i tuoi metodi setter, ti appaiono come metodi di istanza sull'oggetto viewmodel.

Modifica 2: per rispondere al tuo primo commento, dipende da te e dalle tue preferenze. Personalmente, mi piace rimanere coerente e vorrei solo copiare / incollare il modello in una nuova classe e aggiungere la proprietà. Quindi usa il setter per la vecchia classe e imposta semplicemente quella proprietà normalmente. Ricorda che non ci dovrebbe essere logica nei tuoi modelli di vista; dovrebbero solo sapere che stanno conservando i dati, non come vengono creati quei dati.

Automapper è ancora attivamente sviluppato per quanto posso dire. È davvero più una libreria di utilità piuttosto che una struttura completa. Sembra essere piuttosto maturo per me, l'ho usato al lavoro con molto successo. Potrebbe essere necessario scrivere il codice che va da ViewModel a DomainModel per cose come l'aggiornamento dei dati in un database, ma almeno non dovrai fare DomainModel > ViewModel part. Automapper si occupa molto bene di questo.

Modifica 3: la tua preoccupazione per rimanere ASCIUTTO è valida; tuttavia, interpreto questo principio come non ripetere la tua logica (non la struttura dei dati). Il tuo modello di visualizzazione è una struttura di supporto per i tuoi dati che ti offre il beneficio della digitazione statica nella tua vista. Ogni modello di vista è specifico per una singola vista. L'utilizzo dell'ereditarietà per il riutilizzo delle proprietà lega inutilmente il modello di vista di 2 viste separate che sembrano essere simili. Se si utilizza l'ereditarietà, la modifica del modello di vista di base ha un effetto a catena su tutte le visualizzazioni con i modelli di vista che ne ereditano. Forse è quello che vuoi, ma puoi ottenere lo stesso vantaggio definendo un'interfaccia per tutti i modelli di visualizzazione che ne hanno bisogno. Se c'è un cambiamento, questo ti permette di decidere per ciascun modello se dovrebbe ancora implementare quell'interfaccia o se è necessaria una nuova interfaccia.

    
risposta data 03.01.2013 - 06:46
fonte

Leggi altre domande sui tag