何かの値を一時的に変更したいけど戻すの忘れそう!って時に、こんなコードを書いて使っている。何かもっと良いアイデアをお持ちの方もいるかもしれない。あったら教えて欲しい。
Sample.java
public static class SelfRestorable<T> implements AutoCloseable {
public static <T> SelfRestorable<T> restoreTo(T value) {return new SelfRestorable<T>(value);}
private final T originalValue;
private Consumer<T> setter = null;
public SelfRestorable(T value) {originalValue = value;}
public SelfRestorable<T> by(Consumer<T> setter_) {setter = setter_; return this;}
@Override public void close() throws Exception {if (setter != null) setter.accept(originalValue);}
}
// 例えばユニットテスト中に一時的に static 変数で定義されている DB の接続先を変更する、など。
@Test public void test() throws Exception {
try (
SelfRestorable<Connection> _s = restoreTo(ConnectionProvider.defaultConnection).by(c -> ConnectionProvider.defaultConnection = c);
) {
// 接続先を必要なところに変える。戻すのは AutoCloseable な SelfRestorable というオブジェクトが行なう
ConnectionProvider.defaultConnection = temporalConnection;
// 以下テストコード
}
}
ちなみに Java7 と Java8 の AutoCloseable の規約は若干異なっており、以下のように Java7 では解放すべきリソースである、と既定されているが Java8 の元では必ずしもリソースである必要がない。すなわち、Java7の元では以上のコードは厳密には規約違反と言えるのかもしれない。
Java7 では以上のように記述されていたものが Java8 では以下のようになっている。