Dagger و koin بدون شک دو مورد از محبوبترین فریمورکهای تزریق وابستگی در اندروید هستند. هر دو این کتابخانهها یک هدف دارند و به نظر میرسد بسیار شبیه به همدیگر هستند، اما آنها در پشت صحنه دو کار کاملاً متفاوت را انجام میدهند.
اما در مورد Hilt چطور؟ Hilt کتابخانهای است که از Dagger به صورت داخلی استفاده میکند و فقط کاربرد آن را ساده میکند، بنابراین در اینجا هر چیزی که در مورد Dagger میگویم در مورد Hilt نیز صدق میکند.
در این مقاله قصد ندارم که به شما بگویم که از کدام یک از کتابخانهها استفاده کنید. در عوض میخوام به شما نشان دهم که آنها در پشت صحنه چه کاری انجام میدهند و چه تفاوتی با هم دارند و عواقب این تفاوتها بر روی برنامه شما چیست.
Dagger
اگر میخواهیم Dagger نمونهای از یک کلاس را ارائه دهد، تمام کاری که باید انجام دهیم این است که حاشیهنویس @Inject را به سازنده کلاس اضافه کنیم.
افزودن این حاشیهنویس باعث میشود Dagger در زمان ساخت این کلاس برای آن Factory ایجاد کند. در این حالت از آن جا که نام کلاس CompositeAdapter است برای آن یک کلاس به نام CompositeAdapter_Factory ایجاد میکند.
این کلاس شامل تمام اطلاعاتی است که برای ایجاد نمونه کلاس CompositeAdapter مورد نیاز است.
همانطور که میبینید متد get در پیاده سازی factory، نمونه جدید از کلاس CompositeAdapter را برمیگرداند. این درواقع متدی است که در رابط provider مشخص شده و این کلاس آن را پیاده سازی میکند. کلاسهای دیگر میتوانند از رابط provider برای بدست آوردن نمونهای از یک کلاس استفاده کنند.
اگر از Hilt به جای Dagger استفاده کنیم چه؟
در این مثال هیچ تفاوتی ایجاد نمیکند، Hilt کتابخانهای است که از Dagger در داخل خود استفاده میکند و کلاسی که به شما نشان دادهام توسط Dagger تولید میشود. اگر از Hilt استفاده میکنید، دو کلاس اضافی برای ما ایجاد میکند که استفاده از Dagger را برای ما ساده میکند و تعداد کد تکراری که باید بنویسیم را کاهش میدهد. اما قسمت اصلی ثابت میماند.
Koin
Koin رویکرد کاملاً متفاوتی نسبت به Dagger و البته همچنین با Hilt در مدیریت وابستگیها دارد. برای ثبت وابستگیها در koin از هیچ حاشیه نویسی استفاده نمیکنیم زیرا koin هیچ کدی تولید نمیکند. در عوض ما باید ماژولها و factoryهایی را فراهم کنیم که برای ایجاد نمونههایی از هر کلاس مورد نیاز در پروژه ما استفاده میشوند.
مرجع این factoryها توسط koin به کلاس InstanceRegistry اضافه میشود که شامل ارجاع به تمام factoryهایی است که ما نوشتیم.
نکته کلیدی در این map نام کامل یک کلاس یا نامی است که در صورت استفاده از named parameter ارائه میدهیم. مقدار آن، factory است که ما نوشتیم و برای ایجاد نمونهای از یک کلاس استفاده میشود.
تمام کاری که برای بدست آوردن وابستگی ما باید انجام بدهیم این است که، get() را فراخوانی کنیم (برای مثال در یک factory) یا با فراخوانی delegated property، by inject() در اکتیویتی یا فرگمنت، که فراخوانی را به صورت lazy در پشت صحنه انجام میدهد. متد get() به دنبال factory است که برای یک کلاس از نوع مشخص ثبت شده باشد و آن را تزریق کند.
عواقب آن چیست؟
واقعیت این است که Dagger برای ایجاد وابستگی کد تولید میکند اما koin این کار را نمیکند.
1- مدیریت خطا
از آن جا که Dagger یک فریمورک تزریق وابستگی در زمان کامپایل است، اگر فراموش کنیم که برخی از وابستگیها را ارائه دهیم، تقریباً بلافاصله از اشتباه خود مطلع خواهیم شد، زیرا ساخت پروژه ناموفق خواهد شد.
به عنوان مثال اگر فراموش کنیم که حاشیه نویس @Inject را به سازنده CompositeAdapter اضافه کنیم و بخواهیم آن را به فرگمنتی تزریق کنیم، با یک خطای مناسب در زمان ساخت که دقیقاً نشان میدهد چه اشتباهی رخ داده است مواجه میشویم.
در koin کاملاً متفاوت است. از آن جا که اگر فراموش کنیم factory را برای کلاس CompositeAdapter اضافه کنیم، هیچ کدی تولید نمیکند، برنامه ساخته میشود، اما هنگامی که یک نمونه از کلاس درخواست کنیم با خطای RuntimeException برنامه کرش میکند. این ممکن است در شروع برنامه اتفاق بیفتد، بنابراین ممکن است فوراً متوجه آن شویم، اما همچنین ممکن است بعداً در صفحههای بعدی یا هنگامی که کاربر اقدامی انجام میدهد اتفاق بیفتد.
2- تاثیر روی زمان ساخت
این که koin هیچ کدی تولید نمیکند، یک مزیت دارد: تاثیر بسیاز کمتری بر روی زمان ساخت ما دارد. Dagger برای اسکن کد و تولیده کلاسهای مناسب باید از پردازنده حاشیه نویس استفاده کند. که ممکن است مدتی طول بکشد و سرعت ساخت را کاهش دهد.
3- تاثیر بر عملکرد زمان اجرا
از طرف دیگر، از آن جا که koin در زمان اجرا وابستگیها را برطرف میکند، عملکرد آن در زمان اجرا کمی بدتر است.
چه قدر؟ برای برآورد تفاوت عملکرد میتوان این مخزن را بررسی کرد که در آن Rafa Vazquez عملکرد این دو کتابخانه را در دستگاههای مختلف اندازه گیری و مقایسه کرده است. دادههای این تست به روشی تهیه شده است که چندین سطح وابستگی را شبیه سازی میکند، بنابراین فقط یک برنامه ساده با 4 کلاس نیست.
همانطور که میبینید Dagger تقریباً هیچ تاثیری در عملکرد راه اندازی ندارد. از طرف دیگر در koin میبینیم که زمان زیادی برای راه اندازی طول میکشد. تزریق وابستگی در Dagger نیز کمی سریعتر از koin است.
خلاصه
همانطور که در ابتدای این مقاله گفتم، هدف من در این جا این نیست که به شما بگویم از کدام کتابخانه استفاده کنید. من از Koin و Dagger در دو پروژه متفاوت و نسبتاً بزرگ استفاده کردم. صادقانه بگویم من فکر میکنم تصمیم گیری برای انتخاب Koin یا Dagger اهمیت کمتری نسبت به هر چیزی دارد که به شما اجازه میدهد کدی را بنویسید که تمیز، ساده و آسان برای تست واحد باشد. و من فکر میکنم همه آن کتابخانهها: Koin، Dagger و Hilt این هدف را براورده میکنند.
همه آن کتابخانهها نقاط قوت خود را دارند و امیدوارم دانستن اینکه چگونه در پشت صحنه کار میکنند به شما کمک کند تا تصمیم بگیرید که کدام یک را برای شما بهترین است.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید