3

このコードを見てください:

IDfSessionManager manager = DfcSessionManager.getSessionManager();
    try {
        IDfSession session = manager.getSession(DfsUtils.getCurrentRepository());
        ...
        return somewhat; //May be without return statement
    } finally {
        if (session != null) {
            manager.release(session);
        }
    }

このような構造が何度も繰り返され、さまざまなコードが取り囲まれます。これは、return ステートメントの有無にかかわらずメソッドにすることができます。この try-finally ブロックを再利用できるようにしたいと考えています。

私はそのような認識から考え出しました。

public abstract class ISafeExecute<T> {

private IDfSession session = null;

protected abstract T execute() throws DfException;

public T executeSafely() throws Exception {
    IDfSessionManager manager = DfcSessionManager.getSessionManager();
    try {
        session = manager.getSession(DfsUtils.getCurrentRepository());
        return execute();
    } finally {
        if (session != null) {
            manager.release(session);
        }
    }
}

public IDfSession getSession() {
    return session;
}

}

セッションフィールドは public getter で作成しました。

そして、このクラスを次のように使用できます(返されたオブジェクトを使用):

return new ISafeExecute<String>() {
        @Override
        public String execute() throws DfException {
            return getSession().getLoginTicket();
        }
    }.executeSafely();

または戻りオブジェクトなし:

    new ISafeExecute() {
        @Override
        public Object execute() {
            someMethod();
            return null;
        }
    }.executeSafely();
4

2 に答える 2

5

これを行うメカニズムを構築するために使用できますRunnable<T>(関数を別の関数に注入するようなものです):

public void runInSession(Runnable<IDfSession> runnable) {

    IDfSession session = null;
    try {

        session = manager.getSession(DfsUtils.getCurrentRepository());
        runnable.run(session);        

    } finally {
        if (session != null) {
            manager.release(session);
        }
    }

}

より多くのジェネリックを使用して、値を返すこともできます。ここにはJavaコンパイラがありませんが、構文については少しわかりません。

あなたの編集を見たので、編集してください:

カスタムISafeExecuteインターフェイスを使用することは、 を使用するよりも優れている場合がありますRunnable<T>が、考え方は変わりません。戻り値 (またはエラー) をエレガントに配置できるように構築できます。

interface ISafeExecute<T> {

  void execute(IDfSession session);

  T getResult();

  Exception getException();

}

mySafeExecute.execute(session);

if(mySafeExecute.getException() == null) {
    return mySafeExecute.getResult();
} else {
    // runtime exception or declaration in method
    // signature
    throw new RuntimeException(mySafeExecute.getException());
}
于 2012-08-15T12:59:20.513 に答える
0

私は次のような決断に至りました。

 public abstract class SafeExecute<T> {

    protected IDfSession session = null;

    public T executeSafely() throws Exception {
        IDfSessionManager manager = DfcSessionManager.getSessionManager();
        try {
            session = manager.getSession(DfsUtils.getCurrentRepository());
            return logic();
        } finally {
            if (session != null) {
                manager.release(session);
            }
        }
    }

    protected abstract T logic() throws Exception;

}

次に、このクラスを拡張することによって:

public class Service extends SafeExecute<String> {

    public String getLoginTicket() throws Exception {
        return executeSafely();
    }

    @Override
    protected String logic() throws Exception {
        //TODO implement
    }
}
于 2012-08-16T08:17:19.063 に答える