0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Open/Closedな例外処理

Posted at

はじめに

Open/Closed原則を守った例外処理について考えてみました。

問題

新しい例外が増えるたびにcatch句やif文を追加して対応する

try {
	// 処理
} catch (SqlException e) {
	// ...
} catch (IOException e) {
	// ...
} catch (BusinessLogicException e) {
	// ...
} // 新しい例外が増えるたびに追加

解決策

Strategyパターンを使う

// 共通インターフェース
public interface ExceptionHandler {
    boolean supports(Throwable cause);
    void handle(Throwable cause);
}

// 具体ハンドラ
public class SqlExceptionHandler implements ExceptionHandler {
    public boolean supports(Throwable cause) {
        return cause instanceof SQLException;
    }
    public void handle(Throwable cause) {
        System.out.println("DB error handled by SqlExceptionHandler");
    }
}

// 具体ハンドラ
public class IoExceptionHandler implements ExceptionHandler {
    public boolean supports(Throwable cause) {
        return cause instanceof IOException;
    }
    public void handle(Throwable cause) {
        System.out.println("IO error handled by IoExceptionHandler");
    }
}

// 例外ハンドラDI
List<ExceptionHandler> handlers = List.of(
    new SqlExceptionHandler(),
    new IoExceptionHandler()
);

// 例外処理
try {
    someService.doTask();
} catch (MyAppException e) {
    Throwable cause = e.getCause();
    handlers.stream()
            .filter(h -> h.supports(cause))
            .findFirst()
            .ifPresentOrElse(
                h -> h.handle(cause),
                () -> System.out.println("Unhandled error: " + cause)
            );
}

このようにしておけば、新たに例外を追加する際、

// 新しい例外ハンドラ追加
public class AnotherExceptionHandler implements ExceptionHandler {
	public boolean supports(Throwable cause) {
        return cause instanceof AnotherException;
    }
    public void handle(Throwable cause) {
        System.out.println("Another error handled by AnotherExceptionHandler");
    }
}

// 例外ハンドラDI
List<ExceptionHandler> handlers = List.of(
    new SqlExceptionHandler(),
    new IoExceptionHandler(),
    new AnotherExceptionHandler() // <- 追加
);

を追加するだけで済みます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?