1

次のコードが与えられた場合: モデルをロックし、トランザクションを開始する必要があります (例外がスローされる可能性があるため、ロックが解放されていることを確認する必要があります)。次に、データベース接続を取得するようなことを行います (例外がスローされる可能性があります)。 )、次に、トランザクションを元に戻す必要がある例外をスローする可能性のあるいくつかのことを行います。これは Java 6 であるため、Java 7 の優れた機能は利用できません。

SomeClass someMethod() 
throws SomeException {
  acquireWriteLock();
  try {
    startTransaction();
    try {
      DBConnection d = openDBConnection();
      try {
        doStuff(d);
        commitTransaction();
      } finally {
        d.close();
      }
    } catch (SomeException e) {
      handleSomeException(e);
      revertTransaction();
      throw e;
    } catch (Throwable t) {
      revertTransaction();  // Error: method must return a value of SomeClass
    }
  } finally {
    releaseWriteLock();
  }
}

これを書き直して、より読みやすく、冗長性を低くすることはできますか?

余談ですが、次のようなものを見たとき、あなたはどうしますか?

DBConnection d = null;
try {
  acquireWriteLock();
  startTransaction();
  d = openDBConnection();
  try {
    doStuff(d);
    commitTransaction();
  } catch (SomeException e) {
    handleSomeException(e);
    revertTransaction();
  }
} finally {
  d.close();
  releaseWriteLock();
}
4

2 に答える 2

2

Java 7 に切り替えると、大幅に簡素化できます。それ以外の場合は、おそらくそれについて行うべきことはあまりありません。

次のようなアイデアを試すことができます。

  • DB 接続 + トランザクション管理 + ロック管理を共通のベースクラスの一般的なメソッドにリファクタリングし、トランザクション タイプごとにサブクラスを作成します。

  • DB 接続 + トランザクション管理 + ロック管理を最終クラスの一般的なメソッドにリファクタリングし、トランザクション タイプのインターフェイスとそれぞれの実装クラスを使用します。

ただし、この特定のパターンが何度も繰り返されない限り、この種のリファクタリングはおそらく悪い考えです。(ローカルのイディオムを作成することになります。意味が明確になる前に、読者はイディオムを学習する必要があります。)

于 2012-06-11T00:26:49.470 に答える
1

Java 7にアップグレードしなくても、これらの一部を組み合わせることができるため、1回のトライキャッチのみが必要です。

SomeClass someMethod() throws SomeException {
   boolean committed = false;
   DBConnection d = null;
   acquireWriteLock();
   try {
      startTransaction();
      d = openDBConnection();
      doStuff(d);
      commitTransaction();
      committed = true;
   } catch (SomeException e) {
      handleSomeException(e);
      throw e;
   } finally {
     if( d != null ) d.close();
     if( !committed ) revertTransaction();
     releaseWriteLock();
   }
}

秘訣は、revertTransaction()とDBConnection.close()が何もスローしないようにすることですが、それができない場合は、releaseWriteLock()を別のfinally句に入れることができます。これをもっと改善したい場合は、StephenCが述べたリファクタリングのいくつかを行うことができます。取得/解放writeLock、開始/ロールバックトランザクション、およびオープン/クローズDBConnectionのようなことは、基本クラスまたはいくつかの抽象操作クラスで行われます。

于 2012-06-11T00:49:38.727 に答える