多个地方的对象条件/重复代码(DRY)

时间:2017-09-04 21:12:04

标签: oop web-applications

这是一个基本的应用程序设计问题,我多年来一直在努力和翻转。我们有一个遗留的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中,有时在应用程序代码中等等。显然这不好,但是当我们重构的东西时,我不确定我们是否以最好的方式重构事物。

2 个答案:

答案 0 :(得分:1)

好吧,你坚持使用

这个基本问题
  • 您无法在数据库上运行代码
  • 您希望能够根据此条件使用数据库的选择功能。
  • 你想要计算&#34;经典老&#34;在一个地方(最好是代码)定义

让我们列举解决方案

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>