برنامه نویسی 29 بازدید

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

بدین ترتیب ترجیح‌های شخصی افراد را به صورت داده‌های قابل اتکایی درمی‌آوریم. ما پس از اندکی تحقیق به 12 نکته رسیدیم که جنبه‌های اصلی انتخاب و استفاده از فناوری‌های مختلف را پوشش می‌دهد. این نکته‌ها شامل موارد زیر هستند:

  1. 🕹️ ویژگی‌ها
  2. 🐞 پایداری
  3. عملکرد
  4. 🎁 اکوسیستم پکیج
  5. 🌎 جامعه برنامه‌نویسان
  6. 👶 سهولت یادگیری
  7. 📖 مستندات
  8. 🔧 ابزارها
  9. 🏛️ سوابق
  10. 👫 تیم
  11. ⚖️ تطبیق‌پذیری
  12. 📈 مومنتوم

در ادامه اهمیت هر یک از عوامل فوق را بررسی می‌کنیم و یک جدول امتیازبندی ارائه می‌کنیم که امکان ارزیابی آن را فراهم می‌کند.

ویژگی‌ها

نخستین دلیلی که فرد یک فناوری را انتخاب می‌کند، کارهایی است که آن فناوری انجام می‌دهد. اما سؤال اصلی این است که اهمیت این عامل تا چه حد است؟ React احتمالاً محبوب‌ترین کتابخانه فرانت‌اند در حال حاضر است؛ اما شکایت عمده‌ای که در مورد آن می‌شود، این است که ویژگی‌های کافی ندارد و کارهایی مانند مسیریابی و مدیریت حالت را به کتابخانه‌های شخص ثالث مانند React-Router و Redux واگذار کرده است.

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

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

سیستم امتیازدهی

  • الف: ارائه مسائلی که قبلاً وجود نداشتند
  • ب: ایجاد امکان همان کارهای قدیمی؛ اما به روشی بهتر
  • ج: ارائه مواردی کمتر از راه‌حل‌های کنونی

پایداری

می‌توان یک فریمورک عالی و پر از ویژگی طراحی کرد؛ اما در صورتی که توسعه‌دهندگان روی این فریمورک به طور مداوم با خطاهای مختلف مواجه شوند، ارزش چندانی نخواهد داشت. به همین دلیل ابزارهای زیادی در اکوسیستم کنونی جاوا اسکریپت روی افزودن پایداری و امنیت تمرکز کرده‌اند. اگر به موفقیت‌های typescript و Flow و با حتی زبان‌هایی مانند Reason نگاه کنیم، متوجه این نکته می‌شویم. در سمت لایه داده، سیستم نوع GraphQL نیز برای حصول اطمینان از عملکرد روان همه چیز ارائه شده است.

سیستم امتیازدهی

  • الف: وجود باگ و issue کمتر، سهولت دیباگ و حل مشکلات.
  • ب: انتخاب یک فناوری که روی پایداری نرم‌افزار نقشی ندارد.
  • ج: باگ‌ها و issue های جدید، نتیجه مستقیم انتخاب این فناوری هستند.

عملکرد

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

در اکوسیستم جاوا اسکریپت، نمونه‌ای سریع‌تر از preactjs وجود ندارد. API آن مشابه React است و از این رو تلاش نمی‌کند که در زمینه قدرت با آن رقابت کند. بلکه با تمرکز روی سبک و سریع بودن در هزینه بارگذاری در قیاس با ری‌اکت، باعث می‌شود که چند میلی‌ثانیه صرفه‌جویی داشته باشید و عملکرد وب اپلیکیشن خود را بهبود دهید.

سیستم امتیازدهی

  • الف: بسته‌بندی سبک‌تر، سرعت بارگذاری بیشتر، یا بهبود عملکرد از جهات دیگر
  • ب: انتخاب این فناوری تأثیری روی عملکرد نرم‌افزار نخواهد داشت.
  • ج: انتخاب این فناوری موجب کندتر شدن قابل‌توجهی در اپلیکیشن می‌شود.

اکوسیستم پکیج

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

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

سیستم امتیازدهی

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

جامعه

عامل دیگری که باید هنگام انتخاب یک فناوری در نظر داشت، جامعه آن است. یک فوروم اختصاصی یا کانال اسلک (Slack) می‌تواند کمک زیادی هنگام مواجهه با issue ها بکند.

اسپکتروم (spectrum) یک واسطه در حال رشد و چیزی میان چت‌روم و فوروم‌های سنتی است.

همچنین داشتن یک ریپازیتوری موجود از پاسخ‌های Stack Overflow برای جستجو نیز مناسب است. البته صفحه کاملاً فعال issue های گیت‌هاب نیز یک ضرورت است.

سیستم امتیازدهی

  • الف: فوروم و/یا چت‌روم (Slack/Discord/ غیره) با فعالیت روزانه، issue‌های گیت‌هاب که به صورت روزانه رسیدگی می‌شوند. سؤالات Stack Overflow زیادی پاسخ داده شده‌اند.
  • ب: فوروم و/یا چت‌روم با فعالیت پراکنده
  • ج: هیچ جامعه‌ای به جز گیت‌هاب وجود ندارد.

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

سهولت یادگیری یک فناوری باعث می‌شود که توسعه‌دهندگان به آن کتابخانه یا فریمورک علاقه‌مند شوند. تصور بر است این که آسان بودن یادگیری یک فناوری باعث می‌شود افراد به راحتی از همه موانع عبور کنند، اما این امر چندان واقعیت ندارد. مفهوم کاملاً مرتبط (با این حال گاهی متضاد) سهولت «تبحر» است. Meteor زمانی که در ابتدای انتشار بود، یادگیری کاملاً آسانی، دست کم در قیاس با جایگزین‌های موجود داشت؛ اما الزام می‌کرد که کل استک را به یک باره بیاموزید و بدین ترتیب پیاده‌سازی آن برای پروژه‌های موجود به امری دشوار تبدیل می‌شد.

React نیز به خاطر سهولت یادگیری پایین مشهور است، چون برای توسعه‌دهندگانی که عادت دارند HTML را از جاوا اسکریپت جدا نگه دارند، استفاده از JSX می‌تواند دشوار باشد. از سوی دیگر Vue بدون این که شما را مجبور کند تا روش تفکرتان را در مورد کدنویسی فرانت‌اند تا حدود زیادی تغییر دهید، سهولت یادگیری بیشتری ارائه می‌کند.

سیستم امتیازدهی

  • الف: می‌توان در طی یک روز کار با آن را شروع کرد.
  • ب: در حدود یک هفته زمان برای شروع عملی کار با فریمورک مورد نیاز است.
  • ج: بیش از یک هفته زمان برای یادگیری اساس کار مورد نیاز است.

مستندات

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

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

مستدات vue به خوبی طراحی شده و به خوبی نیز نگهداری می‌شود.

این فرایند همچنین نیازمند پیش‌بینی issue های رایج، درک مدل ذهنی کاربر، و مهم‌تر از همه به روز نگه‌داشتن مستندات بر اساس همه چیزهایی است که در کد تغییر می‌یابند. همه این کارها در واقع از زمان کدنویسی توسعه‌دهندگان کاسته می‌شوند. با توجه به همه این عوامل می‌توان درک کرد که چرا مستندات خوب چیز واقعاً نادر و ارزشمندی محسوب می‌شوند.

سیستم امتیازدهی

  • الف: سایت اختصاصی برای مستندات، آموزش‌های ویدئویی، پروژه‌های نمونه، راهنماها، مستندات API و کد با نگهداری خوب.
  • ب: فایل Read Me اولیه و کد با نگهداری مناسب.
  • ج: Read Me کاملاً مختصر، تنها راه برای درک طرز کار کتابخانه، نگاه کردن به کد آن است.

ابزارها

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

Redux DevTools خود به تنهایی ارزش بررسی و ملاحظه را دارد.

بسیاری بر این باور هستند که یکی از مهم‌ترین عوامل موفقیت Redux، افزونه مرورگر Devtools شگفت‌انگیز آن است که امکان بصری‌سازی ذخیره‌سازی‌ها redux و اقدام‌های مختلف را به روشی کاربرپسند ارائه می‌کند. به طور مشابه پشتیبانی عالی VS Code از TypeScript موجب شده است که صاحبانش از آن استفاده کنند.

سیستم امتیازدهی

  • الف: دو یا چند افزونه مرورگر، افزونه‌هایی برای ویرایشگرهای متنی، ابزار CLI، سرویس‌های SaaS شخص ثالث اختصاصی.
  • ب: وجود یک افزونه مرورگر یا افزونه ویرایشگر متنی، ابزار CLI، سرویس‌های SaaS شخص ثالث اختصاصی.
  • ج: عدم وجود ابزارهای خارجی

ردگیری سوابق

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

بسیاری از داستان‌ها را به یاد می‌آوریم که یک فناوری با آب و تاب فراوان وارد بازار شده است و پس از چند صباحی توسعه‌دهندگان دوباره به سمت فناوری‌های قدیمی ‌مانند Rails یا PHP و غیره بازگشته‌اند.

Express: هنوز پس از سه سال در حال تقلا برای بقا است

به همین دلیل متوجه می‌شویم که هیچ چیز مهم‌تر از نگهداری سوابق نیست. Express یکی از بهترین مثال‌ها محسوب می‌شود. این فریمورک در ابتدا در سال 2010 منتشر شده است و با وجود سرعت حرکت بسیار سریع اکوسیستم جاوا اسکریپت همچنان فریمورک پیش‌فرض سرور Node.js محسوب می‌شود.

سیستم امتیازدهی

  • الف: بیش از 4 سال حضور داشته باشد و از سوی شرکت‌های بزرگ و مشاوران مشهور فناوری انتخاب شده باشد.
  • ب: به مدت 1 تا 4 سال از معرفی‌اش گذشته باشد و از سوی شرکت‌های اولیه و یا مشاوران در مقیاس کوچک انتخاب شده باشد.
  • ج: کمتر از یک سال سابقه داشته باشد و هیچ انتخاب عملی واقعی نداشته باشد.

تیم

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

زمانی که React برای نخستین بار معرفی شد، این واقعیت که فیسبوک در پشت آن قرار داشت، باعث شد که دست کم توسعه‌دهنده‌ها تلاش کنند آن را یک بار امتحان نمایند. سپس فیسبوک اقدام به انتشار Relay و GraphQL کرد و نشان داده موفقیت React اتفاقی نبوده است.

Google Open Source: بیش از 2000 پروژه در حوزه‌های دسکتاپ، موبایل و غیره.

نکته دیگر این است که شرکت‌های بزرگ‌تر منابع بیشتری برای سرمایه‌گذاری دارند. برای نمونه گوگل می‌تواند حتی پس از انتشار نسخه جدیدتری از Angular.js که با نسخه قبلی ناسازگار است به توسعه نسخه قدیمی ادامه دهد.

البته این مسئله بدان معنی نیست که افراد به تنهایی نمی‌توانند نوآوری‌های بزرگی داشته باشند. برای نمونه Vue.js هیچ ربطی به 99% از کتابخانه‌های متن-باز موجود نداشت.

سیستم امتیازدهی

  • الف: از سوی یک شرکت بزرگ و به وسیله تیم متن-باز اختصاصی نگهداری می‌شود.
  • ب: از سوی یک تیم با اندازه متوسط از مهندسان با ردگیری سوابق فردی خوب نگهداری می‌شود.
  • ج: توسعه‌دهنده منفرد که به طور مستقل کار می‌کند.

تطبیق‌پذیری

نکته مهمی که در مورد انتخاب کتابخانه‌های بسیار جدید وجود دارد، این است که معمولاً بسیار سریع تکامل می‌یابند. متأسفانه این می‌تواند یک عیب به شمار بیاید.

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

برای نمونه React Router زمانی که تصمیم گرفت API خود را بین نسخه‌های 3 و 4 به طور کامل تغییر دهد، با مشکلات زیادی مواجه شد. همین موضوع در مورد انگولار زمانی که از Angular.js به «just Angular» جدید تغییر یافت رخ داد.

به‌روزرسانی‌های مداوم زمانی که به تازگی پروژه جدیدی را آغاز کرده‌اید ممکن است سرگرم‌کننده و هیجان‌انگیز باشند؛ اما زمانی که اپلیکیشن راه‌اندازی شد و در محیط production مورد اجرا قرار گرفت، مطمئناً آخرین چیزی که می‌خواهید این است که هر بار که نسخه جدیدی از کتابخانه بیرون می‌آید، هفته‌های متوالی را به بازسازی و دیباگ کردن کد اختصاص دهید.

سیستم امتیازدهی

  • الف: به‌روزرسانی‌ها غالباً به صورت تطبیق‌پذیر با نسخه‌های قبلی هستند، منسوخ شدن روال‌ها یا توابع با هشدار قبلی صورت می‌گیرد و نسخه‌های ناسازگار قبلی به مدت دو سال یا بیشتر نگهداری می‌شوند.
  • ب: تغییرات ناسازگار رخ می‌دهند؛ اما به خوبی مستندسازی شده‌اند و به تدریج صورت می‌گیرند.
  • ج: به‌روزرسانی‌های مداوم که نیازمند بازسازی کد هستند، بدون راهنمایی مناسب صورت می‌گیرند.

مومنتوم

آخرین معیار ارزیابی فریمورک، مومنتوم است که البته اهمیت آن از موارد دیگر کمتر نیست. منظور از مومنتوم همان مد شدن است. ممکن است مد روز بودن از نظر برخی چیز بدی باشد و به معنی ظاهربینی در برابر توجه به ماهیت باشد؛ اما در همه این موارد چنین نیست.

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

JavaScript Rising Stars: پروژه‌ای است که رشد کتابخانه‌های محبوب جاوا اسکریپت را بررسی می‌کند.

البته این سکه، روی دیگری نیز دارد. هیاهوی زیاد و خیلی زودهنگام موجب می‌شود که کاربران بالقوه با نسخه کامل نشده‌ای مواجه شوند که کلی issue دارد و بدین ترتیب علاقه آن‌ها را از بین ببرد. ضرب‌المثل مشهوری هست که می‌گوید «شانس دو بار در یک خانه را نمی‌زند».

سیستم امتیازدهی

  • الف: هیاهوی زیاد، قرارگیری در صدر Hacker News، هزاران ستاره گیت‌هاب، سخنرانی در کنفرانس‌های بزرگ
  • ب: برانگیزی مقداری از علاقه‌مندی در زمان انتشار اولیه، صدها ستاره گیت‌هاب
  • ج: توسعه‌دهنده تنهایی که در گمنامی اقدام به کار می‌کند و به طور مکرر با خود زمزمه می‌کند «یک روز به همه نشان می‌دهم!»

چند عامل دیگر

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

  • مقیاس‌پذیری: این که یک فناوری چگونه می‌تواند در پروژه‌های بزرگ استفاده شود.
  • انتخاب شدن: چه کسانی در حال حاضر از این فناوری استفاده می‌کنند.
  • تطبیق‌پذیری: این فناوری با فنّاوری‌های موجود تا چه حد مطابقت دارد؟
  • جداشدن: در صورتی که بخواهیم استفاده از این فناوری را متوقف کنیم، رها کردن آن تا چه حد آسان خواهد بود؟

مطالعه موردی: کلاینت Apollo

سیستم امتیازدهی خودمان را با استفاده روی یک کتابخانه واقعی یعنی Apollo Client تست می‌کنیم.

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

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

ویژگی‌ها: ب

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

پایداری: ب

انتخاب آپولو و GraphQL امکان بررسی داده‌ها و ردگیری issue ها را تسهیل می‌کند.

عملکرد: ب

آپولو شامل ابزارهایی برای بهینه‌سازی بارگذاری داده‌ها است؛ اما در مجموع به هیچ ترتیبی، تأثیر بهبوددهنده‌ای روی عملکرد اپلیکیشن نشان نمی‌دهد.

اکوسیستم پکیج: الف

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

جامعه: ب

آپولو چت‌روم بسیار فعالی در اسلک دارد؛ اما برخی از سؤالات آن بی‌پاسخ می‌مانند و در واقع گرفتن پاسخ از اعضای تیم مرکزی که به شدت درگیر پروژه هستند، دشوار است.

سهولت یادگیری: ب

یادگیری همه مفاهیم آپولو به خصوص در صورتی که بخواهید همزمان GraphQL را نیز بیاموزید، می‌تواند یک چالش باشد.

مستندات: الف

مستندات خوب و کاملاً نگهداری شده‌ای برای چند فریمورک فرانت‌اند ارائه شده است و چند نمونه کد نیز عرضه گشته است.

ابزارها: الف

افزونه‌های مرورگر و پلتفرم متریک اختصاصی

ردگیری سوابق: ب

آپولو خودش نسبتاً جدید است، اما GraphQL نیز به طور کلی چنین خصوصیتی دارد.

تیم: الف

تیم بسیار مستعد و با بنیاد مناسب به همراه تجربه اجرای پروژه‌های متن – باز دیگر مانند meteor.

تطبیق‌پذیری: ب

از نسخه 1 به نسخه 2 یک به‌روزرسانی ناسازگار صورت گرفته است، اما در مجموع تطبیق‌پذیری مناسبی با نسخه‌های قبلی وجود دارد.

مومنتوم: ب

آپولو ممکن است هنوز نام آشنایی محسوب نشود؛ اما با وجود به راه افتادن Relay به یک بازیگر عمده در این حوزه تبدیل شده است.

امتیاز نهایی: الف

آپولو با کسب 29 امتیاز از 36 امتیاز کلی عملکرد بسیار خوبی داشته است. حتی اگر فکر کنیم که همیشه جای پیشرفت هست، اما درک این که چرا آپولو از سوی تیم‌های زیادی استفاده می‌شود کار سختی نیست. دلیل این مسئله ضرورت وجود روشی مطمئن برای کار با داده‌های GraphQL است.

سخن پایانی

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

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

اگر این نوشته مورد توجه شما قرار گرفته است، پیشنهاد می‌کنیم موارد زیر را نیز ملاحظه کنید:

==

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

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