برنامه نویسی Kotlin — ایجاد الگوهای طراحی اندروید با کاتلین

۱۸۸ بازدید
آخرین به‌روزرسانی: ۲۵ اردیبهشت ۱۴۰۲
زمان مطالعه: ۱۱ دقیقه
برنامه نویسی Kotlin — ایجاد الگوهای طراحی اندروید با کاتلین

جدای از ایجاد حس رضایت برای مشتری‌ها و کارکنان خود، شما باید رضایت و خشنودی یک شخص مهم دیگر را نیز مد نظر داشته باشید. این شخص کسی نیست جز «خود آینده‌ی شما». بگذارید بیشتر توضیح دهیم. فرض کنید شما کدی را نوشته‌اید و در آینده نیاز به بررسی دوباره آن دارید. مطمئناً سؤالات بسیار زیادی در مورد چرایی و چگونگی نحوه نوشتار کد خود خواهید داشت. شاید برخی، از روش قرار دادن کامنت در کد استفاده کنند اما این روش گاهی اوقات بسیار گیج‌کننده خواهد بود. رویکرد بهتر برای حل این مشکل، به کارگیری «الگوهای طراحی» متداول است.

در این مقاله، تعدادی الگوی طراحی متداول برای اندروید در هنگام استفاده از برنامه‌های توسعه نرم‌افزار را معرفی خواهیم کرد. الگوهای طراحی، راه‌حل‌هایی با قابلیت استفاده مجدد برای برطرف کردن مشکلات نرم‌افزاری متداول هستند. الگوهایی ارائه‌شده در این مقاله، به صورت یک فهرست جامع و قابل ارجاع نیستند. با این حال، می‌توان این الگوها را به عنوان مرجع کارآمد و نقطه شروعی برای تحقیقات آتی در نظر گرفت.

در این مقاله، فرض می‌شود که شما با مفاهیم پایه‌ای توسعه اندروید آشنا هستید. اگر هیچ پیش‌زمینه‌ای در مورد Kotlin و اندروید استودیو (Android Studio) ندارید، پیشنهاد می‌کنیم قبل از شروع، نگاهی به مقاله‌های «مقدمه‌ای بر برنامه‌نویسی اندروید با زبان کاتلین» و «مقدمه‌ای بر آموزش اندروید» بیندازید.

شروع کار با کاتلین

شاید در آینده نیاز داشته باشید بخش مشابه ای را در چند جای کد خود تغییر دهید. شما باید زمان کمی را به کار بررسی وابستگی‌های پیچیده پروژه خود اختصاص دهید. از این‌رو، پروژه شما باید تا حد ممکن قابل استفاده مجدد، خوانا و قابل تشخیص باشد. با در نظر گرفتن این اهداف، یک شی‌ء در کل پروژه بررسی می‌شود و در دسته‌بندی‌های زیر قرار می‌گیرد:

  • «الگوهای ایجادی» (Creational patterns): نحوه‌ای که شما اشیا را ایجاد می‌کنید.
  • «الگوهای ساختاری» (Structural patterns): نحوه‌ای که شما اشیا را کنار یکدیگر قرار می‌دهید.
  • «الگوهای رفتاری» (Behavioral patterns): نحوه‌ای که شما فعل‌وانفعالات یک شی‌ء را هماهنگ می‌کنید.

ممکن است شما پیش از این نیز از الگوهای طراحی استفاده کرده باشید (بدون آنکه نام آن را بدانید). در ادامه، الگوهای هر یک از دسته‌های زیر و چگونگی اعمال آن‌ها به اندروید را برای شما پوشش خواهیم داد:

الگوهای ایجادی:

  • سازنده (Builder)
  • تزریق وابستگی (Dependency Injection)
  • یگانه (Singleton)

الگوهای ساختاری:

  • آداپتور (Adapter)
  • نما (Facade)

الگوهای رفتاری:

  • فرمان (Command)
  • ناظر (Observer)
  • مدل-نما-کنترل‌گر (Model View Controller)
  • مدل-نما-مدل‌نما (Model View ViewModel)
  • معماری تمیز (Clean Architecture)

الگوهای ایجادی

«چگونه می‌توان در آینده، به یک شیء پیچیده بخصوص دسترسی داشت؟»

بهتر است پاسخ شما به سوال بالا، «کپی کردن و سپس وارد کردن همان کد، در زمان احتیاج به نمونه‌ای از آن» نباشد. به جای این کار، شما می‌توانید از الگوهای ایجادی برای ساخت آسان و چندباره شی‌ء مورد نظر خود استفاده کنید. در ادامه مثال‌هایی از انواع این الگو را معرفی می‌کنیم.

الگوی سازنده

فرض کنید، فهرستی از تمام مشخصات ساندویچ مورد علاقه خود، اعم از نان، محتویات و ادویه‌جات آن تهیه کرده‌اید و آن را به یک ساندویچ‌فروشی می‌برید. فروشنده، بر اساس سلیقه شما ساندویچ را برایتان حاضر می‌کند و هرکدام از آیتم‌های مورد نظر شما را در نظر می‌گیرد. در اینجا، شما کار ساختن ساندویچ را انجام نمی‌دهید اما با توجه به ذائقه خود، آن را سفارشی‌سازی می‌کنید.

کاری که الگوی سازنده انجام می‌دهد، مشابه مثال بالا است. این الگو، ساختار یک شی‌ء پیچیده (مانند ساندویچ) را از هم جدا می‌کند (مانند بریدن نان، چیدن خیارشور و گوجه درون آن و ...)؛ به این ترتیب، فرآیند ساخت مشابه، می‌تواند منجر به نتایج مختلف شود. در اندروید، هنگام استفاده از اشیایی مانند «AlertDialog.Builder»، الگوی سازنده ظاهر می‌شود:

AlertDialog.Builder(this)
  .setTitle("Metaphorical Sandwich Dialog")
  .setMessage("Metaphorical message to please use the spicy mustard.")
  .setNegativeButton("No thanks", { dialogInterface, i ->
    // "No thanks" button was clicked
  })
  .setPositiveButton("OK", { dialogInterface, i ->
    // "OK" button was clicked
  })
  .show()

این سازنده، مرحله‌به‌مرحله جلو رفته و به شما فقط اجازه مشخص کردن بخش‌هایی از «AlertDialog» را می‌دهد که برایتان اهمیت داشته باشد. اگر نگاهی به کدهای AlertDialog.Builder بیندازید؛ مشاهده خواهید کرد که تعداد کمی دستور برای ساخت یک هشدار در اندروید وجود دارد. بلوک کد بالا، هشدار زیر را ایجاد می‌کند:

با اتخاذ کردن مجموعه تصمیمات متفاوت، نتایج کاملاً متفاوتی به دست خواهد آمد.

الگوی تزریق وابستگی

الگوی تزریق وابستگی، چیزی شبیه به نقل مکان کردن به یک آپارتمان مبله است. هر چیزی که نیاز داشته باشید، حاضر و آماده خواهد بود. نیازی نیست منتظر رسیدن و چیدن وسایل خود یا به دنبال خرید لوازم جدید باشید.

در حوزه اصطلاحات نرم‌افزاری، در هنگام معرفی یک شی‌ء جدید، تمام موارد مورد نیاز آن شی‌ء توسط الگوی تزریق وابستگی فراهم می‌شود. در برنامه‌نویسی اندروید، ممکن است شما به یک سری اشیا پیچیده‌ی مشابه، مانند یک سرویس ارائه خدمات شبکه‌ای، یک نمایش‌دهنده تصویر یا یک شی SharedPreferences برای حافظه محلی، در محل‌های مختلف برنامه خود نیاز داشته باشید. شما می‌توانید اشیا را اصطلاحاً به درون فعالیت‌ها و قاب‌های خود «تزریق» کنید و سریعاً به آن‌ها دسترسی داشته باشید.

محبوب‌ترین فریم‌ورک تزریق وابستگی متن‌باز برای اندروید، «Dagger 2» است. این فریم‌ورک، با همکاری شرکت‌های گوگل (Google) و «اسکوئِر» (Square) توسعه یافته است. برای به کارگیری این الگو، باید یک کلاس را به همراه حاشیه‌نویسی «Module@»، ایجاد کرده و آن را با استفاده از متدهای «Provides@»، توسعه دهید.

@Module
class AppModule {
  @Provides fun provideSharedPreferences(app: Application): SharedPreferences {
    return app.getSharedPreferences("prefs", Context.MODE_PRIVATE)
  }
}

واحد یا ماژول (Module) بالا، تمام اشیا مورد نیاز را ایجاد و پیکربندی می‌کند. شما می‌توانید در اپلیکیشن‌های بزرگ‌تر، از چندین ماژول مجزا (جداشده توسط تابع) استفاده کنید. در مرحله بعد، به منظور فهرست کردن ماژول‌ها و کلاس‌هایی که قرار است تزریق در آن‌ها صورت گیرد، یک مؤلفه رابط (Interface) ایجاد کنید:

@Component(modules = arrayOf(AppModule::class))
interface AppComponent {
  // ...
}

مؤلفه‌ها، از جایی که وابستگی‌ها می‌آیند (ماژول‌ها) تا محلی که در آنجا قرار می‌گیرند (نقاط تزریق)، به هم متصل می‌شوند.

شما باید در انتها، از حاشیه‌نویسی «inject@» برای فراخوانی وابستگی در محل مورد نیاز خود استفاده کنید. بعد از ساخت شی‌ء مورد نظر، به منظور فراهم کردن مقداردهی اولیه غیر نال (non-nullable)، باید از کلمه کلیدی «lateinit» استفاده کنید.

@Inject lateinit var sharedPreferences: SharedPreferences

به عنوان مثال، شما می‌توانید این رویکرد در یک فعالیت (Activity) به کار گرفته و سپس بدون اینکه فعالیت شما از محل آمدن شی‌ء خبر داشته باشد، از حافظه محلی استفاده کنید. این توضیحات، به صورت یک بررسی اجمالی است اما برای کسب اطلاعات دقیق‌تر راجع به جزئیات اجرای الگوی تزریق وابستگی در dagger 2، به صفحه «اسناد Dagger» مراجع کنید.

الگوی یگانه

الگوی یگانه، مشخص می‌کند که تنها یک نمونه از یک کلاس با نقطه دسترسی سراسری باید وجود داشته باشد. داشتن تنها یک نمونه، هنگام مدل‌سازی اشیا واقعی عملکرد خوبی دارد. در زبان کاتلین (Kotlin)، برای تعریف یک الگوی یگانه، از کلمه کلیدی «object» می‌شود. درصورتی‌که در زبان‌های دیگر، نیاز به مشخص کردن یک نمونه استاتیک (static) وجود دارد.

object ExampleSingleton {
  fun exampleMethod() {
    // ...
  }
}

هنگامی‌که نیاز به دسترسی اعضای شی‌ء در یک الگوی یگانه باشد، باید آن شی‌ء را به صورت زیر فراخوانی کنید:

ExampleSingleton.exampleMethod()

در پس‌زمینه برنامه، شی‌ء کاتلین توسط یک محدوده استاتیک «INSTANCE» پشتیبانی می‌شود. از این‌رو، اگر بخواهید از یک شی‌ء کاتلین در کدهای جاوا استفاده کنید، باید فراخوانی را به شکل زیر تغییر دهید:

ExampleSingleton.INSTANCE.exampleMethod();

با استفاده از کلمه کلیدی object، مطمئن خواهید شد که در حال استفاده از نمونه یک مشابه از کلاس مد نظر خود در درون برنامه هستید.

الگوی یگانه، ساده‌ترین الگو برای یادگیری است. با این حال، امکان استفاده بیش‌ازحد و همچنین سوءاستفاده از آن نیز وجود دارد. از آنجایی که این الگو برای چندین شی‌ء قابل دسترس است، احتمال وقوع عوارض غیرقابل‌پیش‌بینی با امکان ردیابی دشوار در آن افزایش می‌یابد. این مسئله، دقیقه چیزی است که شما دوست ندارید در آینده با آن مواجه شوید. شاید سهولت در درک و یادگیری یک الگو، مسئله مهمی باشد اما باید توجه داشت که الگوهای دیگر ایمنی بالاتر و نگهداری راحت‌تری دارند.

الگوهای ساختاری

شاید برای شما هم پیش آمده باشد که هنگام باز کردن یک کلاس، نحوه عملکرد و قرار دادن اشیا مختلف در کنار یکدیگر را فراموش کنید. راه‌حل این مسئله، استفاده از الگوهای ساختاری برای سازمان‌دهی محتویات کلاس‌ها و اشیاء شما، در دسته‌بندی‌های مشخص با کارکردهای مشابه است. دو الگوی ساختاری رایج در برنامه‌نویسی اندروید، الگوی آداپتور و الگوی نما هستند.

الگوی آداپتور

«چگونه می‌توان عملکرد و نحوه قرارگیری کلاس‌ها در کنار یکدیگر را به خاطر سپرد؟»

در فیلم سینمایی «Apollo 13»، یک صحنه معروف وجود دارد که در آن، گروهی از مهندسین تلاش می‌کنند تا یک وسیله مکعبی شکل را درون یک استوانه توخالی قرار دهند. کاری که مهندسان سعی در انجام آن داشتند، مشابه کاری است که یک الگوی وفق دهنده یا آداپتور (Adaptor) انجام می‌دهد. این الگو از منظر مهندسی نرم‌افزار، امکان همکاری دو کلاس غیر سازگار را با تبدیل رابط یک کلاس به رابط دیگری فراهم می‌کند.

منطق تجاری اپلیکیشن خود را در نظر بگیرید. این منطق می‌تواند از نوع یک محصول (Product)، یک کاربر (User) یا حتی یک موجود فضایی با نام «Tribble» باشد (مانند مکعب در مثال ابتدای مقاله). درحالی‌که یکی از اشیا رایج در همه‌ی اپلیکیشن‌های اندرویدی، «RecyclerView» است (مانند استوانه توخالی). در چنین وضعیتی، می‌توانید از زیرکلاس «RecyclerView.Adapter» استفاده کرده و برای شروع کار باقی قسمت‌ها، متدهای مورد نیاز خود را پیاده‌سازی کنید:

class TribbleAdapter(private val tribbles: List<Tribble>) : RecyclerView.Adapter<TribbleViewHolder>() {
  override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): TribbleViewHolder {
    val inflater = LayoutInflater.from(viewGroup.context)
    val view = inflater.inflate(R.layout.row_tribble, viewGroup, false)
    return TribbleViewHolder(view)
  }

  override fun onBindViewHolder(viewHolder: TribbleViewHolder, i: Int) {
    viewHolder.bind(tribbles[i])
  }

  override fun getItemCount() = tribbles.size
}

RecyclerView، قادر به تشخیص ماهیت یک Tribble نیست؛ با این حال، کار آداپتور، در اختیار گرفتن داده‌ها و ارسال آن‌ها به دستور «bind» برای تصحیح «ViewHolder» است.

الگوی نما

الگوی نما، رابطی با سطح بالاتر را ارائه می‌کند که باعث استفاده راحت از دیگر رابط‌ها می‌شود. نمودار زیر، نحوه عملکرد این الگو را نشان می‌دهد:

اگر فعالیت شما به فهرستی از کتاب‌ها نیاز داشته باشد، باید بتواند چنین فهرستی را از یک شی‌ء درخواست کند؛ بدون اینکه نیازی به دانستن عملکردهای داخلی حافظه محلی، حافظه پنهان (Cache) و کلاینت رابط برنامه‌نویسی کاربردی (API Client) شما باشد. این کار، علاوه بر مختصر و مرتب نگه داشتن فعالیت‌ها و قطع کدها، باعث می‌شود که شما بتوانید در آینده، تغییرات مورد نیاز بر روی پیاده‌سازی API را بدون هیچ تأثیری بر فعالیت‌ها انجام دهید.

«Retrofit»، یک کتابخانه متن‌باز اندروید و محصول شرکت Square است که امکان پیاده‌سازی الگوی نما را برای شما فراهم می‌کند. برای مثال، به منظور فراهم کردن داده‌های API برای کلاس‌های کلاینت، شما یک رابط ایجاد می‌کنید:

interface BooksApi {
  @GET("books")
  fun listBooks(): Call<List<Book>>
}

کلاینت، برای دریافت فهرستی از اشیا «Book» در مرحله بازخوانی، به فراخوانی «()listBooks» نیاز دارد. این کار شما را قادر می‌سازد تا بدون تأثیرگذاری بر روی کلاینت، هر نوع سفارشی‌سازی دلخواهی را در پس‌زمینه کد خود ایجاد کنید. به عنوان مثال، شما می‌توانید یک «دی‌سریالازر» (Deserializer) نشانه‌گذاری شیء جاوا اسکریپت (JSON) سفارشی را بدون آن‌که فعالیت از آن اطلاعی داشته باشد، مشخص کنید:

val retrofit = Retrofit.Builder()
  .baseUrl("http://www.myexampleurl.com")
  .addConverterFactory(GsonConverterFactory.create())
  .build()

val api = retrofit.create<BooksApi>(BooksApi::class.java)

توجه کنید که «GsonConverterFactory» در پس‌زمینه برنامه، به عنوان یک JSON Deserializer عمل می‌کند. شما می‌توانید برای کنترل فرآیند ذخیره داده‌ها (Caching) و ثبت داده‌ها (Logging)، از کلمات کلیدی «Interceptor» و «OkHttpClient» در کتابخانه Retrofit استفاده کنید. در این صورت نیز، کلاینت از عملیاتی که انجام می‌شود، اطلاعی پیدا نمی‌کند.

هر چه میزان اطلاع داشتن اشیا از عملیات پس‌زمینه کمتر باشد، مدیریت تغییرات برنامه در آینده برای شما آسان‌تر می‌شود. این الگو می‌تواند در کدهای زیادی مورد استفاده قرار گیرد. Retrofit تنها یکی از سازوکارهای پیاده‌سازی این الگو است. شما می‌توانید گزینه‌های دیگری را نیز انتخاب کنید.

الگوهای رفتاری

الگوهای رفتاری، به شما اجازه می‌دهند، مسئولیت توابع مختلف اپلیکیشن را مشخص کنید. این کار، امکان شناسایی ساختار و معماری یک پروژه در آینده را برای شما فراهم می‌کند. این الگوها می‌توانند برای اهداف مختلفی مورد استفاده قرار گیرند. از مشخص کردن ارتباط بین دو شی‌ء تا توضیح کل معماری برنامه، به وسیله این الگوها قابل انجام است. در بسیاری از موارد، الگوهای رفتاری مختلف، در کنار یکدیگر در یک برنامه مورد استفاده قرار می‌گیرند.

الگوی فرمان

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

الگوی فرمان نیز، مانند مقال بالا عمل می‌کند. این الگو، به شما اجازه می‌دهد تا درخواست‌های خود را بدون این‌که از گیرنده اطلاعی داشته باشید، ارسال کنید. به این منظور، باید ابتدا درخواست خود را به صورت یک شی‌ء، کپسوله‌سازی (Encapsulation) و ارسال کنید. تصمیم‌گیری برای نحوه انجام درخواست شما، سازوکار کاملاً جداگانه‌ای خواهد داشت. کتابخانه «EventBus»، یک فریم‌ورک اندرویدی (Android Framework) محبوب است که از الگوی فرمان به صورت روند زیر پشتیبانی می‌کند:

«Event»، یک شی‌ء دستوری است که می‌تواند توسط ورودی کاربر، داده‌های سرور یا تقریباً هر چیزی در برنامه شما، فعال شود. شما می‌توانید از Event، برای ساخت زیرکلاس‌های مخصوص انتقال داده نیز استفاده کنید:

class MySpecificEvent { /* Additional fields if needed */ }

بعد از تعریف Event، نمونه‌ای از EventBus را به دست آورید و یک شی‌ء را به عنوان یک «Subscriber» ثبت کنید:

eventBus.register(this)

اکنون‌که شی‌ء تبدیل به یک Subscriber شد، نوع رویدادی که باید دریافت کند و کاری پس از دریافت رویداد باید انجام دهد را تعریف کنید:

fun onEvent(event: MySpecificEvent) {
  /* Do something */
}

در آخر، یکی از رویدادها را بر اساس معیار خود، ایجاد و ارسال کنید:

eventBus.post(event)

از آنجایی که تعداد زیادی از این نوع الگو در زمان اجرای برنامه کار می‌کنند، ممکن است در آینده، دنبال کردن رد این الگو برایتان مشکل باشد؛ مگر اینکه پوشش آزمون (Test Coverage) خوبی داشته باشید. با این حال، یک مجموعه کد با طراحی خوب، بین خوانایی و امکان بررسی کدها در آینده، تعادل برقرار می‌کند.

الگوی ناظر

الگوی ناظر، رابطه‌ی یک به چند بین اشیا را تعریف می‌کند. هنگامی یک شی‌ء تغییر وضعیت می‌دهد، تمام وابستگی‌های آن به صورت خودکار، اعلام و به‌روزرسانی می‌شوند.

این الگو، چندمنظوره است. شما می‌توانید برای اجرای عملیات در یک زمان نامشخص، مانند فراخوانی‌های API، از این الگو استفاده کنید. فریم‌ورک «RxAndroid» که با نام «Reactive Android» نیز شناخته می‌شود، امکان اجرای این الگو درون برنامه را برای شما فراهم خواهد کرد:

apiService.getData(someData)
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe (/* an Observer */)

به طور خلاصه، در ابتدا شما اشیا «Observable» را تعریف می‌کنید. این اشیا، مقادیر مختلف را منتشر می‌کنند. این مقادیر می‌توانند به صورت یکجا (مانند پخش پیوسته) یا در یک نرخ و مدت‌زمان مشخص انتشار یابند. اشیا «Subscriber»، این مقادیر را بررسی می‌کنند و به محض دریافت، به آن‌ها واکنش نشان می‌دهند. به عنوان مثال، هنگامی‌که یک API را فراخوانی می‌کنید، Subscriber، منتظر پاسخ سرور مانده و مطابق آن، عمل می‌کند.

الگوی مدل-نما-کنترل‌گر

الگوی مدل-نما-کنترل‌گر یا «MVC»، بیانگر الگوی معماری فعلی حاکم در چندین پلتفرم (Platform) است. تنظیم کردن پروژه‌های اندرویدی با استفاده از این روش، آسان است. نام این الگو، به سه کلاس مورد استفاده در آن اشاره دارد:

  • مدل: کلاس‌های داده‌ای. اگر در کد خود از اشیا «User» و «Product» استفاده می‌کنید، آن‌ها شرایط واقعی را «مدل» می‌کنند.
  • نما: کلاس‌های بصری. هر چیزی که کاربر می‌بیند، در محدوده این کلاس‌ها قرار دارد.
  • کنترلر: رابط بین دو دسته بالا. این کلاس‌ها، نما را به‌روزرسانی؛ ورودی‌های کاربر را دریافت؛ و تغییرات را بر روی مدل اعمال می‌کنند.

با تقسیم‌بندی کد به این سه دسته، بخش زیادی از مسیر جداسازی و امکان استفاده مجدد از کدها را طی خواهید کرد.

ممکن است در آینده نیاز به اضافه کردن یک صفحه جدید به برنامه باشد. اگر بخواهید به این منظور، فقط از داده‌های موجود در برنامه استفاده کنید، الگوی MVC، امکان استفاده آسان از مدل قبلی و تنها ایجاد تغییر در بخش دلخواه (مثلاً تغییر نماها) را برای شما فراهم می‌کند. علاوه بر این، ممکن است بخواهید در آینده، یک ویجت (Widget) را از صفحه اصلی برنامه به بخش جزئیات صفحه انتقال دهید. با استفاده از الگوی پیشنهادی و جداسازی منطق کدنویسی بخش نماها، این کار را برایتان ساده خواهد کرد.

به علاوه، اگر تا حد ممکن، منطق کدنویسی طراحی و منابع به فایل‌های XML اندروید انتقال دهید، لایه نمایش شما مرتب و منظم می‌شود. شاید بخواهید در برخی مواقع، طراحی‌های جدیدی را در کاتلین انجام دهید که در این صورت، جدا کردن عملیات طراحی از کلاس‌های فعالیت و قاب، می‌تواند کمک خوبی انجام این کار باشد. با گذشت زمان، متوجه می‌شوید که اتخاذ تصمیم‌های مرتبط با معماری برنامه با استفاده از MVC، حل مشکلات احتمالی را برایتان آسان‌تر می‌کند.

الگوی مدل-نما-نما-مدل

این نام گذاری تقریباً گیج‌کننده، معرف الگویی مشابه با MVC است و با نام «MVVM» شناخته می‌شود. بخش‌های مدل و نما، مانند الگوی قبلی هستند. بخش مدل نما، وظیفه اتصال بین لایه‌های نمایش و مدل را بر عهده دارد اما نحوه عملکرد آن، با عملکرد کنترلر تفاوت دارد. این بخش، دستورات را برای بخش نما، به نمایش درمی‌آورد و این بخش را به مدل متصل می‌کند. هنگامی‌که مدل به‌روزرسانی شود، نماهای مرتبط با آن نیز توسط داده‌های متصل، به‌روزرسانی می‌شوند. به همین ترتیب، هنگامی‌که کاربر با نما ارتباط برقرار می‌کند، داده‌های متصل شده در جهت برعکس عمل می‌کنند و مدل به طور خودکار به‌روزرسانی می‌شود. این الگوی واکنشی، بسیاری از کدهای ارتباطی را حذف می‌کند.

محبوبیت الگوی MVVM، در خال افزایش است اما هنوز هم یک افزونه تقریباً جدید در کتابخانه الگوها به حساب می‌آید. اخیراً گوگل، این الگو را به عنوان بخش از کتابخانه «Architecture Components» خود اضافه کرده است. اگر این الگو را زیر نظر داشته باشید، ممکن است در آینده بدردتان بخورد.

الگوی معماری تمیز

الگوی معماری تمیز، در جایگاه مفهومی بالاتری از الگوهای معماری MVC و MVVM قرار دارد. این الگو، معماری کلی اپلیکیشن را توصیف می‌کند. تعریف چگونگی برقراری ارتباط لایه‌های مختلف برنامه، از قبیل اشیا تجاری، موارد کاربرد، نمایش‌دهنده‌ها، ذخیره‌سازی داده‌ها و رابط کاربری با یکدیگر، از وظایف این الگو است. این الگو شباهت‌هایی با معماری شش‌ضلعی (Hexagonal architecture) و دیگر معماری‌های اپلیکیشن دارد. MVC و MVVM جزئی از معماری تمیز در لایه‌های بیرونی نمایش و رابط کاربری هستند.

سخن آخر

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

امیدواریم این مقاله، باعث ترغیب شما به یادگیری و استفاده از الگوهای طراحی نرم‌افزاری شده باشد. با ارسال نظرات خود، ما را در بهبود کیفیت مطالب یاری کنید.

#

بر اساس رای ۲ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
raywenderlich
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *