Dagger 2 در اندروید (قسمت دوم) – راهنمای توسعه یافته
درحالتی که از موضوعات منفی که پیرامون Dagger همواره مطرح بودهاند، تأثیر نپذیرفتهاید و میخواهید از آن به کار گیری فرمائید؛ احتمالاً به سعی آن عنایت میدهید و می خواهید بیشترین بازدهی را از آن بگیرید. دراینصورت سفارش می کنیم این نوشتهعلمی را تا به طراحی اپلیکیشن در مشهد آخر پژوهش نمائید.
این نوشتهیعلمی در واقع نصیب دوم «Dagger 2 در اندروید (نصیب اولیه) — راهنمای توسعه یافته» میباشد. مقصود ما دراین نوشتهی علمی دیگر این وجود ندارد که دگر را بی آلایشخیس کنیم. دراین نوشته می خواهیم مطمئن شویم که از دگر به به عبارتی ترتیبی که انتظار میرود به کارگیری میکنیم. برای مثال این حالت در اکثر اوقات مفاد منتهی به افزایش عملکرد می گردد. نکته بهتر این میباشد که مواقعی که دراین راهنما ارائه می شوند به طور کاملً معمولی می باشند و مکان هیچ نگرانی وجود ندارد.
مواقعی که درین نوشتهعلمی ارائه خواهند شد را میاقتدار در فهرست پایین گردآوریبندی کرد:
از منطقهبندی غیرضروری اجتناب کرده و به دفعههای Reusable@ مداقه بدهید.
همواره کوشش نمائید از متدهای استاتیک استعمال نمائید.
چارچوب نرم افزار را به مکان ماژولی با «آرگومان تولیدکننده» (constructor argument)؛ از روش «کامپوننت ساز» (component builder) عرضه نمایید.
در آزمایشها تعلقها را به مکان اُورراید کردن (Overriding) ماژولها؛ از روش کامپوننت آزمایش سوئیچ فرمائید.
از دگر در آزمایشهای واحد کلاس مفرد استعمال نکنید، زیرا به آن نیازی ندارید.
حوزهبندی (Scoping)
منطقهبندی متغیرها امری پرهزینه میباشد و می بایست در شکل قابلیت از آن اجتناب کرد. به این خواسته نوبتهای سینگلتون می بایست بهتدریج و صرفا در مواقعی به کار گیری شوند که حقیقتاً ما یحتاج میباشند. این مفاد محصور به وضعیتهایی می باشند که ساختوساز یک شیء، بسیار پرهزینه میباشد یا این که یک شیء را میاقتدار به صورت مکرر تولید و حذف کرد.
کلیک فرمائید
ولی یک نوع لبه گذاری منطقه خاص به اسم Reusable@ وجود داراست که بایستی با آن آشنا باشید. این نوع منطقهبندی اصولاً به دگر اعلام مینماید که در صورتیکه از تعلق مجدداً به کارگیری یا این که آن را مجدداً تولید نماید، مشکلی نخواهد بود و براین اساس دگر امور را در پشت صحنه به نحو احسن اجرا میدهد.
به صورت خلاصه میقدرت بیان کرد که تمجید کلاسهای کاربردی بیوضعیت به طور Reusable@ ایده قابل قبولی به حساب میآید. ولی در حالتیکه تولید کردن آن ها پرهزینه باشد و بخواهید از تکرار این پروسه در مفاد دیگر اجتناب فرمائید، احتمالاً نمی خواهید که به عبارتی دفعه از آن تعلق را به اشتراک بگذارید و از این رو Reusable@ مورد قابل قبولی محسوب نمی شود. دراین مورد ها تعلق سوای حوزهبندی شایسته ترین مورد ممکن میباشد.
استاتیک
این یکی بی آلایشترین و دیدنیترین ارشادها به حساب میآید. شما بایستی اعتقاد و باور نتیجه ها فرمائید، متدهایی که ارائه میکنید استاتیک می باشند. تک تک ایده به همین آسانی میباشد.
هر ماژولی که متدهای Provides@ آن کلیه استاتیک باشند، در طی پیادهسازی به هیچ نوع نوبتای نیاز نخواهد داشت.
در صورتی ماژول شما تنهاً متدهای provide استاتیک داشته باشد، دگر هیچ وقت نیازی به دفعهسازی از آن نخواهد داشت و در صورتیکه نتوانید به جهت شرایط دار بودن ماژول این شغل را بکنید، می بایست این آیتم را یک توشه دیگر نظارت فرمائید.
پیشنهاد می گردد که ماژولها فاقد شرایط باشند، زیرا در غیر این شکل خوی آن ها غیر قابل پیشبینی خواهد بود. به علاوه، نوبتهای ماژول مجموعاَ بهتدریج اثر گذار می باشند.
این راهنما احتمالاً یکی هویداترین مواقعی میباشد که دراین نوشته مطرح کردهایم؛ ولی این قضیه در دنیای کاتلین پاره ای بغرنجخیس گردد، زیرا در آنجا نمیتوانید به آسانی مانند جاوا، یک روال استاتیک در یک کلاس داشته باشید. شما در کاتلین اصولاً دو آیتم در چنگ دارید، میتوانید از یک شیء companion به کار گیری نمائید و یا ماژول خویش را به یک object تبدیل کرده و متدهای provide را با JvmStatic@ لبهنویسی (annotate) فرمایید.
1@Module
2object YourModule {
3
4 @Provides @JvmStatic
5 fun provideThatDependency() = ThatDependency()
6}
خبر عالی این میباشد که در شکل استعمال از R8 میتوانید عملاً JvmStatic@ را کنار بگذارید، زیرا با استعمال از استاتیک سازی خویش این وظیفه را از ذمه شما بر می دارد.
چارچوب نرم افزار
یکی اولیه روند در هر نوع فعال سازی دگر، عرضه چارچوب نرم افزار تحت عنوان یک تعلق میباشد. این موقعیت احتمالاً مصادف با وقتی میباشد که اشخاص استارت به رسیدگی دگر تحت عنوان یک چیز تعجب آور و غامض مینمایند. حقیقت این میباشد کهاین یک موقعیت به طور کاملً خاص میباشد، زیرا ما میخواهیم بتوانیم یک نوبت از یک شیء را که بر ساخت و ساز آن کنترلی نداریم و با این حالا ارجاعی به آن در چنگ داریم را تزریق کنیم.
کلیک نمائید
برای حل این نقص، معمولاً این کد استعمال می گردد:
1@Singleton
2@Component(modules = [ApplicationModule::class, YourModule::class, ThatOtherModule::class])
3interface ApplicationComponent
4
5@Module
6class ApplicationModule(private val applicationContext: Context) {
7
8 @Provides fun provideApplicationContext(): Context = applicationContext
9}
10
11class YourApplication : Application() {
12
13 val component: ApplicationComponent by lazy {
14 DaggerApplicationComponent.builder()
15 .applicationModule(ApplicationModule(applicationContext))
16 .build()
17 }
18}
مشاهده بدون نقص کدها
در کد فوق یک ماژول ساخت و ساز میگردد که چارچوب نرم افزار را تحت عنوان یک آرگومان خالق اخذ مینماید و یک اسلوب provide ساخت و ساز میکنیم که آن را عرضه نماید. این موقعیت به نیکی شغل مینماید؛ البته به دنبال دیگر نمیتوانیم ماژول را تحت عنوان یک object در دست داشته باشیم، زیرا یک object نمیتواند پارامترهای تولیدکننده داشته باشد. بدین ترتیب در شرایطیکه بخواهیم متدهای provide را به طور استاتیک داشته باشیم، می بایست شیء companion را به طور annotated اضافه کنیم که وضعیت پلیدی داراست. ولی افزون بر آن، این دستور کار عملاً مغایر مستندات میباشد که درین مفاد به صراحت اعلام نموده است:
متدهای BindsInstance@ برای تایپ کردن یک Module@ بایستی بر آرگومانهای تولیدکننده ترجیح داده شوند و فورا آن مقادیر ارائه خواهد شد. در واقع شما می بایست موقعیت ذیل را داشته باشید:
1@Singleton
2@Component(modules = [YourModule::class, ThatOtherModule::class])
3interface ApplicationComponent {
4
5 @Component.Builder
6 interface Builder {
7 @BindsInstance fun applicationContext(applicationContext: Context): Builder
8 fun build(): ApplicationComponent
9 }
10}
11
12class YourApplication : Application() {
13
14 val component: ApplicationComponent by lazy {
15 DaggerApplicationComponent.builder()
16 .applicationContext(applicationContext)
17 .build()
18 }
19}
مشاهده بدون نقص کدها
ApplicationComponent فعلا اندکی بغرنجخیس گردیده است؛ ولی ما دیگر به یک ماژول با شرایط نیازی نداریم. اکثر اوقات اشخاص عملاً این کد را ترجیح می دهند، گرچه چندان خوب وجود ندارد. این زنجیره مقداردهی نخستین اینک مفهوم بیشتری یافته میباشد و کد تولید گردیده به خصوص دراین حالت بی آلایشخیس خواهد بود، چون با یک ماژول کمتر از دگر راز و عمل خواهد داشت.
Dagger 2 در اندروید (قسمت دوم) – راهنمای توسعه یافته
درحالتی که از موضوعات منفی که پیرامون Dagger همواره مطرح بودهاند، تأثیر نپذیرفتهاید و میخواهید از آن به کار گیری فرمائید؛ احتمالاً به سعی آن عنایت میدهید و می خواهید بیشترین بازدهی را از آن بگیرید. دراینصورت سفارش می کنیم این نوشتهعلمی را تا به طراحی اپلیکیشن در مشهد آخر پژوهش نمائید.
این نوشتهیعلمی در واقع نصیب دوم «Dagger 2 در اندروید (نصیب اولیه) — راهنمای توسعه یافته» میباشد. مقصود ما دراین نوشتهی علمی دیگر این وجود ندارد که دگر را بی آلایشخیس کنیم. دراین نوشته می خواهیم مطمئن شویم که از دگر به به عبارتی ترتیبی که انتظار میرود به کارگیری میکنیم. برای مثال این حالت در اکثر اوقات مفاد منتهی به افزایش عملکرد می گردد. نکته بهتر این میباشد که مواقعی که دراین راهنما ارائه می شوند به طور کاملً معمولی می باشند و مکان هیچ نگرانی وجود ندارد.
مواقعی که درین نوشتهعلمی ارائه خواهند شد را میاقتدار در فهرست پایین گردآوریبندی کرد:
از منطقهبندی غیرضروری اجتناب کرده و به دفعههای Reusable@ مداقه بدهید.
همواره کوشش نمائید از متدهای استاتیک استعمال نمائید.
چارچوب نرم افزار را به مکان ماژولی با «آرگومان تولیدکننده» (constructor argument)؛ از روش «کامپوننت ساز» (component builder) عرضه نمایید.
در آزمایشها تعلقها را به مکان اُورراید کردن (Overriding) ماژولها؛ از روش کامپوننت آزمایش سوئیچ فرمائید.
از دگر در آزمایشهای واحد کلاس مفرد استعمال نکنید، زیرا به آن نیازی ندارید.
حوزهبندی (Scoping)
منطقهبندی متغیرها امری پرهزینه میباشد و می بایست در شکل قابلیت از آن اجتناب کرد. به این خواسته نوبتهای سینگلتون می بایست بهتدریج و صرفا در مواقعی به کار گیری شوند که حقیقتاً ما یحتاج میباشند. این مفاد محصور به وضعیتهایی می باشند که ساختوساز یک شیء، بسیار پرهزینه میباشد یا این که یک شیء را میاقتدار به صورت مکرر تولید و حذف کرد.
کلیک فرمائید
ولی یک نوع لبه گذاری منطقه خاص به اسم Reusable@ وجود داراست که بایستی با آن آشنا باشید. این نوع منطقهبندی اصولاً به دگر اعلام مینماید که در صورتیکه از تعلق مجدداً به کارگیری یا این که آن را مجدداً تولید نماید، مشکلی نخواهد بود و براین اساس دگر امور را در پشت صحنه به نحو احسن اجرا میدهد.
به صورت خلاصه میقدرت بیان کرد که تمجید کلاسهای کاربردی بیوضعیت به طور Reusable@ ایده قابل قبولی به حساب میآید. ولی در حالتیکه تولید کردن آن ها پرهزینه باشد و بخواهید از تکرار این پروسه در مفاد دیگر اجتناب فرمائید، احتمالاً نمی خواهید که به عبارتی دفعه از آن تعلق را به اشتراک بگذارید و از این رو Reusable@ مورد قابل قبولی محسوب نمی شود. دراین مورد ها تعلق سوای حوزهبندی شایسته ترین مورد ممکن میباشد.
استاتیک
این یکی بی آلایشترین و دیدنیترین ارشادها به حساب میآید. شما بایستی اعتقاد و باور نتیجه ها فرمائید، متدهایی که ارائه میکنید استاتیک می باشند. تک تک ایده به همین آسانی میباشد.
هر ماژولی که متدهای Provides@ آن کلیه استاتیک باشند، در طی پیادهسازی به هیچ نوع نوبتای نیاز نخواهد داشت.
در صورتی ماژول شما تنهاً متدهای provide استاتیک داشته باشد، دگر هیچ وقت نیازی به دفعهسازی از آن نخواهد داشت و در صورتیکه نتوانید به جهت شرایط دار بودن ماژول این شغل را بکنید، می بایست این آیتم را یک توشه دیگر نظارت فرمائید.
پیشنهاد می گردد که ماژولها فاقد شرایط باشند، زیرا در غیر این شکل خوی آن ها غیر قابل پیشبینی خواهد بود. به علاوه، نوبتهای ماژول مجموعاَ بهتدریج اثر گذار می باشند.
این راهنما احتمالاً یکی هویداترین مواقعی میباشد که دراین نوشته مطرح کردهایم؛ ولی این قضیه در دنیای کاتلین پاره ای بغرنجخیس گردد، زیرا در آنجا نمیتوانید به آسانی مانند جاوا، یک روال استاتیک در یک کلاس داشته باشید. شما در کاتلین اصولاً دو آیتم در چنگ دارید، میتوانید از یک شیء companion به کار گیری نمائید و یا ماژول خویش را به یک object تبدیل کرده و متدهای provide را با JvmStatic@ لبهنویسی (annotate) فرمایید.
1@Module
2object YourModule {
3
4 @Provides @JvmStatic
5 fun provideThatDependency() = ThatDependency()
6}
خبر عالی این میباشد که در شکل استعمال از R8 میتوانید عملاً JvmStatic@ را کنار بگذارید، زیرا با استعمال از استاتیک سازی خویش این وظیفه را از ذمه شما بر می دارد.
چارچوب نرم افزار
یکی اولیه روند در هر نوع فعال سازی دگر، عرضه چارچوب نرم افزار تحت عنوان یک تعلق میباشد. این موقعیت احتمالاً مصادف با وقتی میباشد که اشخاص استارت به رسیدگی دگر تحت عنوان یک چیز تعجب آور و غامض مینمایند. حقیقت این میباشد کهاین یک موقعیت به طور کاملً خاص میباشد، زیرا ما میخواهیم بتوانیم یک نوبت از یک شیء را که بر ساخت و ساز آن کنترلی نداریم و با این حالا ارجاعی به آن در چنگ داریم را تزریق کنیم.
کلیک نمائید
برای حل این نقص، معمولاً این کد استعمال می گردد:
1@Singleton
2@Component(modules = [ApplicationModule::class, YourModule::class, ThatOtherModule::class])
3interface ApplicationComponent
4
5@Module
6class ApplicationModule(private val applicationContext: Context) {
7
8 @Provides fun provideApplicationContext(): Context = applicationContext
9}
10
11class YourApplication : Application() {
12
13 val component: ApplicationComponent by lazy {
14 DaggerApplicationComponent.builder()
15 .applicationModule(ApplicationModule(applicationContext))
16 .build()
17 }
18}
مشاهده بدون نقص کدها
در کد فوق یک ماژول ساخت و ساز میگردد که چارچوب نرم افزار را تحت عنوان یک آرگومان خالق اخذ مینماید و یک اسلوب provide ساخت و ساز میکنیم که آن را عرضه نماید. این موقعیت به نیکی شغل مینماید؛ البته به دنبال دیگر نمیتوانیم ماژول را تحت عنوان یک object در دست داشته باشیم، زیرا یک object نمیتواند پارامترهای تولیدکننده داشته باشد. بدین ترتیب در شرایطیکه بخواهیم متدهای provide را به طور استاتیک داشته باشیم، می بایست شیء companion را به طور annotated اضافه کنیم که وضعیت پلیدی داراست. ولی افزون بر آن، این دستور کار عملاً مغایر مستندات میباشد که درین مفاد به صراحت اعلام نموده است:
متدهای BindsInstance@ برای تایپ کردن یک Module@ بایستی بر آرگومانهای تولیدکننده ترجیح داده شوند و فورا آن مقادیر ارائه خواهد شد. در واقع شما می بایست موقعیت ذیل را داشته باشید:
1@Singleton
2@Component(modules = [YourModule::class, ThatOtherModule::class])
3interface ApplicationComponent {
4
5 @Component.Builder
6 interface Builder {
7 @BindsInstance fun applicationContext(applicationContext: Context): Builder
8 fun build(): ApplicationComponent
9 }
10}
11
12class YourApplication : Application() {
13
14 val component: ApplicationComponent by lazy {
15 DaggerApplicationComponent.builder()
16 .applicationContext(applicationContext)
17 .build()
18 }
19}
مشاهده بدون نقص کدها
ApplicationComponent فعلا اندکی بغرنجخیس گردیده است؛ ولی ما دیگر به یک ماژول با شرایط نیازی نداریم. اکثر اوقات اشخاص عملاً این کد را ترجیح می دهند، گرچه چندان خوب وجود ندارد. این زنجیره مقداردهی نخستین اینک مفهوم بیشتری یافته میباشد و کد تولید گردیده به خصوص دراین حالت بی آلایشخیس خواهد بود، چون با یک ماژول کمتر از دگر راز و عمل خواهد داشت.

راهکارهای کاهش CPC در کمپینها