-
Notifications
You must be signed in to change notification settings - Fork 0
2week_AOS_tech_post_3
์๋๋ก์ด๋ ๊ฐ๋ฐ์ ํด๋ณด๋ฉด ์์กด์ฑ ์ฃผ์ , ์์กด์ฑ ์ฃผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, Hilt ๊ฐ์ ๋จ์ด๋ค์ ๋ง์ด ๋ฃ๊ฒ ๋ฉ๋๋ค.
์์กด์ฑ์ ๋ ๋ญ๊ณ , ๊ทธ๊ฑธ ๋ ์ฃผ์ ??โฆ Hilt๋ ๋ ๋ญ์ผ ๋ฃ๊ธฐ๋ง ํด๋ ๋จธ๋ฆฌ๊ฐ ์ด์ง๋ฌ์ ์ง๋ ๊ธฐ๋ถ์ด์์~
์ ~ ๊ทธ๋ฌ๋ฉด ์ง๊ธ๋ถํฐ ์ฒ์ฒํ step by step์ผ๋ก ํ๋ฒ ์์๊ฐ ๋ด์!
์ฐ์ Hilt ์์กด์ฑ ์ฃผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์๊ธฐ ์ ์ ์์กด์ฑ์ด ๋ญ์ง ์์์ผ ํ ํ์๊ฐ ์์ด์
์ ํฌ ํจ๊ป ์์กด์ฑ์ด ๋ญ์ง ํจ๊ป ์์๊ฐ ๋ณผ๊น์?
์์กด ์ญ์ ์ ์์น์ด๋ผ๊ณ ๋ ๋ถ๋ฆฌ๋ ์๋์ ์ด๋์ ๋์จ ๋ง์ผ๊น์?
DIP๋ ๊ฐ์ฒด์งํฅ์ค๊ณ 5์์น(SOLID)์์ D์ ํด๋นํ๋ ์์น์ด๋ฉฐ ์์กด ์ญ์ ์ ๋ฒ์น์ด๋ผ๊ณ ๋ ํฉ๋๋ค.
์์กด ์ญ์ ์ ์์น
์์กด ๊ด๊ณ๋ฅผ ๋งบ์์ ๋ ๋ณํ๊ธฐ ์ฌ์ด ๊ฒ์ ์์กดํ๊ธฐ ๋ณด๋ค๋ ๋ณํํ์ง ์๋ ๊ฒ์ ์์กดํ๋ผ!
์์ ๋ง์ ์ด๋ค ์๋ฏธ๊ฐ ๋ด๊ฒจ ์์๊น์?
์๋ฅผ ๋ค์ด
์ ํฌ๊ฐ ์ผํ๋ฌผ์์ ์ฌ์ฉ์๊ฐ ๋ฌผ๊ฑด์ ๊ตฌ์ ํ๋ฉด ๊ตฌ์ ํ ๋ด์ญ์ ์๋ ค์ฃผ๊ธฐ ์ํด ์๋ฆผ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ค๊ณ ์๊ฐํด ๋ด ์๋ค.
์ด๋ฉ์ผ๋ก ์ฌ์ฉ์์๊ฒ ์๋ ค์ฃผ๊ธฐ๋ก ๊ฒฐ์ ์ ํ๊ณ ์๋์ ๊ฐ์ด ๊ธฐ๋ฅ์ ๊ตฌํ ํ์ต๋๋ค
class EmailMessenger {
fun sendNotification(message: String): String{
println("Sending email: $message")
}
}
class NotificationService {
private val messenger = EmailMessenger()
fun sendNotification() {
messenger.sendNotification("๊ตฌ์
๋ด์ญ์ ๋ํด ์๋ด ๋๋ฆฝ๋๋ค.")
}
}
ํ์ง๋ง ๋ฌธ์ ๊ฐ ์๋ค์!
๋ฌธ์ ์๋ฆผ ์๋น์ค๋ฅผ ๋ง๋ค์ด ๋ฌ๋ผ๊ณ ์์ฒญ์ด ๋ค์ด์ค๊ฑฐ๋ ์ด๋ฉ์ผ ๋ฉ์ ์ ๊ธฐ๋ฅ์ ๋ฐ๊ฟ๋ฌ๋ฆฌ๋ ์๊ตฌ์ฌํญ์ด ์๊ธฐ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
NotificationService
ย ํด๋์ค๋ย EmailMessenger
ย ํด๋์ค์ ์์กด์ฑ์ ๊ฐ์ง๊ณ ์๋ค๊ณ ํ ์ ์๋๋ฐย ,
EmailMessenger
ย ํด๋์ค์ ๋ณํ๊ฐ ์๊ธฐ๋ฉดย EmailMessenger
ย ํด๋์ค๋ฅผ ์ฐธ์กฐํ๋ ๋ชจ๋ ํด๋์ค๋ฅผ ์์ ํด์ค์ผ ํ๋ ์ํฉ์ด ์๊ธฐ๊ฒ ์ฃ ?
ํ๋ฒ์ ์ง๊ด์ ์ผ๋ก ์ดํด๊ฐ ์๋์์ฃ ? ์ด๋ค ์ํฉ์ผ์ง ๊ถ๊ธํ์ค๋ถ ๋ค์ด ์์ ๊ฒ ๊ฐ์์
๋ฐฑ๋ฌธ๋ถ์ฌ์ผ๊ฒฌ์ด๋ผ๋ ๋ง์ด ์๋ฏ์ด ํจ๊ป ์๋ ์์ ๋ฅผ ํ๋ฒ ๊ฐ์ด ๋ด๋ณผ๊น์?
์๋ ์์ ์ฒ๋ผย EmailMessenger
์ย sendNoticifation
ย ๋ฉ์๋๊ฐ ์ด์ ๋ฌธ์์ด ๋งค๊ฐ ๋ณ์ ๋์ ๊ฐ์ฒด๋ฅผ ๋ฐ๋๋ก ๋ณ๊ฒฝ ๋์๋ค๊ณ ๊ฐ์ ํด ๋ด
์๋ค.
data class EmailMessage(val content: String, val id: Int)
class EmailMessenger {
fun sendNotification(message: EmailMessage): String{
println("Sending email: ${message.content}")
}
}
NotificationService
ํด๋์ค์์๋ sendNoticifation() ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ ๋ฌธ์์ด ๋์ EmailMessenger ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋๋ก
๋ณ๊ฒฝํด์ผํฉ๋๋ค.
class NotificationService {
private val messenger = EmailMessenger()
fun sendNotification() {
messenger.sendNotification(EmailMessage("๊ตฌ์
๋ด์ญ์ ๋ํด ์๋ด ๋๋ฆฝ๋๋ค.", 1))
}
}
์? ๊ทธ๋ฅ ๋ฐ๊พธ๋ฉด ๋๋๊ฑฐ ์๋๊ฐ?? ๋ผ๊ณ ์๊ฐํ์ค ์ ๋ ์์ด์!
์ด๋ ๊ฒ ๊ฐ๋จํ ์์ ์์๋ ๊ทธ๋ฅ ๋ฐ๊พธ๊ณ ๋ง์ง ํ๋๋ฐ ๋ง์ฝ NotificationService ํด๋์ค์ฒ๋ผ EmailMessenger ํด๋์ค๋ฅผ ์์กดํ๋ ํด๋์ค๊ฐ
์์ฒญ ๋ง์์ง๋ค๋ฉด ์ด๋ป๊ฒ ํ ๊น์?
ํผ ๊ฐ์ ์๊ฐ์ ๊ทธ๊ฑธ ์ผ์ผ์ด ๋ฐ๊พธ๊ณ ์์ผ๋ฉด ๋๋ฌผ์ด ์ ๋ก ๋ ๊ฑฐ์์ ๐ฅฒ
์ด๋ ๊ฒ ํ๋์ ํด๋์ค๊ฐ ๋ค๋ฅธ ํด๋์ค์ ์์กดํ๋ ๊ฒฝ์ฐ, ํ์๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ ์๋ ๊ทธ์ ๋ฐ๋ผ ๋ณ๊ฒฝํด์ผ ํ๋ ์ํฉ์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
์ด๋ฐ ์ํฉ์ ํผํ๊ธฐ ์ํด ์์กด์ฑ ์ฃผ์ ์ ์ฌ์ฉํ์ฌ ํด๋์ค ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ฉด ์ฒซ ๋ฒ์งธ ์์ ์ ์ฝ๋์ ๋ํด ๋ฆฌํฉํ ๋ง ๊ณผ์ ์ ๊ฑฐ์ณ์ ์กฐ๊ธ ๋ ์ ์ง๋ณด์๊ฐ ์ฌ์ด ์ฝ๋๋ก ์์ฑํด ๋ด ์๋ค!
์ฐ์ ๊ณตํต ๋ถ๋ถ์ ์ถ์ํํ Interface๋ฅผ ๊ตฌํํ ๋ค
interface Messenger {
fun sendNotification()
}
๊ตฌํ ํด๋์ค๋ค์ ๋ง๋ค์ด ์ค๋๋ค.
class EmailMessenger() : Messenger {
override fun sendNotification(): String {
return "Sending email:"
}
}
class SMSMessenger() : Messenger {
override fun sendNotification(): String {
return "Sending SMS"
}
}
๋น์ง๋์ค ๋ก์ง์ ๋ด๋นํ๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด ์ค ๋ค
class NotificationService(private val messenger: Messenger) {
fun sendNotification(message: String) {
println(messenger.sendNotification() + message)
}
}
์๋์ ๊ฐ์ด ์ฌ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค.
class NotificationServiceTest {
@Test
fun sendNotification_givenEmail_shouldReturnEmailMessage() {
// Given
val notificationService = NotificationService(EmailMessenger())
// When
val message = emailService.sendNotification("๊ตฌ์
๋ด์ญ์ ๋ํด ์๋ดํด ๋๋ฆฝ๋๋ค")
// Then
assertEquals("Sending email:๊ตฌ์
๋ด์ญ์ ๋ํด ์๋ดํด ๋๋ฆฝ๋๋ค", message);
}
@Test
fun sendNotification_givenSms_shouldReturnSmsMessage() {
// Given
val notificationService = NotificationService(SMSMessenger())
// When
val message = notificationService.sendNotification("๊ตฌ์
๋ด์ญ์ ๋ํด ์๋ดํด ๋๋ฆฝ๋๋ค")
// Then
assertEquals("Sending SMS:๊ตฌ์
๋ด์ญ์ ๋ํด ์๋ดํด ๋๋ฆฝ๋๋ค", message);
}
}
์์ ๊ฐ์ ์ค๊ณ๋ฅผ ํ๊ฒ ๋๋ค๋ฉด,
์ธ๋ถ์์ EmailMessenger์ ์ธ์คํด์ค๋ฅผ ์์ฑํด NotificationService ํด๋์ค ๊ฐ์ฒด๋ฅผ ๋ง๋ค ๋ ์์ฑ์๋ก ์ฃผ์ ์ ํด์ฃผ๊ฒ ๋๋ค๋ฉด
EmailMessengerํด๋์ค์ ์์ ์ด ์ผ์ด๋๋๋ผ๋ NotificationServiceํด๋์ค๋ฅผ ์์ ํ ํ์๊ฐ ์๊ฒ ๋ฉ๋๋ค.
์ ์ฒ๋ผ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด NotificationService ํด๋์ค๋ ์ธ์ Messenger ์ธํฐํ์ด์ค์ ์์กดํ๊ฒ ๋๋ฏ๋ก EmailMessenger ํด๋์ค๋
SMSMessgenger ํด๋์ค๊ณผ ๊ฐ์ ๋ณํ๊ธฐ ์ฌ์ด ํด๋์ค ๋ณด๋ค ๋ ๋ณํ์ง ์๋ Messenger ์ธํฐํ์ด์ค์ ์์กดํ๊ฒ ๋๋ฏ๋ก ์ฝ๋์ ์ ์ฐ์ฑ์ด ๋์์ง๊ฒ ๋์๋ค์.
Messenger ์ธํฐํ์ด์ค์ ๊ตฌํ์ด ์ถ๊ฐ ๋๋๋ผ๋ NotificationService ํด๋์ค๋ฅผ ๋ณ๊ฒฐํ ํ์๊ฐ ์์ด์ก์ต๋๋ค.
DI๋ฅผ ํ๋ ์ด์ ๋ ์ฅ์ ์ ๋ญ๊น์?
- boilerplate code๋ฅผ ์ค์ฌ์ฃผ๋ฏ๋ก ์ ์ฐํ ํ๋ก๊ทธ๋๋ฐ์ด ๊ฐ๋ฅํด ์ง๋๋ค.
- ์ฌ์ฌ์ฉ์ฑ์ด ๋์์ง๊ณ ์ ์ง๋ณด์๊ฐ ๋ ์ฌ์์ง๋๋ค.
- ๋ ํธํ ์ ๋ ํ ์คํธ๊ฐ ๊ฐ๋ฅํด์ง๋๋ค.
- ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ์ด์ ํ์ฅ์ฑ์ ๋์ฌ ์ค๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์์กด์ฑ ์ญ์ ์ ๋ฒ์น์ ๋ํด ์์ ๋ดค์ผ๋ ์ด๊ฒ์ ์กฐ๊ธ ๋ ์ฝ๊ฒ ๊ตฌํํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ Hilt์ ๋ํด ํจ๊ป ์์๋ด์
Hilt๋ Android์์ Dependency Injection๋ฅผ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋๋ก ๋๋ ๋๊ตฌ์ ๋๋ค.
ํ์ํ ์์กด์ฑ์ ์ ๊ณตํ๋ **Module
**์ ์์ฑํ๊ณ , ํ์ํ ๊ณณ์ @Inject
์ฃผ์์ ์ฌ์ฉํ์ฌ ์์กด์ฑ์ ์ฃผ์
๋ฐ์ต๋๋ค.
Hilt๋ ์ด๋ฌํ ์์ ์ ์๋ํํ์ฌ ์ฝ๋๋ฅผ ๊น๋ํ๊ฒ ์ ์งํ๊ณ ํ ์คํธ๋ฅผ ์ฉ์ดํ๊ฒ ํด์ค๋๋ค.
๊ทธ๋ผ Hilt๋ฅผ ์ฌ์ฉํ์ ๋์ ์ฌ์ฉํ์ง ์์์ ๋์ ์์ ๋ฅผ ํ๋ฒ ๋ด๋ณผ๊น์?
class CarRepository(private val apiService: ApiService) {
// ...
}
class MainActivity : AppCompatActivity() {
// ์ง์ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ์ฃผ์
private val apiService = ApiService()
private val userRepository = UserRepository(apiService)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
}
}
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideApiService(): ApiService {
return ApiService()
}
}
class CarRepository @Inject constructor(private val apiService: ApiService) {
// ...
}
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
// Hilt๋ฅผ ํตํด ์๋์ผ๋ก ์์กด์ฑ ์ฃผ์
@Inject
lateinit var userRepository: UserRepository
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
}
}
- ์ ์์ ์์ ๋ณด์ด๋ฏ์ด Hilt๋ฅผ ์ฌ์ฉํ๋ฉด
ApiService
์ธ์คํด์ค ์์ฑ ๋ฐ **CarRepository
**์ ์ฃผ์ ํ๋ ์ฝ๋๋ฅผ ๋ช ์์ ์ผ๋ก ์์ฑํ ํ์๊ฐ ์์ด์ง๋๋ค. - Hilt๋ ์์กด์ฑ ์ฃผ์ ์ฝ๋๋ฅผ ๊ฐ์ํํ๊ณ ์๋ํ ํจ์ผ๋ก์จ ์ฝ๋์ ๋ณต์ก์ฑ์ ์ค์ฌ์ฃผ๊ณ ๊ด๋ฆฌ๋ฅผ ๋ ์ฝ๊ฒ ํด์ค๋๋ค.
**Application
ย ํด๋์ค์ Hilt ์ด๊ธฐํ**
@HiltAndroidApp
class CarArtApplication : Application()
CarExteriorImageRepository๋ฅผ ์ ๊ณตํ๋ ๋ชจ๋์ ์์ฑ (Optional)
-
RepositoryModule
ํด๋์ค๋ Hilt๋ฅผ ์ฌ์ฉํ์ฌ ์์กด์ฑ ์ฃผ์ ์ ์ค์ ํ ๋ ์ฌ์ฉ๋๋ ๋ชจ๋ ํด๋์ค์ ๋๋ค. - Hilt์ ๋ชจ๋์ ์์กด์ฑ ๊ทธ๋ํ์ ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋ ๋ฐฉ๋ฒ์ ์ ์ํฉ๋๋ค.
- ์ฆ, ์ด๋ค ํ์ ์ ๊ฐ์ฒด๋ฅผ ์์ฒญํ ๋ ์ด๋ค ๊ตฌํ์ฒด ๋๋ ์ธ์คํด์ค๋ฅผ ์ ๊ณตํด์ผ ํ๋์ง Hilt์ ์๋ ค์ฃผ๋ ์ญํ ์ ํฉ๋๋ค.
-
๋ชจ๋ ํด๋์ค๋ฅผ ์ธ์ ์์ฑํ๋์ง?
-
๋ชจ๋ ํด๋์ค๊ฐ ํ์ ์๋ ๊ฒฝ์ฐ
๋จ์ํ ์์กด์ฑ์ ์ฃผ๋ก ๋ค์๊ณผ ๊ฐ์ ํน์ง์ ๊ฐ์ต๋๋ค.
- ํด๋์ค์ ์์ฑ์๊ฐ ๋ค๋ฅธ ์์กด์ฑ ์์ด ์ฝ๊ฒ ์ธ์คํด์คํ๋ ์ ์์ต๋๋ค.
- ํด๋์ค์ ์์ฑ์์ ํ์ํ ํ๋ผ๋ฏธํฐ๋ค์ด ์ด๋ฏธ Hilt์ ์ํด ์ ๊ณต๋ ์ ์๋ ํ์ ์ด๊ฑฐ๋, ๊ทธ ์์ฒด๋ก ์ฃผ์ ๊ฐ๋ฅํ ๋ค๋ฅธ ํด๋์ค๋ค์ ๋๋ค.
์์ :
kotlinCopy code class UserService @Inject constructor(private val api: UserApi) { // ์ฌ๊ธฐ์ UserApi๋ Hilt๊ฐ ์๊ณ ์๋ ํ์ ์ด๊ฑฐ๋ ๋ค๋ฅธ ๊ณณ์์ ์ฃผ์ ๋ ์ ์๋ ํ์ ์ด์ด์ผ ํฉ๋๋ค. }
์์ **
UserService
**๋UserApi
ํ์ ๋ง ํ์๋ก ํ๋ฉฐ, ์ด **UserApi
**๊ฐ Hilt์ ์ํด ์ด๋ฏธ ์ฃผ์ ๊ฐ๋ฅํ ํ์ ์ด๋ผ๋ฉด, **UserService
**๋ ์๋์ผ๋ก ์ฃผ์ ๋ ์ ์์ต๋๋ค -
๋ชจ๋ ํด๋์ค๊ฐ ํ์ํ ๊ฒฝ์ฐ
๋ณต์กํ ์์กด์ฑ์ ์ฃผ๋ก ๋ค์๊ณผ ๊ฐ์ ํน์ง์ ๊ฐ์ต๋๋ค.
- ์ธ์คํด์ค ์์ฑ์ ํน๋ณํ ์กฐ๊ฑด์ด๋ ๋ก์ง์ด ํ์ํฉ๋๋ค.
- ์ค์ ๊ฐ, ํ๊ฒฝ ๊ฐ, ํ๋๊ทธ ๋ฑ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์์ฑ๋์ด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
- ํน์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ์ฌ๋ฌ ๊ตฌํ์ฒด ์ค์์ ํ๋๋ฅผ ์ ํํด์ผ ํ ๋๊ฐ ์์ต๋๋ค.
์์
kotlinCopy code @Module @InstallIn(SingletonComponent::class) object NetworkModule { @Provides fun provideApiService(@Named("apiUrl") apiUrl: String): ApiService { return Retrofit.Builder() .baseUrl(apiUrl) .addConverterFactory(GsonConverterFactory.create()) .build() .create(ApiService::class.java) } }
์์ ์์ ์์ **
ApiService
**์ ์์ฑ์ Retrofit ์ค์ ๊ณผ ํจ๊ป ํน์ URL์ ๊ธฐ๋ฐํ์ฌ ์ด๋ฃจ์ด์ง๊ธฐ ๋๋ฌธ์, ๋จ์ํ ์์ฑ์ ์ฃผ์ ๋ง์ผ๋ก๋ ์ฒ๋ฆฌํ๊ธฐ ์ด๋ ต์ต๋๋ค. ๋ฐ๋ผ์@Provides
์ด๋ ธํ ์ด์ ์ด ๋ถ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ **ApiService
**์ ์ธ์คํด์ค ์์ฑ ๋ฐฉ๋ฒ์ ์ง์ ํด์ผ ํฉ๋๋ค. -
๋จ์ํ ์์กด์ฑ์ Hilt๊ฐ ์ด๋ฏธ ์๊ณ ์๋ ํ์ ๋ค๋ง์ ์์ฑ์์ ํ๋ผ๋ฏธํฐ๋ก ์ฌ์ฉํ๋ฏ๋ก, ๊ทธ๋ฅ
@Inject
์ด๋ ธํ ์ด์ ์ ๋ถ์ฌ์ฃผ๋ฉด ๋ฉ๋๋ค. -
๋ณต์กํ ์์กด์ฑ์ ํน์ ํ ๋ก์ง์ด๋ ์ค์ ์ ๋ฐ๋ผ ๊ฐ์ฒด๊ฐ ์์ฑ๋์ด์ผ ํ ๋ ๋ฐ์ํ๋ฉฐ, ์ด๋ฐ ๊ฒฝ์ฐ์๋ ๋ชจ๋ ๋ด์
@Provides
๋ฉ์๋๋ฅผ ํตํด ์ธ์คํด์ค ์์ฑ ๋ฐฉ๋ฒ์ ์ง์ ํด์ค์ผ ํฉ๋๋ค.
-
-
์ด๋ค ๊ธฐ์ค์ผ๋ก ๋ชจ๋ ํด๋์ค๋ฅผ ๋๋ ์ผํ์ง?
- ๊ธฐ๋ฅ ๋ณ: ๊ฐ ๊ธฐ๋ฅ์ด๋ ํ๋ฉด(์: ๋ก๊ทธ์ธ, ์ฌ์ฉ์ ํ๋กํ, ์ฃผ๋ฌธ ๋ฑ)์ ๋ํด ๋ณ๋์ ๋ชจ๋๋ก ๋ถ๋ฆฌ
- ๊ณ์ธต ๋ณ: ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํคํ ์ฒ ๊ณ์ธต(์: ๋ฐ์ดํฐ, ๋๋ฉ์ธ, ํ๋ ์ ํ ์ด์ )์ ๋ฐ๋ผ ๋ชจ๋์ ๋ถ๋ฆฌ
-
๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ณ: ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ ํน์ ํ๋ ์์ํฌ์ ๊ด๋ จ๋ ์์กด์ฑ์ ์ ๊ณตํ๋ ๋ชจ๋์ ๋ง๋ญ๋๋ค.
์๋ฅผ ๋ค์ด, Retrofit ๊ด๋ จ ์์กด์ฑ์ ์ ๊ณตํ๋ **
NetworkModule
**์ด๋, Room ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ์์กด์ฑ์ ์ ๊ณตํ๋ **DatabaseModule
**์ ์๊ฐํด๋ณผ ์ ์์ต๋๋ค. -
์ค์ฝํ ๋ณ: ํน์ ์ค์ฝํ(์: ์ ํ๋ฆฌ์ผ์ด์
, ์กํฐ๋นํฐ, ํ๋๊ทธ๋จผํธ ๋ฑ)์ ๋ํ ์์กด์ฑ๋ง์ ์ ๊ณตํ๋ ๋ชจ๋์ ์์ฑํฉ๋๋ค.
SingletonModule
,ActivityModule
, **FragmentModule
**๊ณผ ๊ฐ์ ์ด๋ฆ์ผ๋ก ๋ค์ด๋ฐ ๋ ์ ์์ต๋๋ค. - ํ๊ฒฝ ๋ณ: ๊ฐ๋ฐ, ์คํ ์ด์ง, ํ๋ก๋์ ๊ณผ ๊ฐ์ ๋ค๋ฅธ ํ๊ฒฝ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ๋์ํด์ผ ํ๋ ์์กด์ฑ์ด ์๋ ๊ฒฝ์ฐ, ๊ฐ ํ๊ฒฝ์ ๋ง๋ ๋ชจ๋์ ๋ง๋ญ๋๋ค.
- ํ ์คํธ์ฉ ๋ชจ๋: ํ ์คํธ ์ ์ฌ์ฉํ๋ ์์กด์ฑ์ ์ ๊ณตํ๋ ๋ชจ๋์ ์์ฑํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ค์ ์ด์ ํ๊ฒฝ๊ณผ๋ ๋ค๋ฅธ ๋ชจ์(Mock) ๊ฐ์ฒด๋ ๊ฐ์ง(Fake) ๊ฐ์ฒด๋ฅผ ์ฃผ์ ํ ์ ์์ต๋๋ค.
@Module
@InstallIn(SingletonComponent::class)
object RepositoryModule {
@Provides
@Singleton
fun provideCarExteriorImageRepository(): CarExteriorImageRepository {
return CarExteriorImageRepository()
}
// ... ๊ธฐํ ์ ๊ณต ๋ฉ์๋ ...
}
ViewModel์์ ์์กด์ฑ ์ฃผ์ ํ๊ธฐ
class CarColorChoiceViewModel @Inject constructor(
private val imageRepository: CarExteriorImageRepository
) : ViewModel() {
// ... ๋๋จธ์ง ์ฝ๋๋ ๊ทธ๋๋ก ์ ์ง ...
}
Fragment์์ ๋ทฐ ๋ชจ๋ธ ์ฃผ์
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class CarColorChoiceFragment() : Fragment(), OnOtherColorItemClickListener {
private var _binding: FragmentCarColorChoiceBinding? = null
private val binding get() = _binding!!
// ViewModel ์ฃผ์
private val carColorChoiceViewModel by viewModels<CarColorChoiceViewModel>()
// ... ๋๋จธ์ง ์ฝ๋ ...
}
-
@Singleton:
- ์ด ์ฃผ์์ ํด๋น ์์กด์ฑ์ด ์ฑ๊ธํด์ผ๋ก ๋์ํด์ผ ํจ์ ๋ํ๋ ๋๋ค. ์ฆ, ํด๋น ๊ฐ์ฒด๋ ์ฑ์ ์๋ช ์ฃผ๊ธฐ ๋์ ํ๋๋ง ์์ฑ๋๋ฉฐ ์ฌ๋ฌ ๋ฒ ์์ฒญ๋์ด๋ ๋์ผํ ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด, ์ด๋ค ์๋น์ค๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ฐ์ ๊ฐ์ฒด๊ฐ ์ฑ ์ ์ฒด์์ ํ๋๋ง ์กด์ฌํด์ผ ํ ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋ฉ๋๋ค.
-
@Provides:
-
@Provides
์ฃผ์์ Hilt์๊ฒ ์ด๋ป๊ฒ ํน์ ํ์ ์ ์ธ์คํด์ค๋ฅผ ์ ๊ณตํด์ผ ํ๋์ง ์๋ ค์ค๋๋ค. ์ด ์ฃผ์์ด ๋ฌ๋ฆฐ ๋ฉ์๋๋ ํด๋น ํ์ ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ฐํํฉ๋๋ค. -
@Module
๋ด๋ถ์์ ์ฌ์ฉ๋๋ฉฐ, ํ์ํ ๋๋ง๋ค Hilt์ ์ํด ํธ์ถ๋์ด ํด๋น ํ์ ์ ์ธ์คํด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
-
-
@Module:
-
@Module
์ฃผ์์ ํด๋น ํด๋์ค๊ฐ Hilt ๋ชจ๋์์ ๋ํ๋ ๋๋ค. ๋ชจ๋์ ์์กด์ฑ ์ฃผ์ ์ ์ํด ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋ ๋ฉ์๋๋ค์ ์งํฉ์ ๋๋ค. - Hilt๋ ์ด ๋ชจ๋์ ์ฌ์ฉํ์ฌ ํ์ํ ์์กด์ฑ๋ค์ ์ด๋ป๊ฒ ์์ฑํ๊ณ ์ ๊ณตํด์ผ ํ๋์ง ์๊ฒ ๋ฉ๋๋ค.
-
-
@InstallIn:
-
@InstallIn
์ฃผ์์ ๋ชจ๋์ด ์ด๋ ์ปดํฌ๋ํธ์ ์ค์น๋์ด์ผ ํ๋์ง ์ง์ ํฉ๋๋ค. - ์๋ฅผ ๋ค์ด, **
@InstallIn(SingletonComponent::class)
**์ ํด๋น ๋ชจ๋์ด Singleton ์ค์ฝํ๋ฅผ ๊ฐ์ง ์ปดํฌ๋ํธ์ ์ค์น๋์ด์ผ ํจ์ ๋ํ๋ ๋๋ค. ๋ฐ๋ผ์ ์ด ๋ชจ๋์ ์๋@Provides
๋ฉ์๋๋ค์ด ์ ๊ณตํ๋ ์์กด์ฑ๋ค์ ์ฑ๊ธํด์ผ๋ก ๋์ํ ๊ฒ์ ๋๋ค.
-
-
@AndroidEntryPoint:
- Hilt๋ฅผ ์ฌ์ฉํ์ฌ Android ํด๋์ค์ ์์กด์ฑ์ ์ฃผ์ ํ๊ธฐ ์ํ ์ฃผ์์ ๋๋ค. ์ด ์ฃผ์์ Activity๋ Fragment์ ๊ฐ์ Android ์ปดํฌ๋ํธ์ ๋ถ์ด๋ฉด, Hilt๋ ๊ทธ ์ปดํฌ๋ํธ์ ํ์ํ ์์กด์ฑ์ ์๋์ผ๋ก ์ ๊ณตํฉ๋๋ค.
- ์๋ฅผ ๋ค๋ฉด, **
@AndroidEntryPoint
**๊ฐ ๋ถ์ Fragment์์๋ Hilt๊ฐ ํด๋น Fragment์ ํ์ํ ๊ฐ์ฒด๋ค์ ์์์ ์ฃผ์ ํด์ค๋๋ค.
Hilt๋ฅผ ์ฌ์ฉํ ์ข ์ ํญ๋ชฉ ์ฝ์ ย |ย Android ๊ฐ๋ฐ์ ย |ย Android Developers
Hilt๋ฅผ ์ฌ์ฉํ์ฌ ์๋๋ก์ด๋ MVVM ์ํคํ ์ณ ๊ตฌํํ๊ธฐ
๐ป [H6-CaArt] โDone is better than perfectโ ๐ป
- [์ต๊ทํ] Sentry ๋์ ๊ธฐ (feat. ๋ก๊ทธ ๊ด๋ฆฌ)
- [์ต๊ทํ] GPT3.5 ๋ชจ๋ธ์ ํ์ฉํด์ ์ถ์ฒ ๋ฌธ๊ตฌ ์์ฝํ๊ธฐ
- [์ต๊ทํ] ์คํ๋ง์์ OpenAI API ์ฑ๋ฅ ๊ฐ์ ๊ธฐ
- [๊ถ๋ฏผ์] CaArt CI/CD ๊ตฌ์ถ ๊ณผ์
- [๊ถ๋ฏผ์] ์ฑํ๋ฅ ๊ณ์ฐ ๋ก์ง ๊ฐ์ - Index tuning๊ณผ Batch processing
- [์ด์นํ] useReducer, useContext๋ฅผ ์ฌ์ฉํ ์ ์ญ ์ํ ๊ด๋ฆฌ with React, TS
- [์ด์นํ] ํ๋กํ ํ์ ํจํด์ด๋?
- [์ด์นํ] UX ๊ฐ์ ์ ์ํ ์ด๋ฏธ์ง ํ๋ฆฌ๋ก๋ฉ With Promise
- [์์ํ] ํ์ ์คํฌ๋ฆฝํธ ์ ๋ค๋ฆญ์ด๋?
- [๋ฐ์ธ์] Android์ Data Binding: DataBindingUtil vs Binding.inflate
- [๋ฐ์ธ์] DI, Hilt ๋ฝ๊ฐ๊ธฐ
- [๋ฐ์ธ์] Retrofit ๋์ ๊ธฐ
- [๋ฐ์ธ์] 360๋ Spin Image Touble Shooting
- [๊น์ ๋น] ์ปค์คํ ๋ค์ด์ผ๋ก๊ทธ ๊ตฌํ