English 中文(简体)
在多层体系结构中,表示值的转换应该在哪里进行?
原标题:Where should conversion of presentation values be made in multi-tier architecture?

我正在构建一个多语言、多时区和n层的应用程序。所有日期都以UTC存储在数据库中,所有模型对象都填充有UTC时间。但是,从不显示UTC时间(除非用户碰巧将时区设置为UTC)。

这意味着我需要重复地将时间属性转换为正确的用户时区。重复总是坏代码或更好方法的标志,所以我试图找出实现的最佳策略。尽管这实际上是表示逻辑,但我的想法各不相同,因为模型似乎应该知道当前用户的正确值。到目前为止,我的想法是:

  1. 使用静态帮助器类,然后在每次使用模型的属性时调用它。这似乎容易出错或被遗忘,并使计算变得繁琐。

  2. 将模型对象包裹在视图模型对象中。这同样麻烦,尤其是在处理对象列表时。

  3. 为仅存在于表示层中的模型编写一个扩展方法。这看起来更干净,但并不直观。

  4. 在模型层中创建用于转换的接口。在表示层实现helper,并为模型层提供实现。然后,模型具有使用接口转换时间的属性。这似乎应该打破关注点的分离,但似乎并没有。如果你有一个默认的转换器,那么你就不必担心会出现null对象异常,然而,模型层(目前是POCO)将需要一个用于转换助手的容器,这看起来很混乱。

  5. 在模型上创建一个转换为本地时区的方法,并传入当前时区。

我对这些策略或我应该或可以用来代替这些策略的任何其他策略感兴趣。

Update What I ve currently done is to create an ITimeConvertor and an ITimeConvertorFactory within the model layer. I have then created default implementations of these which just return the original date value. Within the model layer I ve added localtime properties for each existing UTC property that was originally on the model. Within these properties I use the factory to get a convertor and convert the UTC value each way in the getter and setter. I ve had to add a static settings class with in the model layer (which I don t really like) as a place to store the current timeconvertor factory. Within the web app portion I implement the ITimeConvertorFactory and the ITimeConvertor as WebTimeConvertorFactory and WebTimeConvertor. The WebTimeConvertor knows about the session and the current user so can grab the current timezone. The WebTimeConvertorFactory creates WebTimeConvertors. When the application starts (application_onstart in global.asax) I create the factory and pass that to the model layer static settings property. This allows my model layer to be able to convert local times whilst the data layer only knows of the UTC date properties. It also means I can pass localtimes directly into the model and have it accurately converted provided that the consuming app has provided a convertor factory. As the UTC properties are unchanged, they can still be used anywhere within the app. Whilst it seemed like a lot of code, I ve found this solution quite clean once implemented as it allows other consumers of the service to implement their time conversion anyway they want (if at all) whilst also keeping the consumption of the model properties reasonably obvious.

我仍然对更好的解决方案持开放态度,并对我目前的解决方案提出批评。

最佳回答

我假设是您的模型层知道用户的时区,所以由模型层来转换时间属性。否则,您将不得不让表示层了解时区,并转换那里的每个时间值。

在模型层中转换时间值可以在表示层中使用它们,而不需要任何转换,所以我认为这是干净的。例如,您可以在开始时使用转换的时间初始化对象(POCO)。但要注意在模型中重新转换它们,忘记它们已经初始化为本地时间。此外,如果用户可以编辑时间值,则在保存之前需要将其转换回UTC时间。

Update: After some more thinking, I gather that UTC time is part of the model and localtimes are a view of this model, so the conversion duty belongs more in the presentation layer (at the expense of disagreeing with myself). With the same thought process, having localtime properties together with UTC times is duplication in essence, and the conversion is still in the model layer. To overcome this, you might have a readonly UTCToLocalTimeConverter-type property in the user POCO which is initialized with the timezone (which also eliminates the need for static methods). Then all calls to time properties in the pages would be wrapped in the converter s ConvertToLocalTime method, that is accessible via user. You could put the converter instance directly in Session too, if you d like.

我不知道这种方法是否适用于您,但它受到了您的策略的启发,我认为其他设计以这种方式运行会更顺利。此外,到本地时间的转换仍由客户决定。缺点是必须转换客户端中的所有时间值,但在我看来,这是一种必要的邪恶,以换取消除数据重复和静态方法。

问题回答

暂无回答




相关问题
SQL Server - How many users do I *really* need?

I m setting up an application, and I m looking into purchasing a license for SQL Server. My question is pretty simple (though may have a complicated answer...) How many users accounts do I really ...

Object Graph / Persistence Question

I m currently working with an online application that requires multiple screens/steps in order to complete. The application domain is modeled using an object graph. Persistence to and from a database ...

Why does stack get truncated in Exception.StackTrace?

Why does the high part of the stack (in Exception.StackTrace) gets truncated? Let s see a simple example: public void ExternalMethod() { InternalMethod(); } public void InternalMethod() { try ...

ASP.NET MVC and Service Oriented Architecture

I would like to know how do i incorporate a feature like wcf within and MVC application. My current idea of the architecture is as follows: EntityFramework -> ASP.NET MVC (Views) ...

热门标签