Formatting Trim方法通常应该在数据访问层还是在域层?

Formatting Trim方法通常应该在数据访问层还是在域层?,formatting,domain-driven-design,n-tier-architecture,business-objects,trim,Formatting,Domain Driven Design,N Tier Architecture,Business Objects,Trim,我正在处理一个数据库,该数据库包含不一致的数据,例如前导空格和尾随空格 总的来说,我看到很多开发人员通过修剪几乎所有来自数据库的字符串(用户可能在某个时候输入的字符串)来练习防御性编码。在我的观点中,最好在数据持久化之前进行这种格式化,以便只执行一次,然后数据就可以处于一致和可靠的状态。不幸的是,情况并非如此,这导致我使用Trim方法找到了下一个最佳解决方案 如果我将所有数据作为数据访问层的一部分进行修剪,那么我就不必担心域层业务对象中的防御性修剪。如果我将修剪责任放在我的业务对象中,例如使用我

我正在处理一个数据库,该数据库包含不一致的数据,例如前导空格和尾随空格

总的来说,我看到很多开发人员通过修剪几乎所有来自数据库的字符串(用户可能在某个时候输入的字符串)来练习防御性编码。在我的观点中,最好在数据持久化之前进行这种格式化,以便只执行一次,然后数据就可以处于一致和可靠的状态。不幸的是,情况并非如此,这导致我使用Trim方法找到了下一个最佳解决方案

如果我将所有数据作为数据访问层的一部分进行修剪,那么我就不必担心域层业务对象中的防御性修剪。如果我将修剪责任放在我的业务对象中,例如使用我的C#properties的set访问器,我应该会得到相同的净结果,但是修剪将操作分配给我的业务对象属性的所有值,而不仅仅是来自不一致数据库的值

我想这是一个有点庸俗的问题,可能会决定答案,我可以问“域层应该负责数据的防御性/强制性格式化吗?”让业务对象上的PhoneNumber属性的set访问器接受未格式化或格式化的字符串,然后尝试根据需要对其进行格式化,这有意义吗?还是应该将此责任推给表示层和数据访问层,让域层对其将接受的数据类型更加严格?我认为这可能是更根本的问题

更新:以下是一些我认为应该分享的关于该主题的链接

最好在数据持久化之前进行这种格式化

当然

域以后是否应负责数据的防御性/强制性格式化

使用当前存储的数据,您将找不到合适的位置来引入修剪。这是因为存储的一致性被破坏了

你可以试试自愈的方法。在显示在对话中之前,读取数据并将其修剪到某个位置。一旦用户保存了这个对话框,数据库中的数据就会被“修复”

至于新的输入,我倾向于认为修剪数据是一种既不属于域层也不属于数据层的清理操作。在您真正开始使用该数据之前,用户输入应该在靠近UI层的某个地方被“清理”掉。

我建议“清理”应用层中的数据。您希望在这里这样做的原因(是的,像Dev Art建议的那样在堆栈的更高位置)是因为您的域模型应该尽可能地“建模”域。如果在某个时间点所有数据都是“干净”的呢?那么,您可能需要删除执行“清理”的helper方法。更容易从应用程序堆栈中较高的位置删除它

使用一个经典的扩展方法,使用反射(不要告诉我反射很慢)或其他东西来挖掘域对象图的所有“字符串”属性(例如)。到固定偏移量-注意它将如何“偏移”集合或其他自定义类型中的所有
DateTime
值。在你的情况下,补偿将是你的修剪。这当然比在整个节目中添加
.Trim()
s更容易,而且可以相当容易地解耦


请记住,坏数据对您的域来说是一个贯穿各领域的问题,因此不应该直接与之关联(想想)。

数据必须在持久化之前清除。既然它被持久化了,那么您就有了不干净的数据,可能需要在数据库中清理这些数据。考虑寻找客户的名字。如果我存储的是“John”,“Doe”,我可以找到“John”,“Doe”吗


清理尽可能靠近UI的数据可以使代码简单得多。防御代码可以从清理代码更改为断言。(即断言字符串=修剪(字符串))。要达到这一点,您需要清理数据库和UI代码。

我的想法也是一样的。我想我意识到的是,通过将格式化代码放入域模型中,我基本上可以处理两个格式化问题,一个是来自UI的数据,另一个是来自数据库的数据。这本质上类似于您描述的自愈方法,但不需要在UI中完成。但通常情况下,仅仅因为某个原因有意义并不意味着它是正确的选择。我还应该提到,我正在使用LINQ to SQL,因此在我的情况下,在运行Trim()的数据访问层中放置一些代码是非常简单的任何有疑问的值,最好的是,这将允许在数据被持久化和从数据库中取出时格式化数据。显然,从长远来看,两者兼而有之是矫枉过正的,但就目前而言,由于我不得不忍受糟糕的数据,我认为这是一个合理的解决方案。或者,在我的业务对象中放置代码也同样容易。以下哪项更正确?还有其他合适的替代方案吗?就像我在回答中试图解释的那样:修剪不是应用程序域的问题,而是应用程序本身(为域提供服务的应用程序)。因此,不要修剪域/业务对象。修剪应用程序/服务层或UI层(如果确实需要)。但同样,UI是用于表示的,虽然这种责任似乎是适当的,但实际上并非如此。如果你没有应用程序或服务层,那么UI应该是我认为的地方。问题是我们的数据库是两个独立应用程序之间的公共链接,只有一个我可以控制。因此,即使我专注于纠正问题,坏数据仍然会存在