iBetter Books
수정

여기까지 왔습니다. 긴 여정이었지만, 돌아보면 생각보다 많은 것을 배웠습니다. 각 PART에서 만났던 핵심 개념들을 한데 모아 정리해봅니다.

PART별 핵심 개념 정리

PART 01. 개발 환경 준비하기

Dart SDK를 설치하고, VS Code에 확장 기능을 설정하고, DartPad로 브라우저에서 바로 코드를 실행해봤습니다. "Hello, Dart!"를 출력하는 그 첫 줄이 이 모든 여정의 시작이었습니다.

  • Dart SDK 설치 및 dart CLI 명령어 사용
  • VS Code + Dart 확장으로 개발 환경 구성
  • DartPad로 설치 없이 Dart 코드 실행
  • dart run, dart compile 기본 명령어

PART 02. 변수와 타입의 세계

변수를 선언하는 방법부터 Dart가 타입을 어떻게 다루는지 배웠습니다. var, final, const의 미묘한 차이, 그리고 null을 처음으로 마주쳤습니다.

  • var, final, const 차이와 선택 기준
  • 기본 타입: int, double, String, bool, dynamic
  • 타입 추론: 컴파일러가 타입을 알아서 결정
  • null의 첫 만남과 ? 연산자 맛보기
  • 산술, 비교, 논리, 할당 연산자 활용

PART 03. 흐름을 제어하다

프로그램이 "생각"하는 방식을 배웠습니다. 조건에 따라 다르게 행동하고, 반복하고, 함수로 기능을 묶는 법을 익혔습니다.

  • if/else, switch 조건문으로 분기 처리
  • for, while, do-while 반복문 활용
  • 함수 선언과 반환값 다루기
  • named 매개변수와 optional 매개변수로 유연한 함수 설계
  • => 화살표 함수로 간결하게 표현

PART 04. 여러 값을 다루다 — 컬렉션

하나의 값이 아닌 여러 값을 묶어서 다루는 법을 배웠습니다. List, Set, Map은 실전에서 가장 자주 쓰이는 도구입니다.

  • List: 순서 있는 데이터 목록
  • Set: 중복 없는 고유한 값의 집합
  • Map: 키-값 쌍으로 데이터 관리
  • map(), where(), reduce()로 데이터를 함수형으로 처리
  • 스프레드 연산자(...)로 컬렉션 합치기

PART 05. 객체로 생각하기 — 클래스와 OOP

현실 세계의 개념을 코드로 표현하는 객체 지향 프로그래밍을 배웠습니다. 클래스는 설계도이고, 객체는 그 설계도로 만든 실물입니다.

  • 클래스 선언, 필드, 메서드, this 키워드
  • 기본 생성자, named 생성자, factory 생성자
  • extends로 상속하고, super로 부모 접근
  • abstract class로 공통 인터페이스 정의
  • implements로 인터페이스 구현
  • with으로 믹스인(mixin) 기능 조합
  • enum으로 의미 있는 상수 집합 표현

PART 06. 안전한 코드의 비밀 — Null Safety 심화

Dart가 null 관련 버그를 컴파일 시점에 잡아내는 Sound Null Safety를 깊이 파고들었습니다. 처음엔 낯설지만, 익숙해지면 코드에 대한 자신감이 생깁니다.

  • Sound Null Safety: nullable(?)과 non-nullable 타입 구분
  • ?. null-aware 접근, ?? null 병합, ??= null 병합 할당
  • ! null 단언 연산자와 남용 금지
  • late 키워드로 늦은 초기화 처리
  • 흐름 분석(Flow Analysis)으로 타입 자동 승격

PART 07. 타입을 자유롭게 — 제네릭

같은 로직을 다양한 타입에 재사용하는 제네릭을 배웠습니다. 타입 안전성을 유지하면서도 코드 중복을 줄이는 강력한 도구입니다.

  • <T>로 제네릭 클래스 선언하고 활용
  • 제네릭 함수로 타입에 구애받지 않는 유틸리티 작성
  • extends로 타입 매개변수에 제약 조건 추가
  • extension으로 기존 타입에 메서드 추가(확장 메서드)

PART 08. 기다림의 미학 — 비동기 프로그래밍

네트워크 요청, 파일 읽기처럼 "기다려야 하는" 작업을 우아하게 처리하는 비동기 프로그래밍을 배웠습니다.

  • Future로 미래의 값을 표현
  • async/await로 비동기 코드를 동기처럼 읽기 쉽게 작성
  • Stream으로 연속적으로 흐르는 데이터 처리
  • Isolate로 멀티스레딩과 병렬 처리
  • try/catch/finally로 비동기 에러 안전하게 처리

PART 09. Dart 3의 새 얼굴 — 패턴과 레코드

Dart 3에서 새롭게 추가된 기능들을 배웠습니다. 함수형 스타일의 코드를 더 명확하고 간결하게 만들어주는 현대적인 문법입니다.

  • 레코드((type, type))로 여러 값을 타입 안전하게 묶기
  • 패턴 매칭으로 데이터 구조를 분해하고 검사
  • switch 표현식으로 값을 반환하는 분기 처리
  • 구조 분해(Destructuring)로 List, Map, 객체에서 값 추출
  • sealed class로 완전한 타입 계층 정의

PART 10. 미니 프로젝트 — 할 일 관리 CLI 앱

배운 모든 것을 하나의 프로젝트로 엮어봤습니다. CLI에서 할 일을 추가하고, 완료하고, 삭제하고, JSON 파일에 저장하는 실전 앱을 만들었습니다.

  • CLI 인자 파싱과 대화형 입력 처리
  • dart:convert로 JSON 직렬화/역직렬화
  • dart:io로 파일 입출력 구현
  • OOP 설계: Todo 모델, TodoRepository, TodoHandler 분리
  • 예외 처리와 사용자 친화적 에러 메시지

학습 체크리스트

지금까지 배운 내용을 스스로 점검해봅니다. 자신 있게 "할 수 있다"고 답할 수 있는 항목이 늘어날수록 실력이 쌓인 것입니다.

기초 문법

  • var, final, const의 차이를 설명할 수 있다.
  • 기본 타입(int, double, String, bool)을 상황에 맞게 사용할 수 있다.
  • if/else, switch, for, while을 활용한 흐름 제어를 작성할 수 있다.
  • 함수를 선언하고, named 매개변수와 optional 매개변수를 활용할 수 있다.
  • 화살표 함수(=>)로 간결하게 표현할 수 있다.

컬렉션과 OOP

  • List, Set, Map을 생성하고 데이터를 추가/조회/삭제할 수 있다.
  • map(), where(), reduce()를 활용해 데이터를 변환할 수 있다.
  • 클래스를 설계하고 생성자, 필드, 메서드를 구현할 수 있다.
  • 상속(extends)과 추상 클래스(abstract)를 적절히 활용할 수 있다.
  • 믹스인(with)으로 기능을 조합할 수 있다.

Null Safety와 제네릭

  • nullable 타입(?)과 non-nullable 타입의 차이를 이해한다.
  • ?., ??, ??=, ! 연산자를 상황에 맞게 사용할 수 있다.
  • late 키워드가 필요한 상황을 설명할 수 있다.
  • 제네릭 클래스와 제네릭 함수를 작성할 수 있다.
  • 확장 메서드(extension)로 기존 타입에 기능을 추가할 수 있다.

비동기와 Dart 3

  • Futureasync/await를 활용해 비동기 코드를 작성할 수 있다.
  • Stream을 구독하고 데이터를 처리할 수 있다.
  • 비동기 에러를 try/catch로 처리할 수 있다.
  • 레코드와 구조 분해를 활용해 여러 값을 다룰 수 있다.
  • switch 표현식과 패턴 매칭으로 분기를 처리할 수 있다.

실전 응용

  • 작은 CLI 앱을 설계하고 구현할 수 있다.
  • JSON 파일에 데이터를 읽고 쓸 수 있다.
  • 코드를 역할에 따라 클래스로 분리할 수 있다.
  • 예외 상황을 예측하고 적절히 처리할 수 있다.

아직 체크하지 못한 항목이 있어도 괜찮습니다. 이 책을 한 번 읽었다고 모든 것이 머릿속에 남는 것은 아닙니다. 다시 돌아와서 해당 PART를 펼쳐보고, 직접 코드를 타이핑해보는 것이 가장 좋은 복습 방법입니다.