۲۳ شهریور، ۱۴۰۰

۴ روز پیش ١۵۰۰+ امتیاز
نویسنده @mahdiabbasian یک مقاله تازه به اسم معرفی معماری MVI بخش دوم نوشت.

بعد از مدت ها مشغله در کار و زندگی برگشتم با ادامه معماری MVI در خدمت دوستان پارس کلیکی هستم در بخش اول معرفی کوتاهی از بخش های مختلف این معماری داشتم و به صورت کوتاه اشاراتی داشتیم در این بخش قصد دارم پیاده سازی این معماری رو بهتون آموزش بدم:

لایه Model

در دیگر معماری ها Models به دید یک لایه نگهدارنده دیتا نگاه شده است در واقع Back کار بودند به مانند ارتباط دهنده API و دیتابیس، در معماری MVI علاوه بر این با ساخت یوآی به صورت state مواجه هستیم که دایمی هستند به طور مثال اگر مادل را به صورت یک دیتا کلاسی از Movie در نظر بگیریم:

data class Movie (
    var id: Long? = null,
    var countryProduct: String? = null,
    var rateImdb: String? = null,
    var categoryName: String? = null,
    var director: String? = null,
)

یکی از قابلیت های خیلی خوب که خیلی ازش استفاده میکنم استفاده از sealed class ها در تعریف state های مختلف هست برای نمونه در اینجا با توجه به دیتا کلاسی از Movie داریم چند حالت در DataState خود داریم:

sealed class MovieState {
  object LoadingState : MovieState()
  data class DataState(val data: List<Movie>) : MovieState()
  data class ErrorState(val data: String) : MovieState()
}

Views and Intents

مانند معماری MVP معماری MVI برای ویو یک interface در نظر می گیرد:

interface MainView {
    fun displayMoviesIntent()
    fun render(state: MovieState)
}

که توسط اکتیویتی یا فرگمنت implement می شود در واقع می توان گفت که ویو در MVI تمایل داره از intent استفاده کنه که به اکشن کاربر پاسخ بده در نهایت بر طبق state ها و اینترفیس حالت ها در اکتیویتی به شکل زیر خواهد بود:

class MainActivity : MainView {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
  }

  //implement interface
  override fun displayMoviesIntent() = button.clicks()

  //implement interface
  override fun render(state: MovieState) {
    when(state) {
      is MovieState.DataState -> renderDataState(state)
      is MovieState.LoadingState -> renderLoadingState()
      is MovieState.ErrorState -> renderErrorState(state)
    }
  private fun renderDataState(dataState: MovieState.DataState) {
      //Render movie list
  }
  private fun renderLoadingState() {
      //Render progress bar on screen
  }
  private fun renderErrorState(errorState: MovieState.ErrorState) {
      //Display error mesage
  }
  }

این آموزش ساده ای از معماری MVI بود تمامی موارد بالا براساس تلفیق با معماری دیگر مانند MVVM و Clean متفاوت خواهد بود به دلیل اینکه در این معماری ها لایه های مختلفی قرار داره اما اصل معماری به همین سادگی هستش.

۴ اسفند، ۱۳۹۹

۷ ماه پیش ١۵۰۰+ امتیاز
نویسنده @mahdiabbasian یک مقاله تازه به اسم معرفی معماری MVI بخش اول نوشت.

ضرورت توسعه این معماری

همانطور که می دانیم معماری ها در جهت هر چه بهتر سازماندهی کردن کدها و جهت نگهداری هر چه بهتر در زمان توسعه به وجود آمدند در این میان معماری جدید MVI با استفاده از Reactive Programming راهکار تازه ای ارایه کرده است، این معماری در اصل یک معماری برای Cycle.js در جاوا اسکریپت است که در اندروید هم پیاده سازی شده است همچنین در این معماری امکان استفاده از Rxjava و LiveData وجود دارد.

کلمات در این معماری مخفف Model-View-Intent هستند و اساس آن بر پایه Intent است این لایه نشان دهنده قصد یا تمایلی برای انجام عملی از طرف کاربر است یه این معنا که این لایه یک ویو دریافت می کند و می‌تواند Model را به حالت جدیدی ترجمه کند.

لایه Model

این لایه کار نگهداری پایگاه های داده، تمامی داده های مربوط به API ها پ غیره را برعهده دارد، همچنین در این معماری کار این لایه کمی متفاوت است به این صورت که خروجی از Intent می‌گیرد و بنا به حالت (State) که لازم است آن را برای کاربر نهایی تغییر می‌دهد.

لایه View

در نهایت در این لایه State های جدید باعث ایجاد تغییرات در View خواهند شد و نتیجه نهایی به کاربر نشان داده خواهد شد.

۱۰ بهمن، ۱۳۹۹

۸ ماه پیش ١۰۰+ امتیاز
@mahdiabbasian به گفتگوی استاندارد داکیومنت نویسی برای یک اپ جواب داد.

منم با نظر آقای امین موافق هستم و اینکه به نظر من باید دید که سطح اون مشاغل چطور هس اما چیزی که در بیشتر موارد اتفاق میوفته اینه که داکیومنت رو نمیخونن تا جایی که لازمشون نباشه اصلا چرا راه دور بریم یه جورایی خودمون هم همینطور هستیم چون باید نیاز ببینن تا برن سراغش در مورد دیزاین پترن ها به شدت موافقم چون این هاس که کد رو کلین نگه میداره و بهتر میکنه کار رو و اینکه کارفرماها هم به دولوپری که دیزاین پترن استفاده کرده باشه البته اگر فقط فهم مدیریتی نداشته باشه بیشتر بها میده ولی خب در نهایت بخام بگم اینجور کارها خیلی خوبه اما نه خیلی در ایران! البته استثنا هم وجود داره

۸ بهمن، ۱۳۹۹

۸ ماه پیش ١۵۰۰+ امتیاز
نویسنده @mahdiabbasian یک مقاله تازه به اسم پیاده سازی viewBinding به زبان ساده نوشت.

همانطور که احتمالا در جریان هستید یکی از مشکلات و دردسرهای دولوپرهای اندروید سر و کله زدن با خطایی به نام null pointer exception است در اصل ویو بایندینگ جهت هر چه کمتر کردن این خطا که همگی ما حداقل یکبار با آن روبه رو شده ایم توسط گوگل در جت پک قرار گرفت با استفاده از این روش خصوصا در معماری MVVM می‌توانیم با پدیده پرتکراری به نام findViewById در اپلیکیشن ها خداحافظی کنیم!

پیاده سازی ویوبایندینگ

برای فعال سازی این قابلیت کافیست در فایل build.gradle کد زیر را اضافه کنیم:

    viewBinding{
        enabled = true
    }

کارکرد این قابلیت به صورتی است که برای لایه های موجود در اپلیکیشن کلاسی معادل با آن میسازد که در هر جایی قابل استفاده است در اصل لایه توسط نرم افزار bind می شود

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

ActivityMainBinding mainBinding = 
ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(mainBinding.getRoot());
  }
}

همانطور که ملاحظه میکنید نمونه ای از لایه activity_main.xml ایجاد کردیم که توسط اون میتونیم به هر آی دی متصل بشیم و در اینجا نیازی به findViewById نیست همچنین در این کلاس متدی استاتیک به نام getRoot وجود دارد که روت لایه را برمیگرداند اگر به طور نمونه در این لایه یک تکست ویو داشته باشیم به کد زیر:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

       <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textViewMain"/>

</RelativeLayout>

در زمان پیاده سازی آن در اکتیویتی خواهیم داشت:

 mainBinding.textViewMain.setText("ParsClick");

و در فرگمنت ها خواهیم داشت:

@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
    mainbinding = FragmentMainBinding.inflate(inflater, container, false);
    View view = mainbinding.getRoot();
    return view;
}

به همین سادگی!

۲۳ دی، ۱۳۹۹

۸ ماه پیش ١۵۰۰+ امتیاز
نویسنده @mahdiabbasian یک مقاله تازه به اسم معرفی معماری MVVM نوشت.

ضرورت ایجاد معماری MVVM

همانطور که می‌دانید در پروژه‌های تجاری بزرگ آنچه بیش از هر چیز اهمیت دارد انعطاف پذیری در زمان توسعه است به طوری که تیم بتوانند به خوبی با یکدیگر کار کنند ایجاد این معماری توسط جان گوسمن و معرفی آن در جت پک گوگل پاسخی به بهبود هر چه بیشتر این نیاز بود.

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

حروف MVVM مخففModel، View، ViewModel هستند.

لایه Model

این لایه شامل تمامی موارد مرتبط با داده مانند Api ها، کلاس ها مانند Entitiy ها ، فایربیس و ... هست اما در این لایه شرایطی حاکم است به این مفهوم که این لایه از view و viewmodel بی اطلاع است یعنی استقلالی برای خود دارد.

لایه view

اکتیویتی‌ها، فرگمنت‌ها، لایه‌های ایکس ام ال همگی در این لایه قرار می گیرند نکته ای که در اینجا مهم است اینجاست که این لایه تمامی موارد لازم را به viewmodel ارسال می کند اما به طرز جذابی پاسخ را به طور مستقیم دریافت نمی‌کند همچنین این لایه می تواند تحت شرایطی که لازم باشد از viewmodel درخواست کند که پردازشی را صورت دهد و model را براساس آن بروزرسانی کند.

لایه viewmodel

این لایه واسطی بین دو لایه دیگر است کارکرد این لایه به این شکل است که داده های مورد نیاز را از model دریافت می‌کند و به view تحویل می‌دهد از جمله موارد مهم که در این لایه انجام می‌شود می توان به عملیات بایندینگ دیتا اشاره کرد اما از جمله نکات مهم در این لایه این است که وظایف inflate لایه ها و استارت اکتیویتی‌ها به عهده این لایه نیست و باید از ان اجتناب کرد.

در حال حاضر از دو روش viewBinding و Rxjava برای پیاده سازی این معماری استفاده می شود به طور خلاصه در viewBinding تمامی لایه ایکس ام ال تحت یک کلاس در اکتیویتی و فرگمنت قرار می‌گیرد و تمامی عملیات‌های لازم تحت این کلاس صورت می‌پذیرد همچنین در RXjava تمامی محتوای قابل نمایش تحت یک ترد جداگانه به یوزر (Observe) نمایش داده می‌شود.