본문 바로가기

코딩

영어 많이 듣자! (어플리케이션 구조)

728x90
반응형

영어 많이 듣자! 클래스 다이어그램 📊

🏗️ 전체 클래스 구조 개요

classDiagram
    %% 메인 애플리케이션
    class MoviePhraseApp {
        +MaterialApp app
        +ThemeData theme
        +build() Widget
    }

    %% 메인 화면
    class MoviePhraseScreen {
        -MovieApiService _apiService
        -TranslationService _translationService
        -PageController _pageController
        -List~MovieResult~ _movies
        -List~SearchHistory~ _searchHistory
        -bool _isLoading
        -String _currentQuery
        +initState() void
        +_performSearch(String) Future~void~
        +_loadInitialData() Future~void~
        +build() Widget
    }

    %% 데이터 모델
    class MovieResult {
        +String name
        +String startTime
        +String text
        +String posterUrl
        +String videoUrl
        +fromJson(Map) MovieResult
        +toJson() Map~String,dynamic~
        +hasValidPoster bool
        +hasValidVideo bool
        +formattedTime String
    }

    class SearchHistory {
        +String originalQuery
        +String translatedQuery
        +DateTime timestamp
        +bool wasTranslated
        +int searchCount
        +fromJson(Map) SearchHistory
        +toJson() Map~String,dynamic~
        +copyWith() SearchHistory
    }

    %% 서비스 계층
    class MovieApiService {
        -Map~String,List~MovieResult~~ _cache
        -List~String~ _searchHistory
        +searchMovies(String) Future~List~MovieResult~~
        +getPopularSearches() Future~List~String~~
        +getSearchHistory() Future~List~String~~
        +checkHealth() Future~bool~
        +clearCache() void
    }

    class TranslationService {
        -Map~String,String~ _cache
        +translateToEnglish(String) Future~String?~
        +translateToKorean(String) Future~String?~
        +isKorean(String) bool
        +isEnglish(String) bool
        +clearCache() void
    }

    class SpeechService {
        -bool _isInitialized
        +initialize() Future~bool~
        +startListening(String,Duration) Future~String?~
        +stopListening() Future~void~
        +isAvailable() bool
    }

    %% UI 위젯
    class HeaderSection {
        +build() Widget
        +_showHelpDialog(BuildContext) void
        +_buildHelpItem(String,String,String) Widget
    }

    class SearchSection {
        +Function(String) onSearch
        +bool isLoading
        +TranslationService? translationService
        -TextEditingController _controller
        -SpeechService _speechService
        +_performSearch() void
        +_startListening() Future~void~
        +_buildLanguageIndicator() Widget
    }

    class MovieResultsSection {
        +List~MovieResult~ movies
        +build() Widget
        +_buildMovieCard(MovieResult) Widget
        +_buildEmptyState() Widget
    }

    class VideoModal {
        +String videoUrl
        +MovieResult movie
        -VideoPlayerController? _controller
        +_initializeVideo() Future~void~
        +_buildVideoPlayer() Widget
        +_buildControls() Widget
    }

    class RecentSearchesSection {
        +List~SearchHistory~ searchHistory
        +Function(String) onSearchTap
        +build() Widget
        +_buildSearchItem(SearchHistory) Widget
    }

    class StatisticsSection {
        +List~String~ statistics
        +Function(String) onStatisticTap
        +build() Widget
        +_buildStatisticChip(String) Widget
    }

    class LoadingIndicator {
        +String message
        +bool isTranslating
        +build() Widget
    }

    %% 유틸리티
    class AppConstants {
        +Color primaryColor
        +Color secondaryColor
        +Color backgroundColor
        +String baseUrl
        +Duration apiTimeout
        +int maxSearchHistory
    }

    %% 관계 정의
    MoviePhraseApp --> MoviePhraseScreen : creates
    MoviePhraseScreen --> MovieApiService : uses
    MoviePhraseScreen --> TranslationService : uses
    MoviePhraseScreen --> MovieResult : manages
    MoviePhraseScreen --> SearchHistory : manages
    MoviePhraseScreen --> HeaderSection : contains
    MoviePhraseScreen --> SearchSection : contains
    MoviePhraseScreen --> MovieResultsSection : contains
    MoviePhraseScreen --> RecentSearchesSection : contains
    MoviePhraseScreen --> StatisticsSection : contains
    MoviePhraseScreen --> LoadingIndicator : contains

    SearchSection --> SpeechService : uses
    SearchSection --> TranslationService : uses
    MovieResultsSection --> VideoModal : creates
    VideoModal --> MovieResult : displays

    MovieApiService --> MovieResult : returns
    TranslationService ..> MovieResult : translates
    SpeechService ..> SearchSection : provides input

📱 주요 클래스 상세 설명

🎭 1. 애플리케이션 계층

MoviePhraseApp

역할: 앱의 최상위 진입점
주요 기능:
- MaterialApp 설정 및 테마 적용
- 다크 테마 기본 설정
- 글로벌 앱 설정 관리
- 네비게이션 루트 설정

핵심 속성:
- theme: ThemeData (다크 테마 설정)
- home: MoviePhraseScreen (메인 화면)

MoviePhraseScreen

역할: 메인 화면 컨트롤러 및 상태 관리
주요 기능:
- 검색 로직 총괄 관리
- 페이지 네비게이션 (홈 ↔ 검색결과)
- 로딩 상태 및 에러 처리
- 번역 및 검색 워크플로우 조정

핵심 메서드:
- _performSearch(): 검색 실행 및 번역 처리
- _loadInitialData(): 앱 시작시 데이터 로딩
- _addToSearchHistoryLocal(): 검색 기록 저장
- _showTranslationSnackBar(): 번역 결과 알림

상태 관리:
- _movies: 검색된 영화 결과 리스트
- _searchHistory: 사용자 검색 기록
- _isLoading: 로딩 상태 플래그
- _currentQuery: 현재 검색어

🗃️ 2. 데이터 모델 계층

MovieResult

역할: 영화 검색 결과 데이터 모델
주요 기능:
- Django API 응답 데이터 파싱
- 영화 정보 구조화 관리
- 유효성 검증 (포스터/비디오 URL)
- 시간 포맷팅 (00:01:23 → 1분 23초)

핵심 속성:
- name: 영화 제목
- startTime: 장면 시작 시간  
- text: 영화 대사 내용
- posterUrl: 포스터 이미지 URL
- videoUrl: 비디오 파일 URL

유틸리티 메서드:
- hasValidPoster: 포스터 URL 유효성 검사
- hasValidVideo: 비디오 URL 유효성 검사
- formattedTime: 사용자 친화적 시간 표시
- textPreview: 대사 미리보기 (50자 제한)

SearchHistory

역할: 사용자 검색 기록 데이터 모델
주요 기능:
- 검색어 및 번역 정보 저장
- 검색 빈도 및 시간 추적
- 로컬 저장소 연동
- 검색 패턴 분석 지원

핵심 속성:
- originalQuery: 원본 검색어 (사용자 입력)
- translatedQuery: 번역된 검색어
- wasTranslated: 번역 여부 플래그
- timestamp: 검색 실행 시간
- searchCount: 해당 검색어 사용 횟수

데이터 처리:
- fromJson(): JSON → SearchHistory 변환
- toJson(): SearchHistory → JSON 변환
- copyWith(): 불변 객체 업데이트

🛠️ 3. 서비스 계층

MovieApiService

역할: Django 백엔드 API 통신 관리
주요 기능:
- RESTful API 호출 및 응답 처리
- 검색 결과 캐싱으로 성능 최적화
- 네트워크 에러 처리 및 재시도
- API 상태 모니터링

핵심 메서드:
- searchMovies(): 영화 대사 검색 API 호출
- getPopularSearches(): 인기 검색어 조회
- getSearchHistory(): 검색 기록 조회
- checkHealth(): 서버 상태 확인

캐싱 전략:
- _cache: 검색 결과 메모리 캐싱
- _searchHistory: 로컬 검색 기록 관리
- clearCache(): 캐시 정리 및 메모리 최적화

TranslationService

역할: 한국어-영어 자동 번역 서비스
주요 기능:
- MyMemory Translation API 연동
- 언어 자동 감지 (한국어/영어)
- 번역 결과 캐싱으로 API 호출 최소화
- 번역 실패시 graceful fallback

핵심 메서드:
- translateToEnglish(): 한국어 → 영어 번역
- isKorean(): 한국어 텍스트 감지
- isEnglish(): 영어 텍스트 감지

언어 감지 로직:
- 정규식 기반 한글 문자 패턴 매칭
- 영문 문자 및 특수문자 패턴 분석
- 혼합 언어 텍스트 처리

SpeechService

역할: 음성 인식 및 STT 기능 제공
주요 기능:
- Google Speech-to-Text API 연동
- 한국어 음성 인식 (11.5초)
- 마이크 권한 관리
- 실시간 음성 피드백

핵심 메서드:
- initialize(): 음성 인식 엔진 초기화
- startListening(): 음성 인식 시작
- stopListening(): 음성 인식 중단

설정 관리:
- language: 'ko-KR' (한국어 설정)
- timeout: 11.5초 (사용자 요청)
- 권한 처리: RECORD_AUDIO 권한 확인

🎨 4. UI 위젯 계층

HeaderSection

역할: 앱 상단 헤더 UI 컴포넌트
주요 기능:
- 앱 브랜딩 표시 ("영어 많이 듣자!")
- 사용자 아바타 이미지 (cskang.jpg)
- 설정 및 도움말 버튼
- 도움말 다이얼로그 표시

UI 구성:
- 좌측: 원형 아바타 이미지
- 중앙: 앱 타이틀 및 서브타이틀
- 우측: 설정/도움말 아이콘 버튼
- 그라데이션 배경 및 테두리

SearchSection

역할: 검색 입력 및 제어 UI
주요 기능:
- 텍스트 검색 입력 필드
- 음성 인식 버튼 및 상태 표시
- 실시간 언어 감지 UI
- 검색 팁 및 가이드 표시

상호작용:
- onSearch: 검색 실행 콜백
- 언어 감지: 실시간 🇰🇷/🇺🇸 표시
- 음성 버튼: 🎤 → 🔴 (녹음 중) 상태 변경
- 로딩 상태: 검색/번역 중 UI 비활성화

MovieResultsSection

역할: 영화 검색 결과 표시 UI
주요 기능:
- 영화 카드 리스트 렌더링
- 포스터 이미지 로딩 및 캐싱
- 빈 결과 상태 처리
- 비디오 모달 트리거

카드 구성:
- 포스터 이미지 (썸네일)
- 영화 제목 및 대사
- 시간 정보 (formattedTime)
- 탭 제스처로 비디오 재생

VideoModal

역할: 비디오 재생 모달 UI
주요 기능:
- 전체화면 비디오 플레이어
- 재생 컨트롤 (재생/일시정지)
- 진행바 및 시간 표시
- 영화 정보 오버레이

현재 상태:
- 오디오: 정상 재생 ✅
- 비디오: Galaxy S21 호환성 문제 ⚠️
- 하드웨어 가속 비활성화 적용
- AspectRatio 문제 해결 시도 중

RecentSearchesSection

역할: 최근 검색어 표시 UI
주요 기능:
- 검색 기록 리스트 표시
- 원본/번역 검색어 구분 표시
- 검색 시간 및 빈도 표시
- 클릭 이벤트 처리 (현재 비활성화)

표시 정보:
- 🇰🇷 원본 검색어 (한국어)
- 🇺🇸 번역 검색어 (영어)
- ⏰ 검색 시간
- 🔢 검색 횟수

⚙️ 5. 유틸리티 계층

AppConstants

역할: 앱 전역 상수 및 설정 관리
주요 기능:
- 색상 테마 정의
- API 엔드포인트 URL
- 타임아웃 설정
- 앱 제한값 설정

핵심 상수:
- primaryColor: Color(0xFF6C63FF) (보라색)
- baseUrl: 'https://movie.thesysm.com'
- apiTimeout: Duration(seconds: 30)
- maxSearchHistory: 20
- maxPopularSearches: 8

🔗 클래스 간 상호작용 플로우

검색 실행 플로우

1. User Input (SearchSection)
   ↓
2. Language Detection (TranslationService)
   ↓
3. Translation (if Korean) (TranslationService)
   ↓
4. API Call (MovieApiService)
   ↓
5. Data Parsing (MovieResult)
   ↓
6. UI Update (MovieResultsSection)
   ↓
7. History Save (SearchHistory)

음성 검색 플로우

1. Mic Button Tap (SearchSection)
   ↓
2. Permission Check (SpeechService)
   ↓
3. Voice Recognition (SpeechService)
   ↓
4. Text Input (SearchSection)
   ↓
5. Search Execution (→ 일반 검색 플로우)

비디오 재생 플로우

1. Movie Card Tap (MovieResultsSection)
   ↓
2. Modal Open (VideoModal)
   ↓
3. Video Initialize (VideoPlayerController)
   ↓
4. URL Load (MovieResult.videoUrl)
   ↓
5. Playback Start (VideoModal._controller)

📊 설계 패턴 적용

1. MVC (Model-View-Controller)

  • Model: MovieResult, SearchHistory
  • View: UI Widgets (SearchSection, MovieResultsSection 등)
  • Controller: MoviePhraseScreen (상태 관리)

2. Service Layer Pattern

  • API Service: MovieApiService
  • Translation Service: TranslationService
  • Speech Service: SpeechService

3. Repository Pattern

  • Local Storage: SearchHistory 로컬 캐싱
  • Remote API: MovieApiService API 호출
  • Cache Management: 메모리 및 로컬 캐시 전략

4. Observer Pattern

  • State Management: StatefulWidget + setState()
  • Event Handling: 콜백 함수 기반 상호작용
  • UI Updates: 상태 변경시 자동 UI 업데이트

이 클래스 다이어그램은 앱의 전체 구조와 각 컴포넌트 간의 관계를 명확히 보여주며, 유지보수와 확장성을 고려한 체계적인 설계를 반영합니다.

728x90
반응형