这是一个基本的应用程序设计问题,我多年来一直在努力和翻转。我们有一个遗留的Web应用程序,如果这个小问题可能会影响您的答案,那么它实际上并没有真正的ORM。为了抽象我的问题,我们假设我们有一个类Car,以及一个名为car的数据库中的相应表。 Car有一些属性:color,weight,year,maxspeed这些属性直接对应于db表中的列。
在我们的应用程序中,我们将汽车定义为“经典旧”,如果年份是< 1960年,颜色=黑色。在我们的应用程序中的许多地方,知道汽车是否“经典老”是非常重要的(也许我们正在经营一个非常不合逻辑的保险机构,它给予“经典旧”的汽车陡峭的折扣和其他额外津贴)。
我们的应用程序遍及:
- 列出所有经典旧车
- 如果他们的汽车是经典旧车,则给当前用户一个折扣
- 列出所有具有最高速度的经典旧车>每小时100英里
- 如果当前用户的汽车是经典旧车且重量超过1000磅,则通过电子邮件发送给用户
最好的方法是什么?我们有一个遗留应用程序可以在某些地方执行此操作:
getOldClassicCars()
select * where year < 1960 and color = black
以及其他地方:
cararray = getAllCars();
for each car in cararray
if car.year < 1960 and car.color = black
oldcararray = car.add()
关键在于,我们的应用程序中非常重要的基本部分 - 汽车经典旧版 - 在许多地方被“硬编码”为year < 1960 and color = black
。有时在SQL中,有时在应用程序代码中等等。显然这不好,但是当我们重构的东西时,我不确定我们是否以最好的方式重构事物。
答案 0 :(得分:1)
好吧,你坚持使用
这个基本问题让我们列举解决方案
1:将计算放在一个sproc中,并始终使用sproc来检索汽车。
这里的问题是如果你在代码中创建一个新车,它的类状态是未定义的,所以你还没有真正解决“不在两个地方”的问题。问题
2:让DB通过程序集运行计算。例如,您可以从.net程序集中获取mssql来运行函数,您也可以在代码库中使用它来执行相同的计算。
问题,它的辛勤工作。除了它仍然在两个地方,你必须保持数据库最新,并确保正确访问表
3:在DB上保留计算值,但在代码
中执行计算问题是,如果计算更改,则DB值将不正确并需要更新。
3似乎是最好的选择,因为我们知道计算何时发生变化并能够采取一些行动来解决问题。
然而,鉴于这种计算的基本性质,最好的做法是“过时”。隐含在我们构造代码的方式中。
我们可以添加一个带有datetime属性的CarStatusReport对象,而不是简单地持久化car.IsClassic。然后,我们生成一个CarStatusReport(2017),用于评估该时间点的所有汽车,并将该数据保存在单独的表格中。
我们的业务逻辑已不复存在,&#34;这款车是否经典?&#34;但是&#34;最新的CarStatusReport说这辆车的状态是什么?&#34;
You Business Logic将驻留在单个CarStatusReportGenerator服务中,并且任何其他访问IsClassic计算的逻辑将被强制确认存储信息的短暂性质。
答案 1 :(得分:0)
这里没有最佳解决方案。但是,一个好处是将所有业务逻辑转移到一个地方。如果你不能(当你制作计算某些属性的方法或函数时,例如isOld()
),那么隐藏所有这些不一致的内容,因此实现用户(从概念上讲)永远不会注意到来自外部的DRY违规。 / p>