고급
App architecture
UI, domain, data layer를 나누고 의존성 방향을 관리합니다.
핵심 개념
App architecture 주요 항목
레이어 분리
UI layer는 화면과 사용자 상호작용을 다룹니다.
언제 쓰나: Data layer는 API, 로컬 DB, 캐시 같은 데이터 출처를 다룹니다.
Flutter에서: Domain layer는 앱의 핵심 규칙을 분리하고 싶을 때 추가할 수 있습니다.
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text('레이어 분리', style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(height: 8),
Text('UI layer는 화면과 사용자 상호작용을 다룹니다.'),
],
),
),
)
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: const Color(0xFFDCE6EF)),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
decoration: BoxDecoration(
color: const Color(0xFFEEF7FB),
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'레이어 분리',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w900),
),
)
],
),
)
레이어 분리
추천 사고방식
작은 앱부터 과한 구조를 적용하기보다 기능이 반복될 때 분리합니다.
언제 쓰나: Repository는 데이터 출처를 숨기고 UI가 안정적인 인터페이스에 의존하게 도와줍니다.
Flutter에서: 의존성 주입은 테스트 가능성과 구현 교체 가능성을 높여 줍니다.
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text('추천 사고방식', style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(height: 8),
Text('작은 앱부터 과한 구조를 적용하기보다 기능이 반복될 때 분리합니다.'),
],
),
),
)
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: const Color(0xFFDCE6EF)),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
decoration: BoxDecoration(
color: const Color(0xFFEEF7FB),
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'추천 사고방식',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w900),
),
)
],
),
)
추천 사고방식
확장 개념
계층과 의존성
- UI layer는 화면 상태와 사용자 입력을 처리합니다.
- Data layer는 API, 로컬 저장소, 캐시와 통신합니다.
- Repository는 UI가 데이터 출처를 직접 알지 않아도 되도록 경계를 만듭니다.
확장 개념
테스트 가능한 구조
- 비즈니스 규칙은 화면 코드에서 분리할수록 단위 테스트가 쉬워집니다.
- 의존성 주입은 실제 API 대신 테스트 대역을 넣을 수 있게 해 줍니다.
- 앱 규모가 작을 때부터 모든 계층을 강제하기보다 반복되는 책임이 보일 때 분리합니다.
코드
예제
lib/
features/
lessons/
ui/
data/
domain/
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: const Color(0xFFDCE6EF)),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
decoration: BoxDecoration(
color: const Color(0xFFEEF7FB),
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'실행 결과',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w900),
),
),
Wrap(
spacing: 8,
runSpacing: 8,
children: [
Chip(label: Text('UI')),
Chip(label: Text('상태')),
Chip(label: Text('데이터'))
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('코드가 앱의 한 부분으로 연결됩니다.')
],
)
],
),
)
프로젝트 구조
uidatadomain
기능 단위로 화면, 데이터, 규칙을 분리합니다.
다음 단계
실습 체크리스트
UI와 data 책임 분리Repository 도입 기준 정하기테스트 가능한 의존성 설계
- 출처세부 기준과 최신 변경 사항을 확인할 수 있습니다.
- Flutter API Reference클래스, 메서드, 생성자 세부 정의를 확인합니다.
- Dart languageDart 문법 자체가 궁금할 때 함께 봅니다.