确定保存设置(控制器,服务和映射器)的责任

编辑: 因为我很晚才将
300
的最初赏金给予@arcain,我正在重新开放。并将额外的
150
授予@arcain。除非有人提供更好的答案。 :) /编辑 请考虑以下形式:
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]
上表的设置将保存在DB表中,其中列映射到上面的列(显然不包括最后一列)。 所有(保存和删除)操作都直接指向本地化控制器。 Localization控制器基本上调用LocalizationService上的方法,如下所示:
$localizationService->updateCollection( $_POST ) // update collection settings
// or
$localizationService->delete( $_POST ) // delete a single locale
其中的LocalizationService调用LocaleMapperDb,如下所示:
foreach( $localeCollection as $locale )
{
    $localeMapperDb->update( LocaleModel $locale );
}
// or
$localeMapperDb->delete( LocaleModel $locale );
但是,保存此设置的责任在于:
[x] let visitors browser-settings determine default language
它将保存在名为site_settings的数据库表中。我想到了几个选择: 在LocalizationController中使用SiteService / SiteSettingsService。但是,完整的表单已经在LocalizationService中生成和处理。 在LocalizationService中使用SiteMapperDb / SiteSettingsMapperDb并在updateCollection中使用它($ _POST) 在LocaleMapperDb中使用SiteMapperDb / SiteSettingsMapperDb 第一个和最后一个选项看起来像最差的选项,但我不确定。你觉得什么是最好的选择?或许你有另一种选择,我没有想到?     
已邀请:
我认为将域模型对象投影到视图模型对象上可以很好地适应这种情况。 在附加代码的情况下(请原谅我在C#中编写它;它应该是相当可移植的)域模型对象永远不会公开(它们只能直接在服务对象中访问。)服务只公开视图模型对象,像
LocalViewModel
,那些视图模型对象由控制器操纵。
LocaleConfigController
还将服务返回的数据映射到
LocaleConfigViewModel
对象,并且该对象是与视图直接交换的唯一对象。 因此,简而言之,视图具有专用控制器,视图通过
LocaleConfigViewModel
对象与控制器通信。控制器操纵
LocaleConfigViewModel
对象并调用
ILocaleConfigService
ISystemConfigService
的实现。服务对象永远不会将域模型暴露给控制器,它们负责将视图模型对象映射到域模型对象(通过任何需要的持久性机制)。 请注意,语言环境服务是一个配置服务,它没有任何实现来查找正确的本地化字符串。我会把它放到另一个服务中,因为它可以在你不想暴露任何允许更改本地化配置的方法的地方使用。 例如,在应用程序的管理方面,您需要本地化配置服务和本地化字符串呈现服务(因为管理站点也可以进行本地化。)对于面向前端的客户,您可能只需要本地化字符串呈现服务,因为系统配置修改应该是不需要的并且超出该站点的范围。 因此,最后回答您的问题:控制器包含对区域设置和系统配置服务的引用,并且控制器专用于视图 - 它具有明确定义的合同,其中仅交换
LocaleConfigViewModel
s。 至于保存系统范围设置的责任在哪里,控制器负责从
LocaleConfigViewModel
解压缩系统设置并将它们推送到适当的服务(在这种情况下是
ISystemConfigService
实例),在那里它们将被保留。
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; }
  // ...
}
    

要回复问题请先登录注册