목록전체 글 (135)
Archive
onCreateView()“Fragment의 XML을 메모리에 올리고(binding), root view를 반환하는 단계”역할: 레이아웃 inflate + binding 연결이 시점에는 뷰가 “만들어지는 중”이라, 아직 Activity에 완전히 붙지 않았고 화면 표시도 안 된 상태이다.그래서 여기서는 최소한의 일만 하는 게 원칙override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { _binding = FragmentSampleBinding.inflate(inflater, container, false) return binding.root}..
Repository → ViewModel(StateFlow) → UI(Fragment/Compose) 두 가지 UI 버전 예시에 포함됨. 0) 모델 & UI 상태// domain/modeldata class User(val id: String, val name: String)// presentation/statedata class UserUiState( val loading: Boolean = false, val data: List = emptyList(), val error: String? = null) 1) DataSource & Repository (Flow로 데이터 제공)// data/remoteinterface UserRemoteDataSource { suspend fun ..
Flow에서의 map의 의미프래그먼트 쪽 collect { show -> ... }는 showPickNumberSpinner 값이 바뀔 때마다 람다를 실행해서 스피너 isVisible을 토글한다.mode가 바뀌면 → 그 변화를 map { ... }이 반영 → showPickNumberSpinner가 자동으로 바뀐다. (1) _mode (MutableStateFlow) ← 여기 값을 바꿈 (업스트림) │ emits ▼(2) mode: StateFlow (= _mode.asStateFlow()) │ map { it != RANK && it != DICE } ▼(3) showPickNumberSpinner: StateFlow │ collect (..
1. List / Iterable용 map// kotlinx.coroutines.flow.FlowKt__TransformKtpublic fun Flow.map(transform: suspend (T) -> R): Flow = unsafeTransform { value -> emit(transform(value)) } 즉시 계산, 자료구조를 바꿔서 새 컬렉션을 리턴 2. Sequence용 map // kotlin.sequences.Sequences.ktpublic fun Sequence.map(transform: (T) -> R): Sequence { return TransformingSequence(this, transform)} 지연 계산, 필요할 때만 계산TransformingSeque..
FingerPick 업데이트로 새로운 모드를 추가하던 중,과거에 해당 구조를 사용함으로써 이번에 작업을 수월하게 한 경험을 기록한다. 새로운 enum 값이 추가되면, else가 있는 경우엔 버그가 숨어들 가능성이 높아지게 되는데,else 없는 when을 사용해 두면 컴파일러가 "이 모드 처리 안 했잖아!" 하고 알려주게 되어 버그를 줄일 수 있다. val pickNumbers = when (mode) { Mode.PICK, Mode.RANK -> ... Mode.TEAM -> ... Mode.DICE -> ...} 즉, 이러한 enum Class + when 구조는 모든 경우를 다 다루고 있다는 검증을 컴파일러가 체크해준다.풀어 설명하면 enum class나 sealed class를 wh..
removeTouchCallback의 역할은? removeTouchCallback은 게임 로직에서 ViewModel로 "이 터치를 화면에서 제거해줘"라고 요청하는 콜백 함수이다. 역할: - GameLogic → ViewModel 통신: Strategy 패턴에서 게임 로직이 UI 상태를 직접 조작할 수 없으므로, 콜백을 통해 ViewModel에게 터치 제거를 요청 - 관심사 분리: 게임 로직은 "누구를 선택할지" 결정만 하고, 실제 터치 데이터와 애니메이션 관리는 ViewModel이 담당 - 의존성 역전: 게임 로직이 ViewModel에 의존하지 않고, 인터페이스(콜백)에만 의존 동작 흐름: 1. PickLogic이 랜덤 선택 후 removeTouchCallback(pointer)로 제거 요..
required?Dart에서는 Named parameter(이름 있는 파라미터)가 많다.기본적으로는 optional(선택)이라서 안 넣어도 됨.required를 붙이면 “이거 꼭 줘야 돼”라는 의미가 된다.예시:void greet({required String name, int? age}) { print("Hello $name");}greet(name: "Jiyeon"); // OKgreet(); // ❌ 컴파일 에러 (name 안 줌) → 즉, required는 “이 파라미터는 무조건 넣어야 한다”는 약속.(코틀린의 fun greet(name: String, age: Int? = null)과 비슷한데, Dart는 named param에서 required로 강제할 수 있음.)
자바나 코틀린에서의 final = “상수(변경 불가)” 개념이랑 비슷함.근데 Dart는 이걸 아주 광범위하게 적용할 수 있음:변수/필드 앞 → 값 재할당 불가 (Java의 final 변수, Kotlin의 val)final name = "Jiyeon"; // 한 번만 할당 가능클래스 앞 → 이 클래스는 더 이상 상속할 수 없음 (Java의 final class, Kotlin의 final 기본값과 비슷)final class A {}생성자 매개변수 앞 → 읽기 전용 필드로 고정됨 class Person { final String name; Person(this.name); // 여기서 name은 생성자 때만 정해지고 이후 변경 불가}지역 변수, 루프 변수 등등→ 어디서든 값 재할당 막을 때 final을 써..
하나의 스크린에서 동작하는 각 게임 모드에 대한 대한 게임로직을 만들어야 하는 상황. game_engine.dart에 모두 때려박아야 하는가?(예를들어 GameEngine 클래스의 gameResult()라는 메소드에서 게임 모드에 따라 switch문으로 분기시키기) 아니면 모드를 전략(Strategy)으로 분리하는게 좋은가? 당연히 Strategy 패턴을 이용하여 테스트·확장성·가독성·버그 격리도를 향상시키는게 좋다.확장성: 새로운 모드 추가해도 기존 코드 최소 변경(레지스트리에만 등록).테스트 용이: 각 로직을 단독 유닛테스트 가능, seed로 결과 재현.UI 분리: 엔진은 순수 로직, ChangeNotifier/ViewModel은 상태만 관리.안전성: 참가자 수/팀 개수 검증을 각 전략에 국한 → 버..
class A { A(); } 이 코드는 Dart 문법으로 작성된 클래스 선언이다. 의미를 풀어보면:class A { ... }→ A라는 이름의 클래스를 정의한 것.A();→ A 클래스의 기본 생성자(default constructor) 를 명시적으로 정의한 것.Dart에서는 생성자를 생략하면 자동으로 A(); 라는 기본 생성자가 제공됨.즉, 아래 두 코드는 완전히 동일한 의미이다:class A { A(); // 기본 생성자 (직접 정의) }class A { // 아무 생성자도 정의하지 않으면, 자동으로 A(); 생성자가 만들어짐 } 👉 정리하자면:이 코드는 "A라는 클래스를 만들고, 매개변수가 없는 기본 생성자를 명시적으로 선언한다"는 뜻 언어별 기본 생성자 여부C❌ (개념 없음)Kotlin✅Java..