728x90
반응형
1. 디자인 패턴이란? 🤔
1.1 쉬운 비유로 이해하기
디자인 패턴은 집을 지을 때 사용하는 설계도와 같습니다:
- 검증된 방법으로 문제 해결
- 유지보수가 쉬워짐
- 다른 개발자들과 소통이 쉬워짐
예를 들어, 아파트를 지을 때 주방, 화장실, 거실의 위치를 계획하는 것처럼, 앱을 만들 때도 각 부분의 역할과 위치를 계획합니다.
2. MVVM 패턴 🏗️
2.1 MVVM이란?
쉽게 설명하면, 앱을 세 부분으로 나누는 방법입니다:
- Model: 데이터
- View: 화면
- ViewModel: 데이터를 화면에 맞게 가공
2.2 실생활 비유
레스토랑으로 비유하면:
- Model: 주방에서 요리하는 셰프 (데이터 처리)
- View: 손님이 보는 메뉴판과 음식 (화면)
- ViewModel: 주문을 받고 전달하는 웨이터 (중간 역할)
2.3 간단한 예제
// Model: 데이터 클래스
data class User(
val name: String,
val age: Int
)
// ViewModel: 데이터 처리
class UserViewModel : ViewModel() {
private val _user = MutableLiveData<User>()
val user: LiveData<User> = _user
fun loadUser() {
// 사용자 정보 가져오기
_user.value = User("홍길동", 25)
}
}
// View: 화면 표시
class MainActivity : AppCompatActivity() {
private val viewModel: UserViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 데이터 변경 관찰
viewModel.user.observe(this) { user ->
nameTextView.text = user.name
ageTextView.text = "${user.age}세"
}
}
}
3. Repository 패턴 📚
3.1 Repository란?
데이터를 저장하고 가져오는 방법을 한 곳에서 관리하는 패턴입니다.
3.2 실생활 비유
도서관으로 비유하면:
- Repository: 도서관 사서
- 데이터: 책
- 앱: 책을 빌리는 사람
3.3 간단한 예제
// Repository 인터페이스
interface UserRepository {
suspend fun getUser(id: String): User
suspend fun saveUser(user: User)
}
// Repository 구현
class UserRepositoryImpl(
private val api: UserApi,
private val database: UserDatabase
) : UserRepository {
override suspend fun getUser(id: String): User {
// 1. 먼저 로컬 데이터베이스 확인
val localUser = database.getUser(id)
if (localUser != null) {
return localUser
}
// 2. 없으면 서버에서 가져오기
val remoteUser = api.fetchUser(id)
// 3. 데이터베이스에 저장
database.saveUser(remoteUser)
return remoteUser
}
}
4. Factory 패턴 🏭
4.1 Factory란?
객체를 만드는 공장이라고 생각하면 됩니다.
4.2 실생활 비유
피자 가게로 비유하면:
- Factory: 피자를 만드는 주방
- 제품: 다양한 종류의 피자
- 주문: 객체 생성 요청
4.3 간단한 예제
// 피자 인터페이스
interface Pizza {
fun prepare()
fun bake()
fun cut()
}
// 구체적인 피자 클래스들
class CheesePizza : Pizza {
override fun prepare() = println("치즈 피자 준비")
override fun bake() = println("치즈 피자 굽기")
override fun cut() = println("치즈 피자 자르기")
}
class PepperoniPizza : Pizza {
override fun prepare() = println("페퍼로니 피자 준비")
override fun bake() = println("페퍼로니 피자 굽기")
override fun cut() = println("페퍼로니 피자 자르기")
}
// 피자 공장
class PizzaFactory {
fun createPizza(type: String): Pizza {
return when (type) {
"cheese" -> CheesePizza()
"pepperoni" -> PepperoniPizza()
else -> throw IllegalArgumentException("알 수 없는 피자 종류")
}
}
}
5. Builder 패턴 🔨
5.1 Builder란?
복잡한 객체를 단계별로 만드는 방법입니다.
5.2 실생활 비유
레고 조립으로 비유하면:
- Builder: 레고 조립 설명서
- 부품: 객체의 속성들
- 완성품: 만들어진 객체
5.3 간단한 예제
// 일반적인 방법
class User(
val name: String,
val age: Int,
val email: String,
val address: String,
val phone: String
)
// Builder 패턴 사용
class UserBuilder {
private var name: String = ""
private var age: Int = 0
private var email: String = ""
private var address: String = ""
private var phone: String = ""
fun setName(name: String) = apply { this.name = name }
fun setAge(age: Int) = apply { this.age = age }
fun setEmail(email: String) = apply { this.email = email }
fun setAddress(address: String) = apply { this.address = address }
fun setPhone(phone: String) = apply { this.phone = phone }
fun build() = User(name, age, email, address, phone)
}
// 사용 예시
val user = UserBuilder()
.setName("홍길동")
.setAge(25)
.setEmail("hong@example.com")
.build()
6. Clean Architecture 🏛️
6.1 Clean Architecture란?
앱을 여러 층으로 나누어 관리하는 방법입니다.
6.2 실생활 비유
백화점으로 비유하면:
- UI 층: 진열대 (고객이 보는 부분)
- Domain 층: 매장 관리자 (비즈니스 로직)
- Data 층: 창고 (데이터 저장소)
6.3 간단한 예제
// Data Layer (데이터 층)
class UserRepositoryImpl : UserRepository {
override suspend fun getUser(id: String): User {
return api.getUser(id)
}
}
// Domain Layer (비즈니스 로직 층)
class GetUserUseCase(
private val repository: UserRepository
) {
suspend operator fun invoke(id: String): User {
return repository.getUser(id)
}
}
// Presentation Layer (UI 층)
class UserViewModel(
private val getUserUseCase: GetUserUseCase
) : ViewModel() {
private val _user = MutableStateFlow<User?>(null)
val user: StateFlow<User?> = _user.asStateFlow()
fun loadUser(id: String) {
viewModelScope.launch {
_user.value = getUserUseCase(id)
}
}
}
디자인 패턴 선택 가이드 💡
언제 어떤 패턴을 사용할까?
- MVVM 패턴
- 화면이 많은 앱
- 데이터와 화면을 분리하고 싶을 때
- Android 앱 개발시 권장
- Repository 패턴
- 여러 데이터 소스를 사용할 때
- 데이터 캐싱이 필요할 때
- 오프라인 모드 지원시
- Factory 패턴
- 비슷한 객체를 여러 개 만들 때
- 객체 생성 로직을 분리하고 싶을 때
- Builder 패턴
- 복잡한 객체를 만들 때
- 선택적 매개변수가 많을 때
- Clean Architecture
- 큰 규모의 앱
- 테스트가 중요한 프로젝트
- 유지보수가 중요한 경우
결론 ✨
디자인 패턴과 아키텍처는 앱을 더 잘 만들기 위한 도구입니다:
- 코드 구조화
- 체계적인 코드 관리
- 쉬운 유지보수
- 명확한 책임 분리
- 팀 협업
- 공통된 용어
- 이해하기 쉬운 구조
- 효율적인 소통
- 품질 향상
- 버그 감소
- 테스트 용이성
- 확장성 개선
반응형
'Kotlin' 카테고리의 다른 글
코틀린(Kotlin)데이터 클래스와 sealed 클래스 (0) | 2024.11.25 |
---|---|
Kotlin(코틀린) FLow 란? (24) | 2024.11.21 |
코틀린이란? (Kotlin) (1) | 2024.11.19 |
QueryDSL 란, 주요 메서드 및 장단점 기본 설명 (0) | 2024.08.13 |
테스트 코드 작성 이유 및 방법 - SpringBoot, Kotlin (0) | 2024.08.09 |