Lascia che un'istanza di modello scelga la classe di vista appropriata usando la categoria. E 'un buon design?

1

Supponiamo di avere una classe di modello di base astratta chiamata MoneySource. E due realizzazioni BankCard e CellularAccount. In MoneysSourceListViewController voglio visualizzare un elenco di essi, ma con ListItemView diverso per ogni sottoclasse di MoneySource.

Cosa succede se definisco una categoria su MoneySource

@interface MoneySource (ListItemView)
- (Class)listItemViewClass; 
@end

E poi sostituiscilo per ogni sottoclasse concreto di MoneySource, restituendo una classe di visualizzazione adatta.

@implementation CellularAccount (ListItemView)
- (Class)listItemViewClass
{
    return [BankCardListView class];
}
@end

@implementation BankCard (ListItemView)
- (Class)listItemViewClass
{
    return [CellularAccountListView class];
}
@end

@implementation MoneySourceListController
- (ListItemView *)listItemViewForMoneySourceAtIndex:(int)index
{
    MoneySource *moneySource = [items objectAtIndex:index];
    Class viewClass = [moneySource listItemViewClass];
    ListItemView *view = [[viewClass alloc] init];
    [view setupWithMoneySource:moneySource];
    return [view autoreleased];
}
@end

quindi posso chiedere all'oggetto del modello la sua vista, non violando i principi MVC ed evitando l'introspezione della classe o le costruzioni.

Grazie!

    
posta Denis Mikhaylov 18.09.2012 - 15:36
fonte

2 risposte

3

Leggi l'articolo su MVC di Martin Fowler .

La breve sinossi è che la tua struttura è sbagliata. Dal 4 ° paragrafo discutendo di MVC: Model objects are completely ignorant of the UI. E nella tua domanda, stai discutendo su come il Modello può restituire diversi tipi di Visualizzazioni.

Il fatto che il modello restituisca la vista è probabilmente la prima cosa che risolverei. Il Controller potrebbe / dovrebbe avere la logica che modifica ciò che la Vista mostra in base a quale Modello viene utilizzato.

Modifica

Ancora sbagliato *, mi spiace.
* sbagliato == non seguendo MVC o le sue varianti.

Il Modello non è altro (e niente di meno) del metodo per accedere ai dati.
Il Modello e la Vista non dovrebbero avere alcuna idea reciproca, e il fatto che il Modello restituisca un tipo di Vista viola questo principio.

Il problema principale qui è che la tua logica per l'istanziazione degli oggetti è nel posto sbagliato. Il Controller, non il Modello, è il luogo appropriato per questa logica. Il tuo uso delle categorie è ortogonale (cioè non correlato) a questo problema di progettazione.

Per essere un po 'più concreto, ho intenzione di semplificare l'esempio e assumere che alla MoneySourceListController venga detto che tipo di account è in gioco. Un'altra vista & Il controller può trasmettere tali informazioni o potrebbe essere derivato da un oggetto Cliente che fa parte del dominio. Del resto, potrebbe trattarsi di un'altra area del controller MSLC e di alcune parti statiche della vista.

Una volta che MSLController sa quale tipo di account è richiesto, deve fare due cose.

  1. Crea la Vista associata in base alla logica in MSLController per quanto riguarda i tipi di account.
  2. Crea la classe Modello associata, ancora una volta basata sulla logica in MSLController per quanto riguarda i tipi di account.

Il controller è il contraente del traffico che determina quale vista (s) e quali modelli vengono creati. Dovrei tornare a rileggere tutto l'articolo di Fowler per determinare se esiste un rigido rapporto 1: 1 tra Controller e View o se un controller può avere più viste. È una sfumatura di MVC contro MVP contro MVVM a cui non presta troppa attenzione. Ho chiesto una domanda correlata per MVVM.

Dal tuo punto di vista, presumo che tu stia cercando di utilizzare MVC per aumentare la tua capacità di ridimensionare e mantenere la tua app. Avere il Controller crea il Modello (s) e Visualizza (s) come ho delineato sopra vi darà quei benefici.

    
risposta data 18.09.2012 - 15:52
fonte
0

Penso che tu sia skipping the concept of viewmodel or mixing up that with model.

È corretto dire che il tuo controller dovrebbe definire quale vista debba essere visualizzata. Tuttavia, idealmente ogni vista dovrebbe avere il proprio viewmodel dedicato per scenari specifici come: quando il tuo modello è grande o view ha bisogno di qualche altra informazione - che ha tutto il set minimo di elementi di dati che la tua vista dovrebbe rendere.

Fondamentalmente, il tuo viewmodel può consistere in un singolo modello o in più modelli. Tuttavia, dovrebbe avere solo un set minimo di elementi di dati richiesti dalla tua visualizzazione.

Inoltre, puoi gestire la sicurezza dell'accesso ai ruoli anche attraverso i tuoi modelli di visualizzazione.

    
risposta data 18.09.2012 - 16:57
fonte

Leggi altre domande sui tag