feat(cache): add SimpleCacheManager and cache formatted rates/amounts in exchange and currency services

This commit is contained in:
JiWoong Sul
2025-09-08 14:31:44 +09:00
parent eb6691ce6a
commit b034f60510
3 changed files with 164 additions and 9 deletions

View File

@@ -2,6 +2,7 @@ import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:intl/intl.dart';
import '../utils/logger.dart';
import 'cache_manager.dart';
/// 환율 정보 서비스 클래스
class ExchangeRateService {
@@ -16,6 +17,14 @@ class ExchangeRateService {
// 내부 생성자
ExchangeRateService._internal();
// 포맷된 환율 문자열 캐시 (언어별)
static final SimpleCacheManager<String> _fmtCache =
SimpleCacheManager<String>(
maxEntries: 64,
maxBytes: 64 * 1024,
ttl: const Duration(minutes: 30),
);
// 캐싱된 환율 정보
double? _usdToKrwRate;
double? _usdToJpyRate;
@@ -62,6 +71,8 @@ class ExchangeRateService {
_usdToJpyRate = (data['rates']['JPY'] as num?)?.toDouble();
_usdToCnyRate = (data['rates']['CNY'] as num?)?.toDouble();
_lastUpdated = DateTime.now();
// 환율 갱신 시 포맷 캐시 무효화
_fmtCache.clear();
Log.d(
'환율 갱신 완료: USD→KRW=$_usdToKrwRate, JPY=$_usdToJpyRate, CNY=$_usdToCnyRate');
return;
@@ -177,32 +188,45 @@ class ExchangeRateService {
/// 언어별 환율 정보를 포맷팅하여 반환합니다.
Future<String> getFormattedExchangeRateInfoForLocale(String locale) async {
await _fetchAllRatesIfNeeded();
// 캐시 키 (locale 기준)
final key = 'fx:fmt:$locale';
final cached = _fmtCache.get(key);
if (cached != null) return cached;
String result = '';
switch (locale) {
case 'ko':
final rate = _usdToKrwRate ?? DEFAULT_USD_TO_KRW_RATE;
return NumberFormat.currency(
result = NumberFormat.currency(
locale: 'ko_KR',
symbol: '',
decimalDigits: 0,
).format(rate);
break;
case 'ja':
final rate = _usdToJpyRate ?? DEFAULT_USD_TO_JPY_RATE;
return NumberFormat.currency(
result = NumberFormat.currency(
locale: 'ja_JP',
symbol: '¥',
decimalDigits: 0,
).format(rate);
break;
case 'zh':
final rate = _usdToCnyRate ?? DEFAULT_USD_TO_CNY_RATE;
return NumberFormat.currency(
result = NumberFormat.currency(
locale: 'zh_CN',
symbol: '¥',
decimalDigits: 2,
).format(rate);
break;
default:
return '';
result = '';
break;
}
// 대략적인 사이즈(문자 길이)로 캐시 저장
_fmtCache.set(key, result, size: result.length);
return result;
}
/// USD 금액을 KRW로 변환하여 포맷팅된 문자열로 반환합니다.