Skip to content

Commit

Permalink
Merge pull request #12 from DO-SOPT-ANDROID/feat/week8_clean_architec…
Browse files Browse the repository at this point in the history
…ture

[Feat/week8] clean architecture
  • Loading branch information
chanubc committed Jan 14, 2024
2 parents dc13bac + 7539122 commit 81a9e85
Show file tree
Hide file tree
Showing 48 changed files with 438 additions and 228 deletions.
18 changes: 12 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.20'
id 'kotlin-parcelize'
id 'kotlin-kapt'
id 'com.google.dagger.hilt.android'
}

Properties properties = new Properties()
Expand Down Expand Up @@ -30,23 +33,26 @@ android {
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '11'
jvmTarget = '17'
}
buildFeatures {
buildConfig true
viewBinding true
dataBinding true
}

// Allow references to generated code
kapt {
correctErrorTypes true
}
}

dependencies {
// parcelize
apply plugin: 'kotlin-parcelize'
implementation "com.google.dagger:hilt-android:2.44"
kapt "com.google.dagger:hilt-compiler:2.44"

// viewmodel 의존성 추가
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.dosopttemplate.network
package org.sopt.dosopttemplate.data

import android.util.Log
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
Expand All @@ -8,11 +8,13 @@ import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.sopt.dosopttemplate.BuildConfig
import org.sopt.dosopttemplate.network.login.AuthService
import org.sopt.dosopttemplate.data.service.AuthService
import org.sopt.dosopttemplate.data.service.ReqresService
import retrofit2.Retrofit

object ApiFactory {
private const val BASE_URL = BuildConfig.AUTH_BASE_URL
private const val AUTH_BASE_URL = BuildConfig.AUTH_BASE_URL
private const val USER_BASE_URL = BuildConfig.USER_BASE_URL

/* 1. 일단 로깅을 해줄 인터셉트를 만들어 줍니다.
2. 이 함수는 Http통신 중 로깅을 담당
Expand All @@ -34,17 +36,25 @@ object ApiFactory {
.addInterceptor(getLogOkHttpClient())
.build()

val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
private fun createRetrofit(baseUrl: String): Retrofit {
return Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient) // 여기에 달아준다.
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.build()
}

inline fun <reified T> create(): T = retrofit.create<T>(T::class.java)
private inline fun <reified T> create(baseUrl: String): T {
return createRetrofit(baseUrl).create(T::class.java)
}

object ServicePool {
val authService = ApiFactory.create<AuthService>()
val authService: AuthService by lazy {
create<AuthService>(AUTH_BASE_URL)
}

val userService: ReqresService by lazy {
create<ReqresService>(USER_BASE_URL)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.dosopttemplate.data.datasource.remote

import org.sopt.dosopttemplate.data.dto.remote.request.RequestLoginDto
import org.sopt.dosopttemplate.data.dto.remote.request.RequestSignUpDto
import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseLoginDto

interface AuthDataSource {
suspend fun login(request: RequestLoginDto): ResponseLoginDto
suspend fun signUp(request: RequestSignUpDto): Unit
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.dosopttemplate.data.datasource.remote

import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseReqresDto

// 레포지터리 인터페이스, 데이터 접근을 추상화, 데이터를 요청하는 코드를 부름
interface ReqresDataSource {
suspend fun getReqresList(page: Int): ResponseReqresDto
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.sopt.dosopttemplate.data.datasourceimpl.remote

import org.sopt.dosopttemplate.data.datasource.remote.AuthDataSource
import org.sopt.dosopttemplate.data.dto.remote.request.RequestLoginDto
import org.sopt.dosopttemplate.data.dto.remote.request.RequestSignUpDto
import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseLoginDto
import org.sopt.dosopttemplate.data.service.AuthService

class AuthDataSourceImpl(private val authService: AuthService) : AuthDataSource {
override suspend fun login(request: RequestLoginDto): ResponseLoginDto =
authService.postLogin(request)

override suspend fun signUp(request: RequestSignUpDto): Unit =
authService.postSignUp(request)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.sopt.dosopttemplate.data.datasourceimpl.remote

import org.sopt.dosopttemplate.data.datasource.remote.ReqresDataSource
import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseReqresDto
import org.sopt.dosopttemplate.data.service.ReqresService

// 실제 데이터 소스를 구현하는 클래스, 네트워크 호출을 통해 데이터를 가져오는 역할
class ReqresDataSourceImpl(
private val reqresService: ReqresService,
) : ReqresDataSource {
override suspend fun getReqresList(page: Int): ResponseReqresDto {
return reqresService.getUserList(page)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.dosopttemplate.network.login
package org.sopt.dosopttemplate.data.dto.remote.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sopt.dosopttemplate.network.login
package org.sopt.dosopttemplate.data.dto.remote.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.sopt.dosopttemplate.data.dto.remote.respose

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.sopt.dosopttemplate.domain.entity.UserEntity

@Serializable
data class ResponseLoginDto(
@SerialName("id")
val id: Int,
@SerialName("username")
val username: String,
@SerialName("nickname")
val nickname: String,
) {
fun toUserEntity() = UserEntity(
id = username,
pwd = "",
nickName = nickname,
mbti = "",
)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.sopt.dosopttemplate.network.doandroid
package org.sopt.dosopttemplate.data.dto.remote.respose

import kotlinx.serialization.Serializable
import org.sopt.dosopttemplate.domain.entity.ReqresEntity

@Serializable
data class ResponseReqresDto(
Expand All @@ -25,4 +26,14 @@ data class ResponseReqresDto(
val text: String,
val url: String,
)

fun toReqresList(): List<ReqresEntity> = data.map {
ReqresEntity(
id = it.id,
email = it.email,
first_name = it.first_name,
last_name = it.last_name,
avatar = it.avatar,
)
}
}
12 changes: 0 additions & 12 deletions app/src/main/java/org/sopt/dosopttemplate/data/login/User.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.sopt.dosopttemplate.data.repositoryimpl

import org.sopt.dosopttemplate.data.datasource.remote.AuthDataSource
import org.sopt.dosopttemplate.data.dto.remote.request.RequestLoginDto
import org.sopt.dosopttemplate.data.dto.remote.request.RequestSignUpDto
import org.sopt.dosopttemplate.domain.entity.UserEntity
import org.sopt.dosopttemplate.domain.entity.UserRequestEntity
import org.sopt.dosopttemplate.domain.repository.AuthDomainRepository

class AuthRepositoryImpl(private val authDataSource: AuthDataSource) : AuthDomainRepository {
override suspend fun login(userRequestEntity: UserRequestEntity): Result<UserEntity> =
kotlin.runCatching {
authDataSource.login(
RequestLoginDto(
userRequestEntity.userName,
userRequestEntity.passWord,
),
).toUserEntity()
}

override suspend fun signUp(userEntity: UserEntity): Result<Unit> =
kotlin.runCatching {
authDataSource.signUp(
RequestSignUpDto(
userEntity.id,
userEntity.pwd,
userEntity.nickName,
),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.sopt.dosopttemplate.data.repositoryimpl

import org.sopt.dosopttemplate.data.datasource.remote.ReqresDataSource
import org.sopt.dosopttemplate.domain.entity.ReqresEntity
import org.sopt.dosopttemplate.domain.repository.ReqresDomainRepository

// 외부 데이터 소스(ReqresDataSource)로부터 데이터를 가져오고, 필요한 형태로 변환하여 비즈니스 로직 계층에게 제공
class ReqresRepositoryImpl(private val reqresDataSource: ReqresDataSource) :
ReqresDomainRepository {
override suspend fun getReqresList(page: Int): Result<List<ReqresEntity>> {
return runCatching {
reqresDataSource.getReqresList(page).toReqresList()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.sopt.dosopttemplate.data.service

import org.sopt.dosopttemplate.data.dto.remote.request.RequestLoginDto
import org.sopt.dosopttemplate.data.dto.remote.request.RequestSignUpDto
import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseLoginDto
import retrofit2.http.Body
import retrofit2.http.POST

interface AuthService {
@POST("api/v1/members/sign-in")
suspend fun postLogin(
@Body request: RequestLoginDto,
): ResponseLoginDto

@POST("api/v1/members")
suspend fun postSignUp(
@Body request: RequestSignUpDto,
): Unit
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.sopt.dosopttemplate.data.service

import org.sopt.dosopttemplate.data.dto.remote.respose.ResponseReqresDto
import retrofit2.http.GET
import retrofit2.http.Query

interface ReqresService {
@GET("api/users")
suspend fun getUserList(
@Query("page") page: Int,
): ResponseReqresDto
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.dosopttemplate.domain.entity

data class ReqresEntity(
val id: Int,
val avatar: String,
val email: String,
val first_name: String,
val last_name: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.sopt.dosopttemplate.domain.entity

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class UserEntity(
val id: String,
val pwd: String,
val nickName: String,
val mbti: String,
) : Parcelable
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.sopt.dosopttemplate.domain.entity

data class UserRequestEntity(
val userName: String,
val passWord: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.dosopttemplate.domain.repository

import org.sopt.dosopttemplate.domain.entity.UserEntity
import org.sopt.dosopttemplate.domain.entity.UserRequestEntity

interface AuthDomainRepository {
suspend fun login(userRequestEntity: UserRequestEntity): Result<UserEntity>
suspend fun signUp(userEntity: UserEntity): Result<Unit>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.dosopttemplate.domain.repository

import org.sopt.dosopttemplate.domain.entity.ReqresEntity

/*ReqresRepository 인터페이스는 도메인(Domain) 레이어에서 사용되며,
원격 데이터 소스(ReqresDataSource)로부터 Reqres 사용자 리스트를 가져오는 기능을 정의*/
interface ReqresDomainRepository {
suspend fun getReqresList(page: Int): Result<List<ReqresEntity>>
}

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 81a9e85

Please sign in to comment.