تزریق تعلق در Koin – به لهجه معمولی
تزریق تعلق در Koin – به لهجه معمولی
فرض نمائید دو کلاس به اسمهای A و B داریم که کلاس A با استعمال از متدی در کلاس B به آن اشاره مینماید. این عملیات مستقیماً یک تعلق میان دو کلاس ساخت و ساز مینماید، زیرا قبل از آماده داخل شدن قابلیت استعمال از سیاق یک کلاس در کلاسهای دیگر مورد نیاز میباشد که دفعهای از آن کلاس ساختوساز گردد. در این باره مورد نیاز میباشد که کلاس A دفعهای از کلاس B را قبل از دسترسی به متدهای آن تولید کردهباشد. در یک پروژه بی آلایش، دفعهسازی از شی ها کاری میباشد که میقدرت به طور دستی اعمال بخشید، ولی در بعضا موردها ما یحتاج میباشد که شی ها به طور خود کار با به کار گیری از برای مثالً یک فریمورک نوبتسازی شوند. به این ترتیب جابجایی وظیفه ساختوساز یک شیء به شخص دیگر و به کار گیری بدون واسطه از تعلق به عبارتی تزریق تعلق طراحی اپلیکیشن در مشهد نامیده می گردد.
به کار گیری از تزریق تعلق چه اهمیتی دارااست؟
اصل پنجم S.O.L.I.D ذکر مینماید که یک کلاس می بایست به تجرید متعلق باشد و خیر کد طاقت فرسا. S.O.L.I.D مشتمل بر پنج اصل نرم افزارنویسی شیءگرا میباشد که از سوی Uncle Bob پیاده سازی گردیده است. مفهوم گفته فوق این میباشد که یک کلاس، نباید تعلقهای خویش را به طور استاتیک تنظیمات نماید؛ بلکه می بایست آنها را توسط کلاسهایی از فارغ خویش تنظیمات نماید.
با به کار گیری از این اصول، کد شما می تواند به طریق بی آلایشای آزمایش خواهد شد و وراثت در میان کلاسهای گوناگون آسودهخیس میگردد و کامپوننتهای نرم افزار «وصلت سست» (loose coupling) خواهند داشت که در نرم افزارنویسی نرم افزار نکته مهمی به حساب می آید.
Koin چیست؟
Koin (+) یک فریمورک تزریق تعلق اپلیکیشننویسی گردیده مدل برای توسعه و گسترشدهندگان کاتلین میباشد که مسئولیت نوبتسازی اشیای متعدد را در نرم افزار بر ذمه میگیرد.
کلیک فرمایید
به کار گیری از Koin در پروژههای اندروید
برای فهم بدون نقص طریق به کارگیری از Koin یک نرم افزار خرد اندرویدی میسازیم که فهرستی از یوزرها گیتهاب را که دراین نشانی (+) جانور میباشد اکران میدهد.
معماری نرم افزار ما به طور تصویر پایین خواهد بود. ما قصد نداریم از مقر داده SQLite استعمال کنیم و نرم افزار مستقیماً با دادههایی که از خدمت اینترنت میاید، فارغ از این که آنانرا در مقر داده محلی ذخیره نماید، تعامل خواهد کرد.
چنانچه به تصویر فوق اعتنا نمائید، می بینید که Activity مستقیماً با View-model تعامل می یابد که آن نیز به نوبه خویش مستقیماً با Repository تعامل داراست که مسئول گزینش منبع داده میباشد. در ارتباط این نمونه ریپازیتوری فقط یک منبع داراست.
چنان که در تصویر فوق می بینید، کامپوننتهای مهم نرم افزار ما به همپا تعلقهای بینشان معین گردیدهاند. Activity یک ارجاع به ViewModel داراست و آن نیز به نوبه خویش ارجاعی به Repository داراست که از retrofit برای بازیابی دادهها از سرور به کارگیری مینماید. در طی این راهنما با نحوه مدیر مؤثر این تعلقها از سوی Koin آشنا خواهیم شد.
قدم 1: اضافه کردن تعلقهای ما یحتاج در پوشه gradle
فولدر build.gradle
1// Retrofit
2implementation 'com.squareup.retrofit2:retrofit:2.6.0'
3implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
4
5// We will use it for loading the images
6implementation 'com.squareup.picasso:picasso:2.71828'
7
8// For ViewModel
9implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
10implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0"
11
12// Koin
13implementation "org.koin:koin-android:2.0.1"
14implementation 'org.koin:koin-androidx-viewmodel:2.0.1'
15implementation 'org.koin:koin-androidx-scope:2.0.1'
مشاهده بدون نقص کدها
قدم 2: ساخت کلاسی که مخاطب را روی گیتهاب اکران می دهد
به خواسته آسانی نرم افزار، فقط سه گزینه از داده ها استفاده کننده یعنی id، اسم کاربری و تصویر اورا ذخیره میکنیم:
پوشه User.kt
1data class GithubUser(
2 val id: Long,
3 val login: String,
4 val avatar_url: String
5)
قدم 3: ساخت و ساز کامپوننتهای نرم افزار
اینترفیسی که اینترنتخدمت را اکران می دهد:
فولدر GithubApi.kt
1interface GithubApi {
2
3 @GET("users")
4 fun getUsers(): Call>
5}
کلاس ریپازیتوری به طور پایین میباشد. یک پارامتر به اسم GithubApi داراست.
پوشه UserRepository.kt
1class UserRepository(private val api: GithubApi) {
2 fun getAllUsers() = api.getUsers()
3}
سبک نما یک نوبت از UserRepository را تحت عنوان پارامتر میگیرد:
پوشه UserViewModel.kt
1class UserViewModel(private val repo: UserRepository) : ViewModel(), Callback> {
2
3 private val _loadingState = MutableLiveData()
4 val loadingState: LiveData
5 get() = _loadingState
6
7 private val _data = MutableLiveData>()
8 val data: LiveData>
9 get() = _data
10
11 init {
12 fetchData()
13 }
14
15 private fun fetchData() {
16 _loadingState.postValue(LoadingState.LOADING)
17 repo.getAllUsers().enqueue(this)
18 }
19
20 override fun onFailure(call: Call>, t: Throwable) {
21 _loadingState.postValue(LoadingState.error(t.message))
22 }
23
24 override fun onResponse(call: Call>, response: Response>) {
25 if (response.isSuccessful) {
26 _data.postValue(response.body())
27 _loadingState.postValue(LoadingState.LOADED)
28 } else {
29 _loadingState.postValue(LoadingState.error(response.errorBody().toString()))
30 }
31 }
32}
مشاهده بی نقص کدها
نکته: ما از کلاس کمکی به کار گیری کردیم تا بتوانیم موقعیت بار گذاری را رئیس کنیم.
فولدر LoadingState.kt
1data class LoadingState private constructor(val status: Status, val msg: String? = null) {
2 companion object {
3 val LOADED = LoadingState(Status.SUCCESS)
4 val LOADING = LoadingState(Status.RUNNING)
5 fun error(msg: String?) = LoadingState(Status.FAILED, msg)
6 }
7
8 enum class Status {
9 RUNNING,
10 SUCCESS,
11 FAILED
12 }
13}