我认为这里的逻辑可能有些倒退并导致了问题。如果您的方法如下所示:
updateTo1002()
{
if (version != 1001) {
updateTo1001();
}
// do the job
}
updateTo1003()
{
if (version != 1002) {
updateTo1002();
}
// do the job
}
我不知道您的确切用例,但在我看来,您通常希望更新到最新版本,但在此过程中根据需要安装增量更新。我认为这样做可以更好地捕捉到这种逻辑。
编辑:来自@user470379 的评论
在这种情况下,主要是识别您有复制/粘贴模式并对其进行编辑的事实。
在这种情况下,耦合问题几乎不是问题,但可能是。我会给你一些在你的场景中可能出现的东西,如果这样做的话,这些东西很难编码:
- 现在每次更新都需要一个额外的清理步骤,所以在 updateTo1001() 之后调用 cleanup() 等。
- 您需要能够退后一步才能测试旧版本
- 您需要在 1001 和 1002 之间插入更新
让我们按照您的模式将这两者结合起来。首先让我们添加一个“undoUpgradeXXXX()”来撤消每次升级并能够后退。现在您需要第二组并行的 if 语句来执行撤消操作。
现在,让我们添加“插入 1002.5”。突然之间,您正在重写两条可能很长的 if 语句链。
您将遇到此类问题的关键迹象是您正在以某种模式进行编码。寻找这样的模式——事实上,我的第一个迹象通常是当我从别人的肩膀上看他们的代码时,如果我能看到一个模式,甚至无法阅读这样写的任何东西:
********
***
*****
********
***
*****
...
然后我知道他们的代码会有问题。
最简单的解决方案通常是从每个“组”中删除差异并将它们放入数据中(通常是数组,不一定是外部文件),将组折叠成一个循环并遍历该数组。
在您的情况下,简单的解决方案是使用单一升级方法制作每个升级对象。创建这些对象的数组,并在需要升级时对其进行迭代。您可能还需要某种方式来对它们进行排序——您当前正在使用一个数字,这可能会起作用——或者日期可能会更好——这样你就可以轻松地“转到”给定的日期。
现在有几点不同:
- 向每次迭代(cleanup())添加新行为将是对循环的单行修改。
- 重新排序将本地化为修改您的对象 - 可能更简单。
- 将升级分成多个必须按顺序调用的步骤会很容易。
让我给你一个最后一个例子。假设在所有升级都运行之后,您需要为每个升级执行一个初始化步骤(在每种情况下都不同)。如果为每个对象添加一个初始化方法,那么对初始循环的修改是微不足道的(只需在循环中添加第二次迭代)。在您的原始设计中,您必须复制、粘贴和编辑整个 if 链。
结合 JUST undo & initialize,你有 4 个 if 链。最好在开始之前找出问题。
我也可以说消除这样的代码可能很困难(根据您的语言,这非常困难)。在 Ruby 中它实际上很容易,在 java 中可能需要一些练习,而且许多人似乎无法做到,所以他们称 Java 不灵活且困难。
花一个小时在这里和那里思考如何减少这样的代码对我的编程能力的影响比我读过的任何书或我接受过的任何培训都要多。
这也是一个挑战,让你有事可做,而不是编辑巨大的 if 链来寻找你忘记将 8898 更改为 8899 的复制/粘贴错误。老实说,它使编程变得有趣(这就是为什么我花了这么多时间在这个答案上)