مهدی اسداله پور
مهدی اسداله پور
خواندن ۴ دقیقه·۶ ماه پیش

الگوی UDF در Jetpack Compose و راه حل برای استفاده آسان تر

سلام دوستان! امروز می‌خوایم با هم یه نگاهی بندازیم به یکی از الگوهای مهم به نام UDF یا همون Unidirectional Data Flow که در Jetpack Compose هم کاربرد داره. شاید اسمش به نظرتون پیچیده بیاد، ولی نگران نباشید، قدم به قدم با هم جلو می‌ریم و با مثال توضیح میدیم.

UDF چیه؟

اول از همه، بذارید ببینیم UDF اصلاً چی هست و چرا باید ازش استفاده کنیم. UDF یا همون جریان داده‌ی یک‌طرفه، یه الگوی معماریه که توش داده‌ها فقط در یک جهت جریان دارن. به زبون ساده‌تر، فانکشن های کامپوزی ما، state ها رو به فاکنشن های زیرین خودشون پاس میدن (در صورت نیاز و وجود داشتن child function) و اون child function ها event ها رو به فانکشن های بالایی خودشون بر میگردونن.

توی مثال بالا، ما یک parent داریم که یک state داره که به child خودش اونو پاس داده. و فانکشن فرزندش هم به ازای هر تغییر، به parent خودش اطلاع میده (onTextChange).

چرا UDF مهمه؟

در مثال بالا، اگر از UDF استفاده نمی‌کردیم و state رو داخل تابع فرزند تعریف می‌کردیم، دیگه تابع parent خبری از مقدار text نداشت. حالا اگر مقدار text در تابع parent برامون مهم باشه و نیازش داشته باشیم چی ؟؟؟ احتمالا به فکرتون میرسه که viewmodel رو به فانکشن پاس بدیم، اما آیا پاس دادن viewmodel به همه ی فانکشن ها کار خوبیست ؟ خیر!
نکته‌ی مهم دیگه اینه که با این کار قابلیت Reusability رو افزایش می‌دیم. اینطوری می‌تونیم یه تابع بنویسیم و توی جاهای مختلف ازش استفاده کنیم، مثل همه‌ی Custom Function هایی که شاید تا الان برای Button ها یا TextField هاتون نوشتید.


** ازینجا به بعد مقاله باید درباره Mvi هم اطلاعات داشته باشین. **

استفاده آسون تر از UDF

خب تا اینجا فهمیدیم چرا باید از UDF استفاده کنیم و شاید تا الان هم استفاده میکردین.
اما خیلی از فانکشن هایی که مینویسیم نیازی به قابلیت استفاده مجدد ندارن و صرفا مختص همون صفحه ای که داریم طراحی میکنیم هستن. آیا توی این موارد هم همه دیتا ها رو باید اینجوری هندل کنیم؟

عکس زیر رو نگاه کنید:

Mvi - Udf - Jetpack compose
Mvi - Udf - Jetpack compose

تقریبا میشه گفت که توی MVI با همچین چیزی سروکار داریم. یه data class برای نگهداری مقادیر لازم هر صفحه و یک seald class برای مدیریت کردن event هامون. در viewmodel هم احتمالا یک فانکشن دارین که با دریافت event، مقادیر data class رو آپدیت میکنه.
توی این سناریو فرض کنیم قراره که یک صفحه لاگین درست کنیم، پس ui شما تقریبا یه همچین چیزی میشه :

توی این مثال ما فقط دوتا متغیر داریم و به ازای اون دوتا ما مجبور شدیم دوتا تابع لامبدا بنویسیم تا بتونیم مقادیر جدید یوزرنیم و پسورد رو به viewmodel پاس بدیم:

onUsernameChange: (String) -> Unit,
onPasswordChange: (String) -> Unit

ولی برای صفحه هایی که خیلی مقادیر بیشتری دارن چطور؟ مثلا صفحه ثبت نام کاربر که ممکنه کلی پارامتر داشته باشه! و مجبور بشیم برای تک تک اونها لامبدا بنویسیم.
یا ممکنه عمق فانکشن های ما زیاد باشه. مثلا:

خب توی اینجا ما مجبوریم همه اون لامبدا ها رو برای هر فانکشن بنویسیم.

خب حالا این همه حرف زدم، راه حل چیه ؟

راه حل خیلی سادس با اضافه کردن یه خط کد:

typealias OnAction = (LoginUiEvent) -> Unit

خب حالا ازین به بعد به جای پاس دادن توابع لامبدای هر متغیر، OnAction رو به childها پاس میدیم و در اونجا مستقیما LoginUiEvent مدنظرمون رو به OnAction میدیم. ینی این شکلی:

حالا این typealias چیه؟

تو زبون کاتلین، typealias به ما اجازه می‌ده که برای یک نوع (type) موجود، یه نام جدید تعریف کنیم. این کار به ویژه وقتی مفیده که:

  1. اسم طولانی و پیچیده‌ای داریم و می‌خوایم اون رو کوتاه‌تر و ساده‌تر کنیم.
  2. برای بهبود خوانایی کد می‌خوایم یه نوع رو با نامی که مفهوم بهتری داره مشخص کنیم.

البته که میتونیم خود نوع رو ینی

(LoginUiEvent) -> Unit

رو هم به فانکشن هامون پاس بدیم ولی با typealias هم کدمون قشنگ تر میشه هم ساده تر.

فقط باید حواستون باشه که برای توابعی این کارو انجام بدین که مطمئن هستین جای دیگه نمیخواین ازش استفاده کنین. چون این شکلی Reusability اون فانکشن رو از دست میدین.

نتیجه گیری

همین! توی این مقاله با هم یاد گرفتیم که UDF چیه و چطوری می‌شه با استفاده ازش، کدهای خواناتر و بهتری بنویسیم. دیدیم که UDF چطور می‌تونه به ما کمک کنه تا داده‌هامون رو بهتر مدیریت کنیم و از پیچیدگی‌های غیرضروری جلوگیری کنیم. همچنین، فهمیدیم که توی پروژه‌های واقعی چطوری می‌تونیم راحت‌تر از UDF استفاده کنیم تا کدهای کمتری بنویسیم و کارمون رو ساده‌تر کنیم.

امیدوارم این آموزش براتون مفید بوده باشه و بتونید از این نکات توی پروژه‌هاتون استفاده کنید. اگر سوالی داشتید یا نکته‌ای براتون مبهم بود، حتماً بپرسید.


ارادت ✌🏻



لینک منبع قسمت دوم آموزش:

https://engineering.teknasyon.com/stop-passing-event-ui-action-callbacks-in-jetpack-compose-a4143621c365


jetpack composeudfstate hositingmvitypealias
برنامه نویس اندروید، کاتلین، جاوا و Jetpack Compose - از سال 97 برنامه نویسی اندروید رو شروع کردم و هنوز دارم یاد میگیرم...
شاید از این پست‌ها خوشتان بیاید