Domanda

Modifica

Perché ero in ritardo con l'assegnazione del premio iniziale di 300 per @arcain sto riapertura. E l'assegnazione del 150 aggiuntivo per @arcain. A meno che, naturalmente, che qualcuno fornisce anche una risposta migliore. :)

/ Modifica

Si consideri il seguente modulo:

language | region | active | default |
-----------------------------------------------
en       | GB     | [x]    | (*)     | [X delete]
nl       | NL     | [x]    | ( )     | [X delete]
nl       | BE     | [x]    | ( )     | [X delete]

[x] let visitors browser-settings determine the default language

[save]

Le impostazioni della tabella di cui sopra verranno salvati in una tabella DB quali colonne mappano le colonne di cui sopra (escludendo l'ultima colonna, ovviamente).

Tutti (Salva e delete) azioni dirette a un controller di localizzazione. Il controller Localizzazione chiama fondamentalmente metodi su un LocalizationService, in questo modo:

$localizationService->updateCollection( $_POST ) // update collection settings
// or
$localizationService->delete( $_POST ) // delete a single locale

Il LocalizationService in esso di volta chiama un LocaleMapperDb, qualcosa di simile:

foreach( $localeCollection as $locale )
{
    $localeMapperDb->update( LocaleModel $locale );
}
// or
$localeMapperDb->delete( LocaleModel $locale );

Dove però, è la responsabilità di salvare questa impostazione:

[x] let visitors browser-settings determine default language

Sarà salvato in una tabella DB denominata site_settings. Ho pensato a un paio di opzioni:

  • Usa un SiteService / SiteSettingsService nel LocalizationController. Ma poi, la forma completa viene generato ed eseguito nel già LocalizationService.
  • Usa un SiteMapperDb / SiteSettingsMapperDb nel LocalizationService e utilizzarlo in updateCollection ($ _POST)
  • Usa un SiteMapperDb / SiteSettingsMapperDb nel LocaleMapperDb

Il primo e l'ultimo opzioni sembrano le opzioni peggiori, ma io sono sicuro. Che cosa si sente è l'opzione migliore? O forse avete un'opzione alternativa, non ho pensato?

È stato utile?

Soluzione

Credo che la proiezione modello di dominio oggetti su oggetti vista del modello funziona bene in questa situazione.

Nel caso del codice allegato (per favore mi perdoni per aver scritto in C #, che dovrebbe essere abbastanza portatile) gli oggetti del modello di dominio non sono mai esposti (non solo si accede direttamente all'interno degli oggetti di servizio.) I servizi espongono solo vista oggetti del modello, come LocalViewModel, e quegli oggetti vista del modello sono manipolati dai controllori.

Il LocaleConfigController associa inoltre i dati restituiti dai servizi in un oggetto LocaleConfigViewModel, e questo oggetto è l'unico oggetto che viene scambiato direttamente con la vista.

Così, in sintesi, la vista ha un controller dedicato, e la vista comunica con il controllore tramite l'oggetto LocaleConfigViewModel. Il controllore manipola l'oggetto LocaleConfigViewModel e chiamate in implementazioni di ILocaleConfigService e ISystemConfigService. Il servizio di oggetti mai esporre il modello di dominio al controller, e sono responsabile degli oggetti vista mappatura modello a oggetti del modello di dominio (attraverso qualsiasi meccanismo di persistenza è auspicabile.)

Si noti che il servizio locale è un Configurazione di servizio, non avrebbe alcuna implementazione per cercare quali sarebbero state le stringhe localizzate corretti. Vorrei mettere che in un altro servizio, perché potrebbe essere utilizzato in luoghi dove non vorrebbe esporre tutti i metodi che consentirebbero l'alterazione della configurazione localizzazione.

Ad esempio, nel lato gestione della domanda, che si vorrebbe sia il servizio di localizzazione di configurazione e il servizio di localizzazione di rendering stringa (dal momento che il sito di gestione potrebbe essere localizzato pure.) Per un cliente di fronte a front-end, si farebbe invece probabilmente vogliono solo il servizio di rendering stringa di localizzazione, in quanto le modifiche alla configurazione del sistema dovrebbero essere indesiderati e fuori portata per quel sito.

Quindi, per rispondere alla tua domanda, infine:. Il controller contiene riferimenti a entrambi i servizi di configurazione delle impostazioni internazionali e di sistema, e il controller è dedicata alla vista - ha un contratto ben definito in cui vengono scambiati solo LocaleConfigViewModels

Per quanto riguarda dove si trova la responsabilità di salvare le impostazioni a livello di sistema, il controller è responsabile per l'estrazione, le impostazioni di sistema dal LocaleConfigViewModel e spingendoli nei servizi appropriati (in questo caso l'istanza ISystemConfigService) dove saranno persistenti.

class LocaleViewModel
{
  public int Id;
  public string Language;
  public string Region;
  public bool Enabled;
  public bool Deleted;
}

class LocaleConfigViewModel
{
  public bool UseVisitorBrowserLocale;
  public LocaleViewModel DefaultLocale;
  public List<LocaleViewModel> Locales; 
}

class LocaleConfigController : ILocaleConfigController
{
  ILocaleConfigService localeConfig;
  ISystemConfigService systemConfig;

  public void Save(LocaleConfigViewModel model)
  {
    foreach (var locale in model.Locales)
    {
      if (locale.Deleted)
      {
        localeConfig.DeleteLocale(locale);
        continue;
      }
      localeConfig.UpdateLocale(locale);
    }
    systemConfig.DefaultLocaleId = model.DefaultLocale.Id;
    systemConfig.UseVisitorBrowserLocale = model.UseVisitorBrowserLocale;
  }

  public LocaleConfigViewModel GetCurrentView()
  {
    var model = new LocaleConfigViewModel();
    model.Locales = localeConfig.Locales;
    model.DefaultLocale = model.Locales.FirstOrDefault(l => l.Id == systemConfig.DefaultLocaleId);
    model.UseVisitorBrowserLocale = systemConfig.UseVisitorBrowserLocale;
    return model;
  }

  // ...
}

interface ILocaleConfigController
{
  void Save(LocaleConfigViewModel model);
  LocaleConfigViewModel GetCurrentView();
  // ... 
}

interface ILocaleConfigService // services will be stateless and threadsafe
{
  void DeleteLocale(LocaleViewModel locale);
  void UpdateLocale(LocaleViewModel locale);
  List<LocaleViewModel> Locales { get; }
  // ...
}

interface ISystemConfigService // services will be stateless and threadsafe
{
  int DefaultLocaleId { get; set; }
  bool UseVisitorBrowserLocale { get; set; }
  // ...
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top