用于跟踪复杂流程的部分结果的设计模式
我面临着一个编程问题,我不知道如何以面向对象和灵活的方式解决。我想到了一些不好的解决方案,但我正在寻找一个好的解决方案。我用Java开发,所以我更喜欢Java的想法,但任何面向对象的想法都是受欢迎的。
我一直在寻找可以帮助我的想法,设计模式或算法,但我不知道哪个术语或名称给我的问题,所以我找不到任何线索。
问题:
总结:
我需要跟踪对实体集合进行不同更改的过程的部分结果。我需要这个向用户报告,每个计算“步骤”的详细信息都在表格报告中。此外,我需要将此集合保存在数据库中。
细节:
我维护的软件有一个类似于这个实体:
public class Salary {
private Date date;
private BigDecimal amount;
}
它被分组到一个集合中,如下所示:
List<Salary> thisYearSalaries;
这组实体可以通过一组“任务”进行修改,具体取决于某些规则:
- 应用特定税(从一组不同的税种中)
- 计算金额的未来价值(更多信息)
- 折扣金额以保持低于最高限额
- 等。。。
例如:
public void processSalaries(List<Salary> theSalaries) {
applyTax(theSalaries, Taxes.TAX_TYPE_1);
(...)
getFutureValue(theSalaries, someFutureDate);
(...)
restrictToAMaximum(theSalaries, Maximum.MARRIED_MAXIMUM);
(...)
applyTax(theSalaries, TAXES.TAX_TYPE_3);
(...)
}
public void applyTax(List<Salary> theSalaries, Tax taxToApply) {
for(Salary aSalary : theSalaries) {
aSalary.setAmount(calculateAmountWithTax(aSalary.getAmount(), taxToApply);
}
}
(...)
我需要的是处理这个薪水集合,对金额进行更改,但保留金额的所有中间“状态”,以便在具有如下列的表中向用户显示它:
示例报告:(问题仅涉及前 4 行数据,不要注意其余数据)
我的想法:
为工资类上的每个“部分结果”添加一个属性
public class Salary {
(...)
private BigDecimal originalAmount;
private BigDecimal amountAfterFirstTax;
private BigDecimal amountAfterMaximumRestriction;
(...)
}
问题:
- “步骤”并不僵化,也许明天一个“步骤”发生了变化,出现了一个新的步骤,或者某些步骤的“意义”发生了变化。在这种情况下,我需要过多地重构代码。
- 有些“步骤”可以重复,那么,我怎么能告诉“方法”其中哪个属性必须“设置”计算结果呢?
将HashMap添加到薪水类中,我可以在其中放置部分结果,并将“键”传递给“step”方法,其中必须放置部分结果
public class Salary {
(...)
HashMap<String, BigDecimal> partialResults;
(...)
}
问题:
- 在某些地方,我需要将HashMap填充到JPA实体中以将其保存在我的数据库中
- 如果另一个开发人员更改了密钥的名称(无论出于何种原因),则属性的“填充”可能会被破坏
最后说明:在我的应用程序中,其他“相似”实体还有其他类似的情况,因此,如果我们能找到此:D
编辑:关于如何对数据进行建模以持久化的新疑问
所有的想法都是相似的,真的很有用。所有这些都与命令模式有关,我认为这是很好的解决方案。但现在我有一些新的疑问:
使用更高级别的抽象,我的应用程序执行如下操作:
- 用户进入工资列表
- 该应用程序通过不同的“步骤”处理此工资
- 使用最后工资金额,它计算平均值并继续进行其他计算
- 经过一些筛选和一些处理后,我向用户显示一份报告,其中包含最终工资金额以及所有中间步骤。然后我保存这些中间信息用于审计目的
因此,第二步几乎解决了。我会使用类似命令模式的东西。我现在的问题是,如何对数据进行建模以将其保存在关系数据库中。因为,除了每个操作的部分“结果”之外,还有更多我不需要向用户显示的信息,但我需要将其存储在数据库中。
我的想法是这样的:
工资桌子:
id
date // The date of the Salary
finalAmount // The final amount after all the calculations ends
部分结果桌子:
id
salaryId // The id of the salary which this element represent a partial result
amount // Partial amount
operationCode // Type of operation
operationDescription
但问题是,我的“未来价值”操作作为输出,具有以下信息:
- 未来值的日期
- 用于更新值的系数
- 部分金额
但“应税”操作有不同的信息:
- 适用税百分比
- 部分金额
那么,如何为不同的操作保存不同的“输出”信息呢?