전체 글
-
영구 저장소 아키텍처: SQL아키텍처/아키텍처 디자인 패턴 2025. 5. 9. 20:16
이 레시피에서는 Flutter 아키텍처 디자인 패턴을 따르면서 SQL을 사용하여 복잡한 데이터를 Flutter 애플리케이션에 영구 저장하는 방법을 배웁니다. 이 레시피를 읽기 전에, SQL과 SQLite에 대한 기본적인 지식이 있어야 합니다. 도움이 필요하다면 Persist data with SQLite 레시피를 먼저 읽어보는 것을 추천합니다. 이 예제는 sqflite와 sqflite_common_ffi 플러그인을 사용하여 모바일과 데스크톱을 동시에 지원합니다. 웹 지원은 실험적인 플러그인인 sqflite_common_ffi_web에서 제공되지만, 이 예제에는 포함되어 있지 않습니다.예제 애플리케이션: 할 일(ToDo) 목록 애플리케이션이 예제 애플리케이션은 상단에 앱 바(AppBar), 중앙에 아이템 ..
-
영속적 저장소 아키텍처: 키-값 데이터아키텍처/아키텍처 디자인 패턴 2025. 5. 9. 11:52
대부분의 Flutter 애플리케이션은 크기에 상관없이 사용자 기기에 데이터를 저장해야 할 필요가 있습니다. 예를 들어, API 키, 사용자 환경설정 또는 오프라인 상태에서도 사용할 수 있어야 하는 데이터 등이 이에 해당합니다. 이 레시피에서는 Flutter에서 권장하는 아키텍처 디자인을 사용하는 애플리케이션에 키-값 데이터를 위한 영속적 저장소를 통합하는 방법을 배웁니다. 키-값 저장소는 일반적으로 앱 설정과 같은 간단한 데이터를 저장하는 데 사용됩니다. 이 레시피에서는 다크 모드 환경설정을 저장하기 위해 키-값 저장소를 사용할 것입니다.예제 애플리케이션: 테마 선택 기능이 있는 앱이 예제 애플리케이션은 상단에 AppBar, 중간에 항목 목록, 하단에 텍스트 필드 입력이 있는 단일 화면으로 구성됩니다. ..
-
낙관적 상태 (Optimistic State)아키텍처/아키텍처 디자인 패턴 2025. 5. 8. 22:54
사용자 경험을 구축할 때, 성능에 대한 인식은 실제 코드 성능만큼이나 중요할 수 있습니다. 일반적으로 사용자들은 작업이 완료될 때까지 기다리는 것을 좋아하지 않으며, 몇 밀리초 이상 걸리는 동작은 “느리다” 또는 “응답하지 않는다”라고 인식될 수 있습니다. 개발자는 백그라운드 작업이 완전히 완료되기 전에 성공적인 UI 상태를 먼저 보여주는 방식으로 이러한 부정적인 인식을 줄일 수 있습니다. 예를 들어, “구독” 버튼을 탭 했을 때, 백엔드 API 호출이 진행 중이더라도 즉시 버튼이 “구독 완료”로 바뀌는 경우입니다. 이러한 기술을 낙관적 상태(Optimistic State), 낙관적 UI(Optimistic UI) 또는 낙관적 사용자 경험(Optimistic User Experience) 이라고 부릅니다..
-
아키텍처 디자인 패턴 개요아키텍처/아키텍처 디자인 패턴 2025. 5. 8. 22:22
이 글들은 고수준의 앱 아키텍처에 관한 것이 아니라, 앱을 어떻게 아키텍처했는지와 상관없이 애플리케이션의 코드 기반을 향상시킬 수 있는 특정한 디자인 문제를 해결하는 방법에 관한 것입니다.다만, 코드 예제에서는 MVVM 패턴을 기반으로 하고 있다는 점을 참고하세요.낙관적 상태 (Optimistic state)user experience | asynchronous dart낙관적 상태 구현을 통해 애플리케이션의 반응 속도에 대한 인식을 향상시키세요.사용자 경험을 구축할 때는, 실제 코드 성능 못지않게 성능에 대한 인식(perception) 이 중요할 수 있습니다.일반적으로 사용자는 어떤 동작이 완료될 때까지 기다리는 것을 좋아하지 않으며, 몇 밀리초 이상 걸리는 동작이라면 “느리다” 또는 “반응이 없다”고 ..
-
테스트 - 테스트용 페이크(fake)를 만들고, 이를 활용하는 코드를 작성하자아키텍처/아키텍처 권장사항 2025. 5. 8. 19:57
“테스트용 페이크(Fake)”란?실제 앱에서 서버나 데이터베이스를 사용하는 대신,“가짜 객체”를 만들어서 테스트하는 방법입니다.즉, 진짜 서버랑 통신하지 않고도테스트에 필요한 데이터만 주고받는 역할을 해요.왜 페이크를 사용할까요?이유 설명빠른 테스트서버에 연결하지 않아도 돼서 테스트가 빠름안정성네트워크 오류 없이 항상 예측 가능한 값을 반환간편한 테스트에러나 특정 상황을 쉽게 시뮬레이션할 수 있음페이크는 "입력"과 "출력"에 집중해요메서드가 실제로 어떻게 동작하는지는 신경 안 써도 돼요.중요한 건 주어진 입력값에 대해 어떤 결과(출력)를 내놓느냐입니다.간단한 예제로 이해하기도메인 모델class User { final String name; final int age; User(this.name, th..
-
테스트 - 아키텍처 구성요소를 별도로, 그리고 함께 테스트하자아키텍처/아키텍처 권장사항 2025. 5. 8. 19:55
테스트는 왜 필요할까요?앱이 잘 작동하는지 눈으로 확인하는 것도 좋지만,버튼 하나 바꿨더니 다른 기능이 망가지는 일이 생길 수 있어요.이런 문제를 자동으로 미리 잡아주는 게 "테스트"입니다.Flutter에서는 테스트도 여러 종류가 있어요테스트 종류설명예시단위 테스트기능 하나하나 잘 동작하는지 확인숫자 계산 함수, 레포지토리 메서드위젯 테스트버튼, 화면 등 UI 위젯이 잘 작동하는지 확인버튼 클릭하면 텍스트가 바뀌는지통합 테스트앱 전체 흐름이 잘 되는지 확인로그인 → 홈 이동 흐름 확인무엇을 테스트하나요?1. 서비스 클래스→ 예: 로그인 API 호출, 로컬 DB 저장 등✅ 실제 외부와 통신하기 전에, 로직이 맞는지 테스트합니다.2. 레포지토리 클래스→ 데이터를 어디서 가져오든, 기능이 동일하게 작동하는지 ..
-
앱 구조 - 추상 레포지토리 클래스를 사용하자아키텍처/아키텍처 권장사항 2025. 5. 8. 19:52
레포지토리(Repository)란?앱에서 서버나 데이터베이스와 통신하려면, 그 데이터를 가져오고 저장하는 중간 역할이 필요합니다.이 역할을 해주는 것이 바로 레포지토리 클래스입니다.예: 사용자의 정보를 서버에서 가져오는 코드class UserRepository { Future fetchUser() { // 서버 통신 로직 (예: http.get) }}그런데, 왜 “추상” 레포지토리가 필요한가요?“추상 클래스”는 형태만 있고 실제 내용은 없는 설계도 같은 것입니다.즉, 어떤 기능이 필요하다는 약속만 해놓고,실제 로직은 다른 클래스가 구현하도록 합니다.예를 들어 볼게요1. 추상 레포지토리 만들기 (약속만 있음)abstract class UserRepository { Future fetchUser(..
-
앱 구조 - 클래스, 파일, 디렉토리에 표준화된 이름 규칙을 사용하자아키텍처/아키텍처 권장사항 2025. 5. 8. 19:49
왜 이름 규칙이 중요할까요?작은 앱에선 괜찮을 수 있지만, 앱이 조금만 커지면 "어디에 뭐가 있는지" 찾는 게 너무 어렵습니다.그래서 개발자들끼리 약속된 이름 규칙을 사용하면, 코드를 더 쉽게 이해하고, 찾고, 유지보수하기가 훨씬 쉬워집니다.클래스 이름 규칙 예시역할이름예시 설명화면 위젯HomeScreen, LoginScreenUI를 구성하는 실제 화면입니다.상태/로직 관리HomeViewModel, LoginViewModel화면에서 필요한 데이터를 만들고 관리합니다.데이터 저장소UserRepository, PostRepository서버나 로컬에서 데이터를 불러오고 저장합니다.API 호출ClientApiService, AuthApiService서버와 통신할 때 사용합니다.💡 이름을 보면 역할이 딱 떠오르..