撤消一系列步骤中的先前步骤的最佳方法

时间:2019-01-31 16:08:04

标签: python optimization design-patterns coding-style

我正在尝试找到一种更好的方法来执行以下功能。我有一系列步骤需要完成,如果有任何失败,则需要像上这样撤消上一步:

try:
    A = createA()
except:
    return None

try:
    B = createB(A)
except:
    deleteA(A)
    return None

try:
    C = createC(B)
except:
    deleteB(B)
    deleteA(A)
    return None

try:
    D = createD(C)
except:
    deleteC(C)
    deleteB(B)
    deleteA(A)
    return None

return D

如果可能的话,我不想重复自己。我该如何改善?有没有可以遵循的已知模式?

我考虑过的一件事是将deleteB(添加到deleteC(),并将deleteA()添加到deleteB()。那是最好的方法吗?

4 个答案:

答案 0 :(得分:0)

如果您查看一些设计模式,请检查以下内容:

Command pattern

这可能是您正在寻找的。另外,它的命令可以具有“撤消”动作。如果它包含您遇到的类似问题,也请检查以下问题。 best design pattern for undo feature

答案 1 :(得分:0)

正如评论所指出的,这就是上下文管理器协议的目的。但是,如果您不想深入了解什么是高级功能,则可以随时定义lambda匿名函数,以记住要整理的内容...

try:
    deleters = []
    A = createA()
    deleters.append( lambda: deleteA(A) )
    B = createB( A)
    deleters.append( lambda: deleteB(B) )
    C = createC( B)
    deleters.append( lambda: deleteC(C) )
    D = createD( C)
    return D
except:
    for d in reversed( deleters):
        d()
    return None

答案 2 :(得分:0)

这取决于“撤消”的确切含义。例如。如果A,B,C,D等是任意用户命令,并且可能以任意顺序存在大量用户命令,则可能需要围绕do / undo编写某种抽象形式。

如果A,B,C,D等是需要整理的资源(数据库连接,文件等),则上下文管理器可能更合适。

也许A,B,C D完全是其他种类的东西。

使用上下文管理器的简短代码:

class A:
    def __enter__(self):
        set things up
        return thing
    def __exit__(self, type, value, traceback):
        tear things down

class B, C and D are similar

def doSomethingThatNeedsToUseD():
    try:
        with A() as a:
        with B() as b:
        with C() as c:
        with D() as d:
            d.doSomething()
    except:
        print("error")

答案 3 :(得分:0)

您正在寻找的被称为 memento模式。这是GoF设计模式之一:

  

在不违反封装的情况下,捕获并外部化对象的内部状态,以便以后可以将对象恢复为该状态。

可以找到here。这是使用python来实现的一种方式。