Skip to content

Conversation

@Yujin1014
Copy link
Collaborator

캐싱 관련한 기능을 구현해본 적이 처음이라 캐싱 관련된 코드를 중점적으로 봐주시면 좋을 것 같습니다!

  • 바코드 스캔 기능 구현
  • OCR 데이터 캐싱 기능 추가
  • 폴더명 및 클래스명 변경

@Yujin1014 Yujin1014 requested a review from abdul0986 April 26, 2025 14:15
@abdul0986
Copy link

[ISSUE #3] Feature/cache layer 와 같은 식으로 ISSUE와 연결해서 PR을 등록해주세요

class Barcode {
final String value;

Barcode(String value) : value = value.trim();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Barcode(String value) : value = value.trim();
Barcode(String value): value = value.trim();

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!

class BarcodeCacheService {
final CacheManager _cacheManager = CacheManager();

Future<void> saveToCache(String barcode, String data) async {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Future<void> saveToCache(String barcode, String data) async {
Future<void> save(String barcode, String data) async {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!

await _cacheManager.saveToCache(cacheKey, data);
}

Future<String?> loadFromCache(String barcode) async {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Future<String?> loadFromCache(String barcode) async {
Future<String?> load(String barcode) async {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!

return await _cacheManager.loadFromCache(cacheKey);
}

String _getCacheKey(String barcode) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
String _getCacheKey(String barcode) {
String _getKey(String barcode) {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!

Comment on lines 38 to 55
Future<void> startBarcodeScan(BuildContext context) async {
final barcode = await _scanService.scanBarcode(context);
try {
if (barcode != null) {
_updateScannedBarcode(barcode.value);
}
} catch (e) {
_handleError(e);
} finally {
///디버그 모드일 때에는 촬영이 불가능하여 임의의 바코드 값을 설정한다.
if (kDebugMode) {
_updateScannedBarcode('1234567890123');
if (context.mounted) {
await _checkCachedData(context, scannedBarcode);
}
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 startBarcodeScan()이 포함하고 있는 기능 목록

  • 스캔
  • 바코드 업데이트
  • 에러 처리
  • 디버그용 임시 데이터 처리

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

startBarcodeScan() : Refactoring

  • Future<void> startBarcodeScan(BuildContext context)
  • Future<Barcode?> _performBarcodeScan(BuildContext context)
  • Future<void> _handleScannerBarcode(BuildContext context, String barcodeValue) async
  • Future<void> _checkDebugModeCachedData(BuildContext context) async
  • void _setDebugBarcodeTemp()

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메소드를 더 잘게 나누어 수정했습니다!

Comment on lines 58 to 65
final cachedData = await _cacheService.loadFromCache(barcode ?? '');
if (context.mounted) {
if (cachedData != null) {
_navigateToIntakeGuide(context, cachedData);
} else {
_navigateToNutrientScan(context);
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

context.mounded처럼 조건이 명확하고, 실패할 경우 이후 코드를 진행할 필요가 없을 때는 early return 처리하기!!!

if (!context.mounted) return; 

final cachedData = await _cacheService.load(barcode ?? ''); 
if (cachedData != null) {
  _navigateToIntakeGuide(context, cachedData); 
} else {
  _navigateToNutrientScan(context); 
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!

class CacheManager {
static const _cacheDuration = Duration(days: 7);

Future<void> saveToCache(String key, String value) async {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Future<void> saveToCache(String key, String value) async {
Future<void> save(String key, String value) async {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!

await prefs.setString('${key}_expiry', expiryDate);
}

Future<String?> loadFromCache(String key) async {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Future<String?> loadFromCache(String key) async {
Future<String?> load(String key) async {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!

return null;
}

Future<void> removeFromCache(String key) async {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Future<void> removeFromCache(String key) async {
Future<void> remove(String key) async {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했습니다!

Comment on lines 15 to 29
final prefs = await SharedPreferences.getInstance();
final cachedValue = prefs.getString(key);
final expiryDateStr = prefs.getString('${key}_expiry');

if (cachedValue != null && expiryDateStr != null) {
final expiryDate = DateTime.parse(expiryDateStr);
if (DateTime.now().isBefore(expiryDate)) {
return cachedValue;
} else {
// Remove expired cache
await prefs.remove(key);
await prefs.remove('${key}_expiry');
}
}
return null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
final prefs = await SharedPreferences.getInstance();
final cachedValue = prefs.getString(key);
final expiryDateStr = prefs.getString('${key}_expiry');
if (cachedValue != null && expiryDateStr != null) {
final expiryDate = DateTime.parse(expiryDateStr);
if (DateTime.now().isBefore(expiryDate)) {
return cachedValue;
} else {
// Remove expired cache
await prefs.remove(key);
await prefs.remove('${key}_expiry');
}
}
return null;
final prefs = await SharedPreferences.getInstance();
final cachedValue = _getCachedValue(prefs, key);
final expiryDate = _getExpiryDate(prefs, key);
if (cachedValue == null || expiryDateStr == null) {
return null;
}
if (_isExpired(expiryDate)
await prefs.remove(key);
await prefs.remove('${key}_expiry');
}
return cachedValue;
String? _getCachedValue(SharedPreferences pref, String key) {
    return prefs.getString(key);
}

Datetime _getExpiryDate(SharedPreferences pref, String key) {
    final expireDateStr = prefs.getString('${key}_expiry'); 
    if (expiryDateStr == null) return null; 

    try {
        return Datetime.parse(expireDateStr); 
    } catch (_) {
        return null; 
    }
}

bool _isExpired(Datetime expiryDate) {
    return Datetime.now().isAfter(expiryDate);
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

명확하게 리팩토링 하였습니다!

@Yujin1014 Yujin1014 linked an issue May 1, 2025 that may be closed by this pull request
@Yujin1014 Yujin1014 requested a review from abdul0986 May 1, 2025 11:05
@Yujin1014 Yujin1014 added this to the 캐싱 레이어 구현 및 성능 최적화 milestone May 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BarcodeCacheServiceXXXService이기 때문에, 최대한 비즈니스 디펜던시가 있는 부분을 모두 포함하는 객체라고 생각

Comment on lines 66 to 71
if (kDebugMode) {
_setDebugBarcodeTemp();
if (context.mounted) {
await _checkCachedData(context, scannedBarcode ?? '');
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (kDebugMode) {
_setDebugBarcodeTemp();
if (context.mounted) {
await _checkCachedData(context, scannedBarcode ?? '');
}
}
if (!kDebugMode) {
return;
}
_setDebugBarcodeTemp();
await _checkCachedData(context, scannedBarcode ?? '');

Comment on lines +16 to +19
if (cachedAnswer != null) {
return AnalysisResult(cachedAnswer);
}
return null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (cachedAnswer != null) {
return AnalysisResult(cachedAnswer);
}
return null;
return cachedAnswer != null ? AnalysisResult(cachedAnswer) : null;

Copy link

@abdul0986 abdul0986 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

피드백 반영 부탁드려요

@Yujin1014 Yujin1014 requested a review from abdul0986 May 6, 2025 03:30
@Yujin1014
Copy link
Collaborator Author

피드백 반영하여 코드 다시 정리하였습니다.

Copy link

@abdul0986 abdul0986 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Yujin1014 Yujin1014 merged commit 58a77e6 into main May 11, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ISSUE #3] Feature/cache layer

2 participants