+------------------+
| 表現層 | Swing/JavaFX/UI:顯示「網絡異常,請稍後重試」彈窗/狀態欄
+------------------+
↓ 調用
+------------------+
| 業務邏輯層 | 數據獲取服務:捕獲 IOException,拋出自定義 BusinessException("NETWORK_ERROR")
+------------------+
↓ 調用
+------------------+
| 數據訪問層 | HTTP Client:OkHttp/HttpClient 發起請求,超時/斷網拋 IOException
+------------------+
public String fetchStockData(String code) throws IOException {
Request request = new Request.Builder()
.url("https://api.example.com/stock/" + code)
.timeout(5, TimeUnit.SECONDS)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("HTTP " + response.code());
return response.body().string();
}
}
public StockQuote getQuote(String code) throws BusinessException {
try {
String json = dao.fetchStockData(code);
return parseJson(json);
} catch (IOException e) {
log.warn("獲取股票數據失敗: {}", code, e);
throw new BusinessException("NETWORK_ERROR", "網絡連接異常,請檢查網絡後重試", e);
}
}
try {
StockQuote quote = service.getQuote("000001");
ui.updateQuote(quote);
} catch (BusinessException e) {
if ("NETWORK_ERROR".equals(e.getCode())) {
ui.showNetworkErrorDialog(); // 彈窗/Toast/狀態欄紅點
} else {
ui.showError(e.getMessage());
}
}
@Retryable 或手寫指數退避重試 3 次。ConnectivityManager、JavaFX NetworkDetector 主動感知斷網/恢復,自動重試。異常在發生層捕獲、轉換為業務異常、向上拋出,表現層統一根據異常碼決定用戶提示方式。業務邏輯層不直接操作 UI,保持純淨可測試。