【发布时间】:2012-05-12 04:43:40
【问题描述】:
我正在构建一个多语言、多时区和 n 层的应用程序。所有日期都以 UTC 格式存储在数据库中,所有模型对象都使用 UTC 时间填充。但是 UTC 时间永远不会显示(除非用户碰巧将他们的时区设置为 UTC)。
这意味着我需要反复将时间属性转换为正确的用户时区。重复总是错误代码或更好方法的标志,因此我试图制定最佳实施策略。尽管这实际上是表示逻辑,但我的想法已经发生了变化,因为似乎模型应该知道当前用户的正确值。到目前为止,我的想法是:
使用静态帮助器类,然后在每次使用模型的属性时调用它。这似乎容易出错或被遗忘,而且计算起来很麻烦。
将模型对象包装在视图模型对象中。这同样很麻烦,尤其是在处理对象列表时。
为仅存在于表示层的模型编写扩展方法。这看起来更简洁但不直观。
在模型层中为转换创建一个接口。在表示层实现助手并给模型层实现。然后模型具有使用接口转换时间的属性。这似乎应该打破关注点分离,但似乎没有。如果您有一个默认转换器,那么您不必担心会出现空对象异常,但是模型层(目前是 POCO)将需要一个用于转换帮助器的容器,这看起来很混乱。
在模型上创建转换为本地时区的方法并传入当前时区。
我对这些策略或我应该或可以用来代替这些策略的任何其他策略的意见感兴趣。
更新 我目前所做的是在模型层中创建一个 ITimeConvertor 和一个 ITimeConvertorFactory 。然后我创建了这些的默认实现,它们只返回原始日期值。在模型层中,我为模型中最初存在的每个现有 UTC 属性添加了本地时间属性。在这些属性中,我使用工厂获取转换器并在 getter 和 setter 中以每种方式转换 UTC 值。我不得不在模型层(我不太喜欢)中添加一个静态设置类作为存储当前时间转换器工厂的地方。在 Web 应用程序部分中,我将 ITimeConvertorFactory 和 ITimeConvertor 实现为 WebTimeConvertorFactory 和 WebTimeConvertor。 WebTimeConvertor 知道会话和当前用户,因此可以获取当前时区。 WebTimeConvertorFactory 创建 WebTimeConvertor。当应用程序启动时(global.asax 中的 application_onstart),我创建工厂并将其传递给模型层静态设置属性。这使我的模型层能够转换本地时间,而数据层只知道 UTC 日期属性。这也意味着我可以将本地时间直接传递到模型中,并在消费应用程序提供转换器工厂的情况下对其进行准确转换。由于 UTC 属性没有改变,它们仍然可以在应用程序内的任何地方使用。 虽然它看起来像很多代码,但我发现这个解决方案在实施后非常干净,因为它允许服务的其他消费者以他们想要的任何方式(如果有的话)实施他们的时间转换,同时还可以合理地保持模型属性的消耗很明显。
我仍然愿意接受更好的解决方案和对我当前解决方案的批评。
【问题讨论】:
标签: design-patterns architecture timezone