2

我正在编写一个将资源列表作为输入的代码,并尝试锁定其中的每一个。如果有人失败,它会努力释放所有资源的锁。这意味着要么“所有”资源有锁,要么根本没有。我有两种方法,我没有看到任何显着的好处。在这种情况下,标准的编码实践是什么?是否有任何设计模式的名称?

OPTION 1:

// one function taking on 2 responsibilities. appears bad to have unlock code in locking function
public boolean getLock(List<Resource> resources) {
     for (Resource r : resources) {
          if (! Lock.getLock(r)) {
              releaseLocks(resources);   
              return false;
          }
     }
     return true;
}

OPTION 2:

    public boolean getLock(List<Resource> resources) {
         for (Resource r : resources) {
              if (! Lock.getLock(r)) { 
                  return false;
              }
         }
         return true;
    }

    public boolean stateChecker(List<Resource> resources) {
           if (!getLock(resouces)) {
               releaseLocks(resources);
               return false;
           } 
           return true;
    }
4

3 回答 3

1

您的第二个选项不会解锁(部分)获得的“锁”,即使它未能获得所有锁。(或者 getLocks() 应该是私有的?)然后这些资源将如何解锁以释放它们?获得所有锁或保证没有获得锁的方法听起来要好得多。(如果不能保证,那么这些将如何被释放,顺便说一句?)

如果可能的话,我会尝试做这样的事情:

interface ResourceUpdater {
    public void useResources(List<Resource> rs);
}

public static boolean withResources(List<Resource> rs, ResourceUpdater updater) {
    // lock/unlock would ideally be private (or perhaps package private).
    // I'm also assuming the unlockAll() will be a no-op on the non-locked resources
    try {
        if(!lockAll(rs))
            return false;
        updater.useResources(rs);
        return true;
    }
    finally {
        unlockAll(rs);
    }
}

这里的重点是使锁定和解锁成为您如何使用资源的实现细节:想要使用它们的客户端代码不需要了解锁定机制,只要它始终使用这种方式来更新资源。

究竟在哪里尝试...最终取决于您的锁定/解锁和操作的失败特征。(例如,您可能希望尝试在单独的 try...catch 中解锁每个资源,以确保至少尝试解锁每个资源。此外,useResources() 可能需要返回值,然后返回来自 withResources()。

于 2013-11-14T19:26:12.330 回答
0

函数应始终指向单个responsibility. 虽然选项 1 看起来更优雅,也减少了代码行数,但从可维护性标准的角度来看,当你重新访问时,某人或你自己很难解释该函数的目的。

可能是一个奇怪的例子,举一个真实的例子,我们在生活中都扮演着父亲、兄弟、丈夫等多个角色。但我们boxes对每个角色和他们的责任都有不同的看法。

没有specific advantage,但将您的功能的责任限制在定义的角色中总是好的。

于 2013-11-14T19:16:46.353 回答
0

相反,我认为后一种选择没有任何优势。名称是“stateChecker”,但它显然不仅仅是检查状态,它还试图锁定资源。

我会使用选项 1 并命名方法tryToLock(List<Resource> resources)或类似名称。

于 2013-11-14T19:12:22.073 回答