<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Ali Shobeyri</title>
        <link>https://virgool.io/feed/@shobeyri.ali</link>
        <description>برنامه نویس اندروید - https://www.linkedin.com/in/iryebohs/</description>
        <language>fa</language>
        <pubDate>2026-06-07 23:26:26</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/4343/avatar/V3Kv9T.png?height=120&amp;width=120</url>
            <title>Ali Shobeyri</title>
            <link>https://virgool.io/@shobeyri.ali</link>
        </image>

                    <item>
                <title>پارادایم‌های برنامه‌نویسی</title>
                <link>https://virgool.io/@shobeyri.ali/%D9%BE%D8%A7%D8%B1%D8%A7%D8%AF%D8%A7%DB%8C%D9%85-%D9%87%D8%A7%DB%8C-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-fkzanngyhzri</link>
                <description>این مقاله ترجمه مقاله دیگری از من در Medium هستآیا تا حالا در مورد «declarative programming» یا «imperative programming» شنیدید ؟ احتمالا تا حالا تو کدهاتون از این نوع استایل‌های برنامه نویسی استفاده کردید بدون اینکه حتی اسمشونو می‌دونستید !!!حتی اگه تا حالا این در این موارد چیزی نشنیده باشید احتمالا از اونا استفاده کردید بدون اینکه تا حالا در موردشون چیزی شنیده باشید. اما اگر شنیدید تا حالا فکر کردید که اینا چی هستن ؟پارادایم های برنامه نویسی چی هستندپارادایم‌های برنامه نویسی یک سری قاعده و متدولوژی هایی هستند که ساختار و پیاده‌سازی برنامه شما رو مشخص می‌کنند. همینطوری ما می‌تونیم زبان های ‌برنامه نویسی رو بر اساس این قواعد دسته بندی کنیم.به طور کلی دو نوع عاقده داریم :Imperative (دستوری)Declarative (اعلامی یا اخباری)Imperative programming در مقابل Declarative programmingدر برنامه‌نویسی به روش Imperative ما به مراحل مورد نیاز برای انجام یک کار اهمیت می‌دیم و در مقابل در برنامه‌نویسی Declarative ما به نتیجه نهایی بدون اهمیت دادن به مراحل مورد نیاز توجه می‌کنیمبه این دو کد  که با کاتلین نوشته شده‌اند نگاه کنید ، می‌خوایم مجموع اعداد زوج درون یک آرایه رو به این دو شیوه حساب کنیم : https://gist.github.com/sasssass/09e9d95256a7a6e3c4e6049c4c62c331  https://gist.github.com/sasssass/13935b3a083ffdc6ecb61caac6e462a2 اولی به شیوه Imperative و دومی به شیوه Declarative نوشته شده . ما در کد اول برای محاسبه مقدار جمع اعداد زوج تمامی مراحل رو برای سیتسم شرح دادیم ولی در کد دوم بیشتر سعی کردیم از توابع خود کاتلین استفاده کنیم (و نمی‌دونیم پیاده سازی اونا چطوریه) و بیشتر به خروجی کار توجه داشتیم تا مراحل تولید اون خروجی !به طور کلی اگه بخوام بگم Imperative روی چطور تمرکز داره و declarative روی چی !به عنوان مثال اگه زبان SQL رو در نظر بگیرید این زبان یک زبان Declarative محسوب میشه ، چرا ؟ چون ما صرفا می‌گیم از فلان table بهمان row هایی رو با بیسار ویژگی به من نشون بده ! ما فقط به سیستم می‌گیم چی می‌خوایم و به SQL توضیحی نمی‌دیم که این مقادیر رو چطور باید برای ما محاسبه کنه !Imperative Paradigmsما انواع مختلفی از این نوع پارادایم (روش) ها داریم اما سه تای معروف اون این موارد هستند :ProceduralObject-Oriented Programming (OOP)StructuredProcedural Programmingما در برنامه نویسی procedural یک مجموعه ای از procedure ها (روش ها) داریم که در واقع همون توابع ما می‌تونن باشند و هر کدوم وظیفه معنی رو انجام می‌دن و برای رسیدن به خروجی مورد نظر باید یک سلسله از این روش‌ها رو پشت سر هم انجام بدیم .زبان‌های زیادی هستند که می‌تونن از این نوع باشند مثل سی، جاوا، پاسکال و ... ولی اینجا یک مثال از پاسکال برای شما می‌زنم . دلیل اون هم اینه که در پاسکال ما علاوه بر تابع (function) یک رویه‌ (procedure) هم داریم تو پاسکال فرق این دو تا اینه که procedure خروجی نداره ولی function داره ! فرض کنید همون برنامه بالا رو برای محاسبه جمع اعداد زوج بخوایم بنویسیم : https://gist.github.com/sasssass/130db72b2098ecf21fdca863ab99ca33 همون طور که می‌بینید در برنامه نویسی procedural در پاسکال ما یک procedure به اسم CalculateSumOfEvenNumbers تعریف کردیم و برای رسیدن به خروجی مورد نظر اون رو اجرا می‌کنیم (چون برنامه ساده است فقط یک procedure داریم)مسلما تا حالا صد تا کد به این روش زدید و فقط اسمشو نمی‌دونستید :)Structured Programmingتو برنامه نویسی Structured ما به یک ساختمار منظم از control flow اهمیت می‌دیم .می‌تونیم این برنامه نویسی رو در سه اصل خلاصه کنیم :سلسله مراتب : کد از بالا به پایین بر اساس یک سلسله مراتب به اجرا در میادانتخاب : همون شرایط کنترلی ما مثل if/else هستندحلقه : حلقه‌های for و while و do while و ... که باعث می‌شن یک کد رو صد بار ننویسیمدر این پاردایم ما سعی می‌کنیم مساله رو به مسایل کوچک تر تقسیم کنیم ، خیلی از زبان‌ها هستند که تو این پارادایم رو شامل می‌شن مثل سی ، جاوا ، کاتلین و ... (همون زبان‌های لیست قبل مثلا)سوالی که الان پیش میاد اینه که تفاوت procedural و structured چیه ؟ به نظر یکی میان ! مساله بیشتر اینه که برنامه نویسی structured در واقع نوعی برنامه نویسی procedural هست که از قابلیت‌های بیشتری بهره می‌بره ، ما در برنامه نویسی structured بیشتر به ماژولار کردن و استفاده از control flow های پیشرفته اهمیت می‌دیم .بیایید برنامه محاسبه فاکتوریل رو در زبان کاتلین به این دو شیوه کنار هم داشته باشیم : https://gist.github.com/sasssass/cceec4c15b1256b73c1b08131e62a651 همون طور که می‌بینید در تابع اول ما یک حلقه while داریم که با کمک اون فاکتوریل رو محاسبه می‌کنیم و تو تابع دوم از control flow های بیشتری استفاده کردیم . اگر عدد صفر یا یک باشه نیازی نیست که حلقه رو بررسی کنیم و مستقیم خروجی رو یک بر می‌گردونیم . همون طور خروجی رو مستقیم return می‌کنیم و مقدار خروجی رو تو یه متغیر نمی‌ریزیم تا دوباره اون رو return کنیم (ساختار یافته تر کد می‌زنیم)کل مبحث رو می‌تونم تو این عکس خلاصه کنم :به نظر من تفاوت این دو پاردایم در واقع صفر و یکی نیست بلکه یک طیفه ، ما می‌تونیم بیشتر کد رو ساختار یافته بنویسیم و اون رو structured در نظر بگیریم و کمتر procedural !Object-Oriented Programming (OOP)بعضی از زبان‌های برنامه نویسی مثل C از تایپی به نام structure پشتیبانی می‌کنند و بعضی از تایپی به نام class/object . تفاوت این دو در اینه که در structure ما یک مجموعه متغیر رو تحت عنوان یک ساختار جدید در نظر می‌گیریم ولی در object ما علاوه بر این مجموعه متغیر (ویژگی‌ها) یک سری توابع (رفتار‌ها) رو هم اضافه می‌کنیم .در مورد ما اشیا موجود در دنیای واقعی رو مدل سازی می‌کنیم . مثلا کلاس «پرنده» یک نوع داره (کلاغ، قناری و ...) و یک سری تابع داره (پرواز کردن و راه رفتن) و خود پرنده نوعی «حیوان»  هست که این کلاس «حیوان» دیگه تابع پرواز رو نداره و فقط راه رفتن رو داره .به این مدل از برنامه نویسی ، برنامه نویسی شی گرا می‌گن و بر ۴ رکن استواره :وراثت یا inheritance : یک پرنده یک نوع حیوان هست ، ما می‌تونیم دو شی داشته باشیم و رابطه والد و فرزند بین اون‌ها برقرار کنیم ، کلاس فرزند همه‌ی ویژگی‌ها و رفتار‌های کلاس والد رو به ارث می‌بره (و می‌تونه اونا رو تغییر یا اصلاح کنه) و همینطور می‌تونه ویژگی‌ها و رفتار‌های اضافه و خاص خودش رو داشته باشهچندریختی یا polymorphism : برای یک رفتار می‌تونیم چنین پیاده سازی داشته باشیم . این پیاده سازی ها به دو نوع داینامیک (run-time) و استاتیک (compile-time) تقسیم بندی می‌شن ، مثلا ما می‌تونیم دو تابع با یک اسم یکسان و ورودی‌های مختلف داشته باشیم (استاتیک) یا می‌تونیم یک تابع رو که در کلاس والد بوده در کلاس فرزند override کنیم (داینامیک) https://gist.github.com/sasssass/73b99f6bba3feec6650a11cf37d2071a در مثالی که می‌بینید ما یک شی از جنس والد داریم اما اون رو با نوع فرزند مقدار دهی می‌کنیم و چندریختی موجود نوع داینامیک هست و دلیل اون اینه که سیستم در حین اجرا تصمیم می‌گیره از کدوم تابع استفاده کنه (که اینجا از تابع کلاس فرزند استفاده خواهد کرد) . https://gist.github.com/sasssass/e714e527f135f8f1ccc761f88a974644 در این یکی مثال نوع چندریختی از جنس استاتیک هست چون سیستم در زمان compile به این نتیجه خواهد رسید که از در وقتی به خط شماره ۱۳ یا ۱۴ رسید از کدوم تابع باید استفاده کنه .کپسوله سازی یا encapsulation :پنهان کردن اطلاعات و مشخصه‌های یک شی از یک شی دیگه و محدود کردن دسترسی به این مشخصه‌ها به جز با توابع خاص (مثلا getter و setter) https://gist.github.com/sasssass/2051e95cc73525ad23a6d19326a73457 دلیلی که برای این کار داریم در این مثال به خوبی نمایان هست ، ما نمی‌خوایم متغیر number مقادیر منفی داشته باشه پس این محدودیت رو در setter ایجاد کردیم ، همین طور شاید بخوایم وقتی کسی به number دسترسی پیدا می‌کنه یک کار اضافه (مثل log کردن یا ...) انجام بشهانتزاع یا abstraction :انتزاع در واقع مربوط به وراثت هست ، بعضی وقتا ما می‌خوایم پیچیدگی رو در اشیا کمتر کنیم ، مثلا به مثلا پرنده بر‌می‌گردیم ، هر پرنده یک نوع حیوان هست و در این انتزاع حیوان یک سری مشخصه‌ها و رفتار‌ها تعبیه شده (مثل راه رفتن) و دیگه لزومی نداره در کلاس پرنده پیاده سازی اون‌ها رو تکرار کنیم (مگر اینکه به دلیلی بخوایم override انجام بدیم) و همچین یک سری رفتارهای انتزاعی مثل غذا خوردن (که می‌تونه برای پرنده دونه باشه و برای شیر گوشت) رو داریم که در کلاس والد صرفا تعریف اون‌ها رو میاریم و کلاس فرزند رو مجبور می‌کنیم که پیاده سازی متناسب خودش رو برای اون تابع انجام بده . کلاس حیوان تو این مثال یک کلاس انتزاعی میشه پس ما هیچوقت نمی‌تونیم یک شی از حیوان داشته بشیم که با خود کلاس حیوان مقداردهی بشه ، بلکه می‌تونیم یک شی از کلاس حیوان داشته باشیم که با کلاس پرنده مقداردهی بشه . https://gist.github.com/sasssass/c925d87bf91f745dbe022d031757cddb Declarative programmingما انواع مختلفی از برنامه نویسی Declarative داریم ولی ۳ تای معروف اون این موارد هستند :Functional ProgrammingReacting ProgrammingLogic ProgrammingFunctional Programmingدر برنامه نویسی functional ما به توابع ریاضی اهمیت می‌دیم (مثل f(x) = y) و المان های کلیدی مثل این دو مورد رو داریم تغییر ناپذیری :‌ ورودی یک تابع هیچگاه تغییر نمی‌کنه و از متغیر‌های global هم استفاده نباید بکنیم. برای ساخت ورودی جدید باید خروجی یک تابع رو به داخل تابع دیگه پاس بدیم.برنامه نویسی بازگشتی : از حلقه استفاده نمی‌کنیم و به جاش از توابع بازگشتی استفاده می‌کنیم ، اگه این مورد رو کنار تغییر ناپذیری بذارید می‌بینید که منطقی به نظر میاد . ما نمی‌خوایم متغیری مثل sum داشته باشیم که مرتبا تغییرش بدیم بلکه این sum رو می‌تونیم از راه بازگشتی حساب کنیم https://gist.github.com/sasssass/259082d81329a0463f2c23b9b88e8dc8 اینجا یک مثال به زبان کاتلین داریم که همون برنامه محاسبه جمع اعداد زوج هست و از توابع بازگشتی استفاده کردیم .باید مراقب باشید کی و کجا از تابع بازگشتی استفاده کنید چون این نوع توابع می‌تونن مقدار زیادی حافظه رو مصرف کنند و برنامه شما رو به سمت crash سوق بدن :)توابع با اولیت بالاتر : شما می‌تونید یک تابع رو به عنوان ورودی یک تابع دیگه پاس بدید ، f(y) = z + 2 و y = x²Reacting Programmingبرنامه نویسی reactive بیشتر به eventها و جریان داده asynchronous (این لغات بهتره هیچوقت ترجمه نشن) اهمیت میده . هر زمان یک event داشته باشیم ، یک جریان داده جدید هم داریم و به این تغییرات واکنش یا react می‌کنیم .این نوع برنامه نویسی بر اساس دیزان پترن observable ساخته میشه . ما یک سری observable داریم که یک جریان داده رو انتشار یا emit می‌کنند و یک سری observer داریم که این observableها رو subscribe می‌کنند تا بتونن نتیجه رو پردازش کنند .همه چیز به صورت asynchronous اتفاق میفته ، یعنی ما میتونیم چندین observable داشته باشیم و این observable ها همدیگه رو block نمی‌کنند .معمولا وقتی از این شیوه استفاده می‌کنیم از ابزار reactive extension بهره می‌بریم که مجموعه کاملی از توابع کمکی رو در اختیار ما قرار می‌دن و برای انواع زبان هم library دارن . مثلا یک توسعه دهنده جاوا از RxJava و یک توسعه دهنده ++C از RxCpp استفاده می‌کنه .در واقع Rx مجموعه ای از extensionها و انواع مختلفی از observable رو برای استفاده ما قرار می‌ده که ترکیبی از برنامه نویسی reacting و functional به حساب میاد ، ما میتونیم چندین extension رو برای تغییر داده‌هامون استفاده کنیم (مثل فیلتر یا ترکیب داده‌ها و ...)به عنوان مثال کد زیر برای محاسبه مجموع اعداد زوج با این روش و با استفاده از Rx نوشته شده : https://gist.github.com/sasssass/debdb1086d9f94e126aa65df60f651d8 Logic Programmingبرنامه نویسی logic بر اساس formal logic صورت می‌گیره ولی این formal logic چی هست ؟ ما به طور کلی formal logic و informal logic داریم . در formal logic ما یک سری سمبل و در informal logic از زبان انسان استفاده می‌کنیم (فارسی و انگلیسی و ...) ، در formal logic ما قواعد مشخصی داریم که در نهایت ما رو به یکی از دو گزاره true یا false هدایت می‌کنند ولی در informal logic ما به کیفیت اهمیت می‌دیم نه درستی و غلطی !مثلا اگه از شما بپرسن هوا امروز سرده شما در informal logic می‌تونی بگی یکم سرده یا خیلی سرده ولی در formal logic هوا یا سرد هست یا سرد نیست ! در واقع همون منطق بولی !ما در برنامه نویسی به شیوه logic قواعد و گزاره‌های مطلق و الگوهایی رو داریم و خروجی رو بر اساس اونا بدست میاریم. معروفی ترین زبان برنامه نویسی به این روش Prolog هست . یک مثال با هم ببینیم : https://gist.github.com/sasssass/8f62fa42a15d5ee4226766797d06e3a7 توی این مثال ما یک سری گزاره داریم ، john والد mary هست ، john والد lisa هست و الی آخر . یک سری گزاره دیگر هم داریم که john مرد هست ، mary زن هست و ... . حالا یک سری قوانین داریم که اگر شخصی والد شخص دیگه ای بود و مرد بود پس اون father به حساب میاد و اگر شخصی والد شخص دیگه ای بود ود زن بود اون شخص mother به حساب میاد .مثلا اگر father(john, mary) به سیستم داده بشه خروجی true هست .آدرس کانال تلگرامی ما : لینکمن رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Tue, 24 Oct 2023 12:26:22 +0330</pubDate>
            </item>
                    <item>
                <title>Delegation in Kotlin</title>
                <link>https://virgool.io/@shobeyri.ali/delegation-in-kotlin-ym3dycluzkyo</link>
                <description>یکی از ویژگی‌های مهم کاتلین پیاده سازی آسان Delegation هست، منتها قبل از اون باید ببینیم اصلا Delegation چی هست !لغت Delegation در انگلیسی به معنی &quot;نمایندگی&quot; هست و Delegate یعنی نماینده یا نمایندگی/وکالت دادن، الگوی Delegation در زبان‌های برنامه نویسی به صورت کلی به این صورت هست که یک سری وظایف رو در کلاس A به کلاس نماینده ای به اسم B بذاریم، به نظرم این به نوعی به قاعده اول اصول SOLID یعنی Single Responsibility هم می‌تونه ربط پیدا کنه (چرا؟) و مانع تولید یک God class بزرگ بشه .ما برای اینکار می‌تونیم از Delegation هم استفاده نکنیم و به جاش از وراثت استفاده کنیم، یعنی یک سری وظایف base تر رو به کلاس والد ببریم، منتها باید بدونیم که چه زمانی از کدوم یک از این مفاهیم استفاده کنیم، زمانی که این وظیفه امکان داره بعدا در کلاس‌های دیگه تکرار بشه یا به هر دلیلی نمی‌خوایم اون وظیفه در کلاس های دیگه (فرزند) override بشن یا کلاس والد final باشه بهتره از Delegation استفاده کنیم، برای استفاده از وراثت بهتره فقط زمانی اینکار صورت بگیره که واقعا یک رابطه &quot;کلاس A یک نوع از کلاس B هست&quot; وجود داشته باشه (تو رفرنس های انگلیسی این رو is-a میگن) .مثلا فرض کنید یک کلاس Shape داریم که قراره یک سری کارا توش انجام بشه و در کنار اون کارا مساحت اون Shape هم حساب بشه، اینجا می‌تونیم یک کلاس AreaCalculator ایجاد کنیم که وظیفه محاسبه مساحت رو داره و یک Instance از این کلاس در Shape داشته باشیم که این کار رو انجام بده، به همین راحتی ! به این مفهوم میگن Delegation .یک نکته دیگه هم که ما مفهومی به اسم Composition هم داریم که در لغت به معنی &quot;ترکیب&quot; هست، این مفهوم در واقع جمله &quot;کلاس A یک کلاس B را دارد&quot; هست که در رفرنس های انگلیسی به اون &quot;has-a&quot; میگن،  به نظر می‌رسه که Delegation مفهوم یکسانی با Composition داشته باشه ، نه ؟ در واقع Composition به رابطه بین اشیا با هم می‌پردازه در حالی که Delegation به سپردن کار اشیا به هم می‌پردازه و یکی از کاربردهای Composition ایجاد یک Delegation هست، مثلا فرض کنید یک کلاس به اسم House داریم که با استفاده از CompostionComposition یک کلاس به اسم Room رو داخل خودش داره، آیا اینجا Delegation داریم؟ نه ! Room چه وظیفه ای از House رو می‌خواد انجام بده ؟ اما فرض کنید داخل همین کلاس House یک کلاس AlarmManager داریم که وظیفه دادن هشدار خطر به پلیس رو در شرایط خاصی داره، اینجا ما Delegation داریم چون یک وظیفه که بر عهده House بوده رو به کلاس AlaramManager دادیم که در واقع این AlaramManager خودش با House یک رابطه Composition هم داره !خب حالا یک مثال ساده از قضیه ببینیم که در کاتلین چطوری باید Delegation رو پیاده کنیم :صورت مساله : یک کلاس مستطیل داریم که می‌خوایم مساحتش رو حساب کنیم، خیلی ساده !راه حل با استفاده از ارث بری :این راه حل برای این مساله مورد قبول ما نیست چون ماهیت محاسبه مساحت به کلاس نباید ربطی داشته باشه و ما می‌تونیم به راحتی از Delegation استفاده کنیم !راه حل مقدماتی با Delegation : در اینجا یک Interface به اسم AreaCalculator داریم که در Shape به صورت Delegation استفاده شده، این راه حل به نظر راه حل مناسبی میاد، اما برای جاوا !!!! در کاتلین به صورت فوق العاده راحت تری این کار رو میشه کرد .راه حل کامل :خب به این کد نگاه کنیم، یک interface به اسم AreaCalculator داریم که Shape باهاش implement شده، اما از اونجایی که Shape خودش abstract هست پس نیازی نیست متد area رو override کنه، فعلا از by صرف نظر می‌کنیم، حالا در کلاس Rectangle ما حتما باید area رو پیاده سازی کنیم چون این کلاس از Shape ارث برده و ما هم area رو اونجا پیاده سازی نکردیم، ولی اگه ببینید ما حتی در Rectangle هم اینکار رو نکردیم !!! پس area از کجا داره میاد ؟ اینجا اپراتور by به کمک ما میاد ، فرمول کلی قضیه by به این صورته :ما در هنگامی که از کلاس Bahman یک شی می‌سازیم Folan_Imp مورد نظرمون رو که از جنس Folan هست (از اون Implement شده) بهش می‌دیم و حالا با استفاده از by دیگه نیازی نیست خودمون دستی متد های Folan رو پیاده کنیم، بلکه کلاس Bahman میاد متدهای مورد نظر رو از Folan_Imp میگیره !!!!حالا شما می‌تونی یک جا به Bahman یک Folan_Imp بدی و یک جای دیگه Folan_Imp_2 رو بدی !!! بسته به نیازی که در اون موقع داری !در مثال مستطیل هم تابع area در واقع از AreaCalculator_Rectangle داره گرفته میشه !نکته : ما همچنان می‌تونیم خودمون area رو در Rectangle به صورت override پیاده سازی کنیم و مشکلی هم نداره، اما وقتی این کار رو بکنیم چی میشه ؟ وقتی area رو صدا بزنیم میاد از متد override شده در داخل Rectangle استفاده می‌کنه یا از داخل AreaCalculator_Rectangle ؟ جواب اینکه میاد اونی که داخل Rectangle هست رو استفاده می‌کنه، مثالی که بالا زدم بسیار ساده بود ، در خیلی از مواقع مسلما interface ما متدهای بیشتری داره و شاید ما نیاز داشته باشیم بعضی از متدهاش رو تغییر بدیم و می‌تونیم اونایی که نیازه رو داخل خود کلاسی که داره عمیلات Delegation رو به عهده یه کلاس دیگه می‌ذاره override کنیم !پیشنهاد می‌کنیم سورس این مطلب رو از خود سایت کاتلین هم بخونید، اونجا مثال ساده تری زده ولی در مورد مفهوم Delegation توضیح خاصی نداده و یک رفرنس به ویکیپدیا داده .آدرس کانال تلگرامی ما : لینکمن رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Mon, 15 Aug 2022 13:57:58 +0430</pubDate>
            </item>
                    <item>
                <title>الگورتیم اعداد Float</title>
                <link>https://virgool.io/@shobeyri.ali/%D8%A7%D9%84%DA%AF%D9%88%D8%B1%D8%AA%DB%8C%D9%85-%D8%A7%D8%B9%D8%AF%D8%A7%D8%AF-float-gmldn1fiscvj</link>
                <description>کامپیوتر برای محاسبه مقدار اعداد سیستم متفاوتی نسبت به ما داره، اجداد ما از مبنای ده برای شمارش استفاده می‌کردند (به دلیل اینکه 10 انگشت داریم) و به طور کلی این عدد یک عدد خاص در فرهنگ های مختلف به حساب میاد، مثلا موسی 10 قانون از سمت خداوند به مردم ابلاغ کرد یا ... ، اما کامپیوتر که بر مبنای عدد 2 کاراشو انجام میده سیستم متفاوتی رو داره.اصلا این کلمه Float یعنی چی ؟ در واقع عبارت کامل Floating Point هست به معنی ممیز شناور ! ما به دو صورت این اعداد رو داریم، یا Float یا Double که در واقع Double هم به معنی Double precision به معنی &quot;دقت دو برابر&quot; هست، اعداد float در حافظه 32 بیست جا می‌گیرند و Double ها 64 بیت !برای دوستانی که نمی‌دانند، اون IEEE رو به صورت &quot;آی تریپل ای&quot; می‌خونند، تریپل به معنی سه هست، البته اکثرا احتمالا بدونید اما شاید بعضی در دانشگاه بهشون درست نگفته باشند :)و فرمول محاسبه هم به این صورت خواهد بود :خب ! حالا هر کدوم از اینا یعنی چی ؟ Sign که مشخصا برای مثبت منفی بودن به کار میره که اگر صفر باشه یعنی مثبت و یک یعنی منفی ، قسمت دوم که ترجمه اش کردیم &quot;توان&quot; عبارتی هست که می‌تونه منفی با مثبت باشه، این قسمت 8 بیت هست، با هشت بیت در مبنای 2 ماکسیمم بشه عدد 1-256 یا همون 255 رو ساخت و مینمم عدد صفر ، حالا اگه یک مقدار ثابت (bias) رو ازش کم کنیم و این مقدار  ثابت رو 127 ( که در واقع هست دو به توان هفت منهای یک) قرار بدیم یک range جدید داریم که از 127- تا 128 رو ساپورت می‌کنه ! حالا چرا این کار رو می‌کنیم ؟ در واقع ما با این کار داریم مکمل 2 این عدد رو به دست میاریم، به طور کلی کامپیوتر وقتی بخواد یک عدد Integer رو حساب کنه به این صورت عمل میکنه :این روش خیلی هم عالیه، منتها اینجا برای Exponent مشکلی پیش بیاد، در این روش مثلا در این مثال 4 بیتی (عکس بالا) ما range اعدادمون از 8- تا 7 هست و اگه اعداد رو به ترتیب بنویسن به صورت صعودی نیستن ، اما ترجیح ما برای Exponent اینه که اعداد مثبت بیشتری داشته باشیم و راحت هم بتونیم دو تا عدد رو بیت به بیت مقایسه کنیم ، پس این روش به درد نمی‌خوره، ما به جای استفاده از این روش فرض می‌کنیم که اعداد ما از روش مکمل 2 استفاده نمی‌کنند و همون روش عادی رو استفاده می‌کنند :الان range اعداد ما از صفر تا 15 خواهد شد (در مثال 4 بیتی) حالا ما یک مقدار به نام offset of bias رو از این مقدار باید کم کنیم که اعداد منفی رو هم داشته باشیم، فرض کنیم مقدار bias برابر دو به توان سه یعنی 8 باشه (یعنی ارزش توانی پرارزش ترین بیت) که اون وقت range ما مثل همون مکمل 2 میشه از 8- تا 7 (فرقش با مکمل دو این میشه که ترتیب اعداد تفاوت می‌کنند، یعنی در مکمل 2 در مثال 4 بیتی اعداد از صفر تا هفت میره بعد یهو میشه منفی هشت و تا منفی یک میره، اما در این یکی روش اعداد به ترتیبت صعودی از منفی هشت تا مثبت هفت میره)، برای این تعداد اعداد مثبت رو بیشتر کنیم به جای دو به توان سه، دو به توان سه منهای یک رو استفاده می‌کنیم تا یک عدد مثبت بیشتر داشته باشیم ! مزیت دیگه این روش همون قضیه ای هست که در پارنتز نوشتم ، در این روش چون اعداد به ترتیب نوشته شدند کامپیوتر راحت تر مقایسه رو انجام میده و برای مقایسه می‌تونه بیت به بیت راحت بفهمه کدوم عدد بزرگتره !حالا تنها چیزی که باقی مونده Mantissa هست، بیت های مربوط به Mantissa در واقع یک عدد رو در مبنای 2 نشون می‌دن که این عدد به عنوان اعشار تلقی میشه ! یعنی چی ؟ یعنی مثلا اگه Mantissa برابر 010 باشه در واقع حاصل نمیشه 2 ، بلکه حاصل میشه 0.25، حالا این عدد Mantissa رو با یک باید جمع ببیندیم تا بشه 1.25 و بعد در فرمول جایگذاری کنیم . حالا متوجه شدید چرا به این اعداد &quot;ممیز شناور&quot; می‌گن ؟ چون محل و مکان ممیز بر اساس Exponent محاسبه میشه و می‌تونه هر جایی از Mantissa قرار بگیره !یک مثال ببینیم :با این مثال می‌تونید قدرت ممیز شناور رو ببینید، این عدد در واقع خیییییلی کوچیکه ولی سیستم ممیز شناوری قادر به محاسبه اون هست !حالا برعکس این رویه چی میشه ؟ الان شما یاد گرفتید عدد ممیز شناور رو سیستم ده دهی خودمون تغییر بدید) ولی برعکسش یعنی ده دهیی به ممیز شناور چی ؟ خب باید همین کار رو برعکس انجام بدید !!! فرض کنید عدد 5/3125 رو می‌خوایم به این صورت بنویسیم .اول که باید ببینید عدد منفی هست یا مثبت که Sign bit مشخص بشه ، بعدش عدد رو در مبنای دو بنویسید (بدون در نظر گرفتن منفی بودن)، حالا باید ممیز این عدد رو تغییر بدید، یعنی مثلا عدد ذکر شده در مبنای دو که میشه 101/0101رو باید جوری عوض کنید که قسمت چپ ممیز فقط یه دونه یک باشه یعنی این طوری 1/010101 که در واقع با تقسیم کردن عدد اصلی به 4 (دو به توان دو) این عدد جدید رو به دست آوردیم، Exponent چی میشه ؟ گفتیم تقسیم بر دو به توان دو یعنی این توان دو معادل همون Exponent هست ، منتها باید bias رو هم دخیل کنیم، حالا این بار چون داریم رویه رو برعکس انجام می‌دیم به جای کم کردن bias باید این مقدار رو بهش اضافه کنیم ، یعنی 2 + 127 که میشه 129 که اگه صورت مبنا دو بنویسیمش میشه : 10000001 حالا با وصل کردن این بیت ها به هم عدد رو داریم :حالا بالاتر گفتیم این قضیه برای اعداد Float هست، برای Double ها هم دقیقا همینه فقط با توجه به اینکه مقدار بیت ها بیشتر شده bias تغییر می‌کنه (که اگه مقاله رو فهمیده باشید خودتون می‌تونید متوجه بشید bias اون‌ها چند میشه) .آدرس کانال تلگرامی ما : لینکمن رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Mon, 04 Jul 2022 11:38:29 +0430</pubDate>
            </item>
                    <item>
                <title>بررسی انواع Kotlin Flow</title>
                <link>https://virgool.io/Rocket/%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D8%A7%D9%86%D9%88%D8%A7%D8%B9-kotlin-flow-ll3ph3rwykxy</link>
                <description>قبل از شروع بد نیست این قسمت را بخوانید (یعنی بخوانید کلا)در قسمت قبلی Flow رو به صورت کلی معرفی کردیم :در کاتلین نوع جدیدی رو به شکل استریمی (جریانی) از داده ها داریم که به اون Flow می‌گیم، Flow که به معنی شناور بودن هست در واقع شامل یک Emitter (ارسال کننده) و یک Collector (دریافت کننده) هست https://gist.github.com/sasssass/847e1a3b4301474ee88c5b505f6e9f0d دو نوع برای Flow داریم :Cold stream Flowدر این نوع ارسال کننده فقط وقتی عملیات emit رو انجام میده که یک دریافت کننده بهش متصل شده باشه Hot stream Flowدر این نوع ارسال کننده کاری نداره که دریافت کننده بهش وصله یا نه، در هر صورت عملیات emit رو انجام میده (مثلا شما اگه یه تایمر داشته باشی تایمره کاری نداره که تو داری نگاش میکنی یا نه، اون تایم خودشو حساب میکنه و جلو میره)در واقع این دسته بندی برای Flow نیست بلکه کلا برای Observable هاستنوع Cold یعنی Flow رو به صورت عادی استفاده کنیم (Flow) و نوع Hot زمانی اتفاق میفته که از SharedFlow یا StateFlow استفاده بشه .یک نمونه از SharedFlow ببینیم و بعدش توضیحاتی در موردش بدیم : https://gist.github.com/sasssass/5e0add356a6eed8ae0bc1df5f7f40742 خب در اینجا چند نکته هست، اول اینکه SharedFlow به صورت Hot Stream هست، اگه دقت کنید ما دو بار emit انجام می‌دیم ولی فقط دومی collect میشه، به خاطر اینکه emit اولی قبل از collect صورت گرفته و چون به حالت Hot هست به هر حال emit انجام میشه ولی چون دیرتر collect شده دریافت نمیشه ولی دومی چون بعد از collect بوده collect میشه، دومین مورد اینه که یک Job تعریف کردیم و اون رو بعد از collect کنسل کردیم، چون اگه این کار رو نکنیم collect به صورت مداوم انجام میشه و برنامه هیچوقت تموم نمیشه (اگه از Scope دیگه ای به جز runBlocking استفاده می‌کردیم قضیه فرق می‌کرد)، سومین نکته در کلاس SharedFlowHelper هست که یک نوع MutableSharedFlow رو به صورت Private تعریف کردیم و یک نوع SharedFlow رو به صورت Public بهش متصل کردیم، دلیل اینکار اینه که عملیات emit باید درون خود SharedFlowHelper با استفاده از MutableSharedFlow صورت بگیره و باقی کلاس نباید بتونن emit رو به صورت مستقیم انجام بدن، SharedFlow عادی هم قابلیت emit نداره و فقط دریاف می‌کنه (این best practice خود گوگل هست)حالا یک نمونه از StateFlow بببینیم : https://gist.github.com/sasssass/0a80a9c1827915c4678b5c0fc2dec19a و نتیجه :خب اینجا کمی وضعیت فرق کرد، تا حد زیادی شباهت به SharedFlow می‌بینیم اما چرا emit شماره یک هم چاپ شده؟ به کلمه دقت کنید State + Flow یعنی آخرین State همیشه درش باقی می‌مونه، بنابراین وقتی ما یک بار emit انجام بدیم و بعدش collect کنیم، آخرین مقداری که درون StateFlow وجود داشته collect میشه (برعکس SharedFlow) و یک نکته مهم هم اینکه StateFlow رو حتما باید مقدار دهی اولیه کنید، مثلا اینجا ما Null رو به عنوان مقدار اولیه قرار دادیم که باز هم به مفهوم State برمی‌گرده چون من باید یک State اولیه داشته باشم .حالا سوال اینجاست که چه زمانی از StateFlow استفاده کنیم و چرا از SharedFlow استفاده نکنیم ؟جوابش ساده است، هر وقتی که به مفهوم State نیاز دارید از StateFlow استفاده می‌کنیم، مثلا یکی از مواردش dataBinding در Android هست، به این عکس نگاه کنید :یکی از best practice ها پاس دادن ViewModel به dataBinding هست، در اینجا ما این کار رو کردیم و بعد یک مدل دیتا به صورت زیر درون ViewModel تعریف کردیم :که این مدل دیتا یک پارامتر fullName داره که به صورت String هست، ما در dataBinding حق استفاده از SharedFlow رو نداریم چون متریال هامون حالت State دارن پس باید از StateFlow استفاده کنیم (یه پروژه سمپل بسازید و کمی با این مفاهیم بازی کنید تا بهتر متوجه بشید) .یک مقدار هم در مورد اپراتورهای Flow صحبت کنیم ، اول در مورد اپراتور های محاسباتی صحبت می‌کنیم که می‌تونید SimpleFlowOperators از این گیت ببینید .در این کد کامنت گذاری کردم و مشخصه هر اپراتور چه کار میکنه اما بذارید در مورد فرق transform و map صحبت کنیم، وقتی map انجام می‌دیم صرفا نوع تایپمون رو عوض می‌کنیم اما تو transform ما دوباره داریم عملیات emit رو override می‌کنیم و می‌تونیم به جای یک بار چندین بار با چندین تایپ emit انجام بدیم، در مورد reduce هم که معنی لغویش به معنی کم کردنه این شکلیه که این اپراتور میاد مثل یک تابع بازگشتی مقادیر flow ی شما رو هی در یک لامبدا بهتون پاس میده، بدنه لامبدا دقیقا مثل یک تابع بازگشتیه، مقدار اولش مقادیر محاسبه شده قبلیه و مقدار اولش مقدار فعلی، این اپراتور برای اینه که شما بیای و کل چیزایی که قراره emit بشه رو مختصر در یک value داشته باشی.یک سری اپراتور دیگه هم داریم که مربوط به عملیات collect میشن که می‌تونید CollectionFlowOperator رو توی این گیت ببینید.برای این اپراتورها هم اونجا کامنت کذاشتم و result هر اپراتور رو هم می‌تونید ببینید تا کامل متوجه بشید داستانشون چیه اما فقط یک نکته ای هم اینجا بگم، وقتی از flatMap (حالا هر نوعش) استفاده می‌کنید کاری که می‌کنه اینه که هر آیتم در ردیف A رو در کل ردیف B ادغام میکنه پس نهایتا سایز مقادیر شما میشه n(A) x n(B) البته به جز flatMapLatest که اونم اگه زمان بندیش درست باشه باز همین اتفاق میفته، اما در zip و combine هدف این نیست بلکه معمولا سایز مقادیر میشه یا سایز A یا سایز B چون اونجا هدف ادغام کل با کل نیست، بلکه مثلا هی یه دونه از A میگیره با یه دونه از B و بعد ترکیبشون میکنه و بعد از اون هم A و هم B رو میبره جلو و میره سراغ دونه بعدی از A و دونه بعدی از B (البته نه لزوما که بازم با توجه به زمان بندی ممکنه مثلا 3 تا از A یهو skip بشه، توضیحات فایل کامله و ریزالتم مشخص شده و بعید بدونم مشکلی پیدا کنید)از این لینک می‌تونید به یک پروژه کوچولو در گیت دسترسی پیدا کنید که همه مثال ها اونجا نوشته شده.آدرس کانال تلگرامی ما : لینکمن رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!اگه دوست داشتید می‌تونید به صفحه Spotify و SoundCloud بنده هم برید و موسیقی های منو گوش بدید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Sun, 29 May 2022 15:33:55 +0430</pubDate>
            </item>
                    <item>
                <title>ایجاد یک سیستم Navigation در Multi Module Application</title>
                <link>https://virgool.io/@shobeyri.ali/%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%DB%8C%DA%A9-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-navigation-%D8%AF%D8%B1-multi-module-application-aiufwnoswqnb</link>
                <description>Where should we navigate?
یکی از چالش های برنامه نویسی در اندروید زمانی هست که شما به صورت مالتی ماژول برنامه نویسی می‌کنید، در این حالت ممکن هست سر ایجاد یک سیستم Navigation به مشکل بر بخورید، چند مقاله در این مورد دیدم که مثلا در یکی از اون ها کلا بیخیال Navigation Component شده بودند و یک سیستم جدید برای خودشون درست کردند (که من نمی‌خواستم این کار رو بکنم)، بعضی هاشون کل سیستم نویگیشن رو به لایه App برده بودن (که به نظرم خیلی درست نیست) و بعضی هم کارهای دیگه . . .در این مقاله با ایجاد یک ماژول جدا برای Navigation قراره یک سیستم برای این داستان درست کنیم .توجه : من در حال درست کردن یک پروژه سمپل برای خودم هستم و این مشکل رو برخوردم، این مقاله بیشتر حالت ترجمه از این مقاله داره که هم کمی تغییرش دادم و یک سری چیزا بهش اضافه کردمفرض کنید پروژه شما به این صورت باشه :ما قراره از Search به Detail بریم و همین طور می‌تونیم از Saved هم به اون قسمت بریم، همچنین میشه بین Search و Saved با استفاده از نویگیشن باتن ها سوئیچ انجام دادفلوی برنامهخب ما اینجا چند مورد رو باید هندل کنیم، یکی اتصال Navigation Button ها به Navigation Component یکی هم هندل Navigate بین ماژول های مختلف .اول از همه که باید library های مورد نظر رو اضافه کنیم که نیاز به توضیح نداره و می‌تونید از این لینک استفاده کنید.بعد از اون باید ببینیم معماری رو به چه صورت بچینیم، خب ما یک MainActivity رد لایه App خواهیم داشت که شامل FragmentContainerView و BottomNavigation هست : https://gist.github.com/sasssass/734e6d60f470f8f5b1c11a20adc36b0e اگر دقت کنید یک فایل نویگیشن گراف به اسم app_navigation به FragmentContainer الحاق شده، خب این کجاست ؟ این فایل و یک سری فایل مربوط به Navigation System در یک ماژول به نام Navigator (یا هر اسم دیگه که دوست دارید) وجود دارند : یک گراف اصلی که app_navigation هست و یه گراف فرعی و یک nav_id که شامل یک سری id برای نویگیشن هستند، هدف این هست که یک سری nested graph در app_navigation داشته باشیم و هندل نویگیت بین ماژولی را با اون ها انجام بدیم، اول از همه nav_id رو ببینیم : https://gist.github.com/sasssass/2902f6cb97e17716e25f9933435c20dc این Id ها از این به بعد در قسمت های مختلف استفاده خواهند شد و معرف nested graph های ما هستند، حالا فایل app_navigation رو با هم ببینیم : https://gist.github.com/sasssass/f92466c92ad449b42bd7db698e14b077 که شمای گرافیکی اون به این صورت هست :خب یک سری توضیحات باید بدم، همون طور که می‌بینید ما یک سری nested_graph در این فایل ایجاد کردیم که home رو هم saved_nav گذاشتیم، یک global action هم تعریف کردیم که کاربر از هرجا بخواهد بتواند به Detail برود (اکشن های گلوبال یعنی متکی به فرگمنت نیستند، از هر جا بخواهیم برویم به هر صفحه مورد نظر، می‌تونید این لینک رو ببینید)، تا اینجا چیز خاصی وجود نداشته، وقتشه بریم ببینیم این saved_nav یا detail_nav یا ... چی هستند، برای نمونه saved_nav : https://gist.github.com/sasssass/65a1579c3212b3423d0e4ddbdf0cca02 خب این که خالیه :/ ولی مشکلی نداره ما عین همین فایل رو در ماژول Saved هم داریم که به این صورته : https://gist.github.com/sasssass/ffda4f62983d859000954025836e3082 الان چرا ما دو تا فایل تعریف کردیم ؟ و اینکه یکی اصلا چرا خالی بود، چند تا نکته اینجا هست، یکی اینکه ماژول Navigator متکی به هیچ ماژولی نیست ولی باقی ماژول ها متکی به اون هستند یعنی در داخل فایل gradle باید implementation رو انجام بدید :implementation project(&quot;:navigator&quot;)یک نکته رو در فهم این قضیه باید متوجه بشید و اونم اینه : نکته اینه که ما در هیچ کدوم از این قسمت ها از + استفاده نکردیم، چرا ؟ چون همه این آیدی ها به همون فایل nav_id که ساخته بودیم اشاره دارن و دارن به این طریق با هم لینک می‌شن، یعنی درسته که ما یک فایل نویگیشن خالی در ماژول Navigator ساختیم ولی به مشکلی بر نمیخوریم چون در Run-Time این فایل به فایل اصلی که در داخل خود ماژول مثلا Saved هست به خاطر وجود Id یکسان لینک می‌شن !یک خلاصه از کارایی که کردیم :اومدیم در Activity مون یک FragmentContainer اضافه کردیمیک ماژول Navigator درست کردیم که توش فایل های مربوط به نویگیشن مثل آیدی ها و nested graph ها و app_navigation بوددر هر feature ای که داریم فایل نویگیشن مربوط به اون feature رو ایجاد می‌کنیمخب بریم سراغ بقیه چیزا، در ماژول Navigator اول از همه این Interface رو اضافه می‌کنیم : https://gist.github.com/sasssass/6f3cb2c390bd455e6eceddb8bf774b35 این interface در MainActivity قرار داده میشه (Implement میشه) که یکم بعد بررسی می‌کنیم این رو، داخل این Interface یک NavigationFlow ورودی قرار داده شده : https://gist.github.com/sasssass/1458f43c386865b919257716f1b02882 این یک Sealed Class هست که متریال لازم برای هندل نویگت بین ماژولی رو درش قرار می‌دیم، یعنی مثلا اگه خواستیم بریم به صفحه Detail لازمه به Interface مون DetailFlow رو پاس بدیم .نکته : به نظرم این فایل شاید کمی اصول SOLID رو نقض کنه، در واقع اصل O یعنی Open-Closed، چرا ؟ چون ما به ازای هر فیچر جدید شاید مجبوریم بشیم این فایل رو تغییر بدیم که درست نیست، می‌تونیم به جاش از وراثت استفاده کنیم یا ... .یک فایل دیگر هم به اسم Navigator داریم که با استفاده از Sealed Class مون میاییم و مشخص می‌کنیم کدوم اکشن رو از نویگیشن گرافمون استفاده کنه : https://gist.github.com/sasssass/bd03b7e4607b9882689be46b5026e818 در این فایل مثلا اگر DetailFlow بیاد میاد و اون اکشن گلوبالی که تو app_navigation بوده رو استفاده می‌کنه و در این مثال خاص دیتا هم داشته که به صورت bundle بشه پاس داده میشه .خب حالا وقت استفاده از این فایل هاست که در MainActivity انجام میشه (ماژول App هم مثل Feature ها باید متکی به ماژول Navigator باشه و این ماژول در gradle اش اد بشه) : https://gist.github.com/sasssass/5eb79aed8dfe9d8ef62f437b0eb05160 خب خیلی هم خوب اما این تابع navigateToFlow چطور صدا زده بشه؟ اینجا تابع باید از سمت Fragment ها صدا زده بشن، برای اینکار می‌تویند یک BaseFragment ایجاد کنید که همه Fragment ها از اون ارث ببرن : https://gist.github.com/sasssass/0ad3ef6693d3b78e19465ccc4495ea35 این طوری ما دسترسی به اون Interface رو در BaseFragment داریم، الان دیگه همه چیز حله، اگر بخوام می‌تونم مثلا از ماژول Saved به Detail برم : https://gist.github.com/sasssass/bfbf85d98ba2726de75d7ab975d04287 و تمام ! فقط یک نکته می‌مونه و اون اتصال Navigation Button ها به Navigation Component هست، خب همون طور که می‌دونید Navigation Button ها یک فایل menu رو می‌گیرن : https://gist.github.com/sasssass/112f2614fc8ca241df3653feded15adc آیدی که برای آیتم ها داده میشه باید مجددا همون آیدی باشه که در ماژول Navigator قرار دادیم، حالا یک تابع هست به این شکل :bottomNav.setupWithNavController(navController) https://gist.github.com/sasssass/27af0f155d1b9d7bf119e33ffb8ce344 و بعدش خود Navigation Componentبقیه شو انجام می‌ده !!!آدرس کانال تلگرامی ما : لینکمن رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!اگه دوست داشتید می‌تونید به صفحه Spotify و SoundCloud بنده هم برید و موسیقی های منو گوش بدید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Sat, 19 Feb 2022 10:51:17 +0330</pubDate>
            </item>
                    <item>
                <title>مروری بر UML</title>
                <link>https://virgool.io/@shobeyri.ali/%D9%85%D8%B1%D9%88%D8%B1%DB%8C-%D8%A8%D8%B1-uml-ro8sw79gsxib</link>
                <description>مسلما داکیومنت سازی یکی از اصلی ترین مراحل توسعه یک محصول است، قبلا در مورد KDoc مقاله ای در مدیوم گذاشته بودم، امروز در جلسه knowledge sharing ای که داشتیم تصمیم گرفتم مروری بر UML برای همکاران داشته باشم و در کنار اون ابزار به شدت کاربردی PlantUML رو هم بررسی کردیماز طریق لینک زیر می‌تونید جلسه رو که رکورد شده رو ملاحظه کنیدhttps://youtu.be/gVetw59hEE8</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Wed, 29 Dec 2021 12:04:09 +0330</pubDate>
            </item>
                    <item>
                <title>پیاده سازی in-app-update</title>
                <link>https://virgool.io/@shobeyri.ali/%D9%BE%DB%8C%D8%A7%D8%AF%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-in-app-update-v0qvgleiwbnb</link>
                <description>خیلی از اپلیکیشن ها رو دیدید که وقتی نسخه تون آپدیت نیست بهتون پیشنهاد آپدیت میده، ولی این کار رو می‌تونیم بدون کمک back-end هم انجام بدیم. گوگل پلی یک ویژگی داره برای این کار که باهاش می‌تونیم آپدیت نبودن اپلیکیشن رو بررسی کنیم و به کاربر بر اساس شرایطی پیشنهاد آپدیت بدیم که بهش in app update می‌گیم. javahttps://giphy.com/embed/2x0tJVAL3IqFnZYhYt نکته : این ویژگی نیازمند اینه که ورژن اندروید 5 استفاده بشه ما این کار رو به وسیله ابزاری به اسم AppUpdateManager انجام می‌دیم ، شما می‌تونید به این ابزار یک Listener وصل کنید و چک کنید که آیا آپدیت جدیدی در دسترس هست یا نه : https://gist.github.com/sasssass/d86e5699d6cd01e6232738afa4c07a49 مثلا در کد بالا ما یک Listener از نوع Success گذاشتیم (می‌تونید از نوع Failed هم بذارید که اسمش addOnFailureListener هست) و میایم چک می‌کنیم که updateAvailability ما برابر با UpdateAvailability.UPDATE_AVAILABLE هست یا نه ، سه مقدار دیگه به جز این مقدار وجود داره که می‌تونید از خودِ اون کلاس ببینید ، مثلا UPDATE_NOT_AVAILABLE که نشون میده آپدیتی نیست) ، شرط دومی که من چک کردم updatePriority هست ، 6 مقدار از صفر تا پنج برای این شرط وجود داره ، شما بعدا از آپدیت های جدید رو با استفاده از یک api تغییر بدید ، متن زیر چیزی هست که به api باید پاس بدید ، این پست رو بخونید :یک شرط جالب دیگه clientVersionStalenessDays هست ، در واقع با این شرط بررسی میشه که چند روز از آپدیت گذشته ، اگه این مقدار null بود به صورت پیشفرض -1 رو براش در نظر گرفتم (یعنی الان من گفتم نگاه کن ببین اگه آپدیت رو اولیت 4 به بالا بود و 3 روز ازش گذشته بود بعد پیغام آپدیت رو نشون بده) ، شرط دیگه ای هم داریم .قبل از اینکه ادامه کار رو بگم باید عنوان کنم که دو نوع آپدیت وجود داره، یکی flexible و یکی immediate ، اگه شما به صورت flexible آپدیت کنید می‌تونید حین کار با اپ مراحل آپدیت رو انجام بدید ولی در نوع immediate نمی‌تونید این کار رو بکنید، وقتی به صورت flexible درخواست آپدیت می‌دید یک دیالوگ برای شما باز میشه ولی تو نوع immediate این دیالوگ تمام صفحه خواهد بود (اینکه چطوری باید بگیم آپدیت بعدی ما immediate هست یا نیست رو هم هیچ جا ننوشته چطوریه :) تو خودِ داک گوگل هم نیست ، تو استک اور فلو و ... رو هم شخم زدم و نبود، اگه پیدا کردید بهم بگید ولی عموما نوشتن که نمیشه فورس کرد که آپدیتی که دادید حتما flexible یا immediate باشه، چیزی که فهمیدم اینه که فقط برای این مهمه که نوعِ آپدیت کردنتون دست خودتون باشه و به صورت کلی به نظر چیز چرتی میاد)چپی ها نوع flexible هست که اجازه استفاده از اپ رو دارید در حین آپدیت و راستی ها immediate که نمی‌ذاره از اپ استفاده کنیددر ادامه فرایند شما می‌تونید یک نوع دیگه از Listener رو هم داشته باشید، یک Listener مخصوص که نشون بده چقدر از وضعیت آپدیت شما جلو رفته : https://gist.github.com/sasssass/2509f253dcb58973517e3dd137e26e94 همون طور که می‌بینید اگه وضعیت Downloaded باشه می‌تونیم یه دیالوگی چیزی به طرف نشون بدیم و وقتی هم که داره Downloading میشه می‌تونیم یک لودینگ به کاربر نشون بدیم ، نکته اینه که کار هنوز تموم نشده ، الان صرفا آپدیت تموم شد، حالا می‌تونیم با همون AppUpdateManager  که داشتیم کار رو تموم کنیم :appUpdateManager?.completeUpdate()وقتی این متد رو صدا بزنید اکتیویتی ای که درونش هستید ریست میشه (در واقع  صدا زده میشه دوباره) و اپ شما آپدیت شده !در قسمت آخر مشکلی که کد بالا داره اینه که الان فقط ما داریم پروسه رو Listen می‌کنیم و جایی آپدیت رو صدا نکردیم ، در قسمت کامنتی که در کد اول گذاشتم نوشتم &quot;پیشنهاد آپدیت&quot; ، شما با این کد می‌تونید درخواست آپدیت رو بدید و بعدش با کد قسمت دوم Listen کنید :appUpdateManager?.startUpdateFlowForResult(appUpdateInfo,AppUpdateType.FLEXIBLE,activity,UPDATE_REQUEST_CODE)متغیر appUpdateInfo رو که در بالا داشتیم ، ورودی دوم میگیم به حالت Flexible آپدیت رو انجام بده، تو ورودی سوم اکتیویتی حالِ حاضر رو پاس میدیم و تو ورودی چهارم یک ریکوئست کد پاس میدیم، این ریکوئست کد به این درد میخوره که ما بعدا می‌تونیم از onActivityResult ببینیم آیا ریکوئست موفق رفته یا نه ، اگه نبود میتونید دوباره درخواست آپدیت بدید :حالا چطوری تستش کنیم؟ حتما بریم یه ورژن تو گوگل پلی بذاریم؟ نه ! پنلی وجود داره (Internal app sharing) که می‌تونید اپ رو برای tester ها اضافه کنید ، شما می‌تونید به جای آپلود روی گوگل پلی روی اون آپلود کنید و مراحل رو تست کنید :https://support.google.com/googleplay/android-developer/answer/9844679آدرس کانال تلگرامی ما : لینکمن رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!اگه دوست داشتید می‌تونید به صفحه Spotify و SoundCloud بنده هم برید و موسیقی های منو گوش بدید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Sat, 27 Nov 2021 12:11:05 +0330</pubDate>
            </item>
                    <item>
                <title>مروری بر مبحث ساختمان داده</title>
                <link>https://virgool.io/@shobeyri.ali/%D9%85%D8%B1%D9%88%D8%B1%DB%8C-%D8%A8%D8%B1-%D9%85%D8%A8%D8%AD%D8%AB-%D8%B3%D8%A7%D8%AE%D8%AA%D9%85%D8%A7%D9%86-%D8%AF%D8%A7%D8%AF%D9%87-mkowzmejemud</link>
                <description>مسلما یکی از مهم ترین موضوعات در علوم کامپیوتر مبحث ساختمان داده است ، شاید خیلی از ما این مبحث رو فراموش کردیم یا اصلا از یک حوزه دیگه به کامپیوتر وارد شدیم (مثلا عمران خوندیم ولی رفتیم برنامه نویس شدیم) و خیلی این بحث رو نمیدونمی چی به چیه ، در این ویدئو به صورت خلاصه یک مروری بر روی ساختمان داده های معروف انجام می‌دیم . https://youtu.be/nUoc4NO3jmQ آدرس کانال تلگرامی ما : لینکلینک گیت مقاله رو هم در این لینک می‌تونید ببینید .من رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!اگه دوست داشتید می‌تونید به صفحه Spotify و SoundCloud بنده هم برید و موسیقی های منو گوش بدید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Thu, 14 Oct 2021 23:04:47 +0330</pubDate>
            </item>
                    <item>
                <title>بررسی Kotlin Flow به زبان ساده</title>
                <link>https://virgool.io/@shobeyri.ali/%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-kotlin-flow-%D8%A8%D9%87-%D8%B2%D8%A8%D8%A7%D9%86-%D8%B3%D8%A7%D8%AF%D9%87-z9ptun2vx2vs</link>
                <description>فلویی از داده ها ، مثلا در اینجا آبآیا تا حالا با RxJava کار کردید ؟ با Sequences﻿ چطور ؟ امروز با مبحثی آشنا می‌شیم که می‌تونه جایگزینی برای استفاده از این ابزار باشه . در این مقاله با به طور ساده این مبحث رو با هم بررسی می‌کنیم .برنامه نویسی Reactiveقبل از هر چیز باید بدونیم برنامه نویسی Reactive چیه ؟ به طور خلاصه کاری که RxJava یا RxAndroid یا RxKotlin یا ... انجام میدن پیاده سازی این نوع برنامه نویسی برای محیط جاوا/کاتلین/اندروید هستند . در برنامه نویسی Reactive یا &quot;واکنش گرا&quot; ما با استریمی از داده ها ، event ها و callback ها کار داریم .کاتلین Flowدر واقع Flow همون طور که از اسمش هم پیداست sequence ای از داده ها به صورت آسنکرون هست . Flow اگر با Coroutines تکریب شود Coroutines را به عنوان scheduler (برای بردن روی Thread های مختلف) اتخاذ می‌‎کند . Flow به طور کامل Coroutines رو ساپورت می‌کنه و در کنار هم ابزار قدرتمندی برای توسعه اپلیکیشن ها محسوب می‌شوند .مدل Flowبه تصویر بالا توجه کنید ، تابع getValues برای ما مقادیری از جنس Flow رو emit می‌کنه و تابع processValues که این Flow رو دنبال یا Subscribe می‌کنه مقادیر emit شده رو می‌گیره و پردازش مورد نظر خودش رو انجام میده .مزایای Flowبسیار ساده تره نسبت به Rxمنطبق با Coroutines (مثلا وقتی Coroutines کنسل بشه Flow هم کنسل میشه)ویژگی Backpressure Handling (البته در Rx هم وجود داره ، وقتی Emitter با سرعت زیادی تری نسبت به Collector دیتا رو منتشر می‌کنه مشکلی برای ما پیش نمیاد ، Emit ها در یک صف قرار داده میشن و به ترتیب به Collector پاس داده میشن)ویژگی Suspending (اگر با Coroutines آشنا باشید متوجه می‌شوید که چون به صورت آسنکرون انجام میشه در واقع Thread اصلی شما block نمیشه)مثال هایی از Flowابتدا باید کتابخونه Coroutines رو به پروژه اضافه کنیدimplementation &#x27;org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1&#x27;implementation &#x27;org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.1&#x27; https://gist.github.com/sasssass/3742f19315c7e7e3bf1f2c2c2b56d33a و نتیجه :حالا یک مثال جامع تر رو بررسی خواهیم کرد ، فرض کنید مدل دیتایی داریم که شامل لیستی از User ها است ، ما می‌خواهیم اسامی این User ها رو در صفحه ای خاص داشته باشیم ، در این سناریو دو بار لیستی از User ها emit می‌شود با فاصله زمانی 2 ثانیه و سپس یک ارور 403 قرار است داده شود  .ما یک DataSource خواهیم داشت که وظیفه این عمل رو به عهده می‌گیره ، این کلاس وظیفه اتصال به Api رو دارد (که اینجا البته نیست و صرفا یک لیستی پاس می‌دهیم) ، سپس در Repo دیتا process شده و تبدیل به لیستی از اسامی می‌شود ، سپس در UI نمایش داده می‌شود (مسلما یک پیاده سازی ساده است ، بعد از خواندن این مقاله سعی کنید Flow رو با MVVM یا دیگر معماری هایی که استفاده می‌کنید مثل Clean MVVM یا MVI ترکیب کنید ) : https://gist.github.com/sasssass/cdc722f5a55c94ccbe8737b6ed0add76 و خروجی :شما می‌تواند Flow را به جای LiveData یا Rx با Room هم ترکیب کنید :البته Flow به همینجا ختم نمی‌شود و ویژگی های بسیاری دارد که سعی می‌کنم در آینده در مورد اونها با هم صحبت کنیم .اگر از مقالات من راضی هستید لطفا به LinkedIn من برید و من Skill های مرتبط با اندروید من رو یک پلاس روش بزنید :)آدرس کانال تلگرامی ما : لینکلینک گیت مقاله رو هم در این لینک می‌تونید ببینید .من رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!اگه دوست داشتید می‌تونید به صفحه Spotify و SoundCloud بنده هم برید و موسیقی های منو گوش بدید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Sun, 01 Aug 2021 15:17:38 +0430</pubDate>
            </item>
                    <item>
                <title>اپراتورها در Kotlin</title>
                <link>https://virgool.io/@shobeyri.ali/%D8%A7%D9%BE%D8%B1%D8%A7%D8%AA%D9%88%D8%B1%D9%87%D8%A7-%D8%AF%D8%B1-kotlin-sxelexhllpjd</link>
                <description>در کاتلین بر خلاف جاوا دست شما در اپراتور ها و استفاده و override کردن شما بازتر هست . بدون مقدمه می‌ریم سراغ اصل داستان و یک به یک انوع اپراتور رو بررسی می‌کنیم .Arithmetic Op.اپراتورهای حسابگر (مثلا +) در جاوا برای متغیرهای اصلی (primitive) مثل int و ... استفاده میشه و برای باقی متغیر (به جز یک استثنا که اون هم String هست) قابل استفاده نیست .اما در کاتلین اینطور نیست ، شما می‌تونید این operator رو override کنید و برای انواع کلاس ها استفاده کنید ، برای مثال همین اپراتور + ، وقتی شما قصد override کردن یک اپراتور رو دارید باید معادل لغوی اون اپراتور رو بدونید (مثلا برای + میشه plus) ، بعد تابع plus رو تعریف کنید و قبل از کلمه fun کلمه operator رو استفاده کنید . برای مثال کلاس A رو داریم که یک متغیر Int درون خودش داره ، ما می‌خوایم اپراتور + رو در دو حالت یکی اینکه دو متغیر از جنس A با هم جمع بشوند و یکی اینکه یک متغیر A با یک Int جمع بشه رو داشته باشیم :اگر دقت کنید به جای اینکه دوبار اپراتور + رو override کنیم در واقع یک بار هم برای Int به صورت Extended این override رو انجام دادیم ، دلیلش چیه ؟ ساده است ، در کاتلین جا به جایی متغیرها رو وقتی جنس اونها فرق کنند رو متوجه نمیشه ، پس اگر جنس A رو به اضافه Int می‌کنید یکبار هم باید جنس Int رو به اضافه A کنید !!!نکته : در جاوا ما این قضیه override کردن اپراتورها رو نداریم پس اگه در کدکاتلین رو در جاوا بخواید استفاده کنید به جای + باید از همون اسم تابع plus استفاده کنید .نکته : همون طور که برای Int به صورت Extended این عملیات رو انجام دادیم برای هر نوع دیگری هم می‌تونیم به جای تعریف اپراتور در بنده اصلی کلاس به صورت Extended این کار رو انجام بدیم .لیست اپراتورهای ریاضی :نکته : حواستون باشه اگه چند اپراتور رو پشت هم استفاده می‌کنید ترتیب عمل کردن اونها از همون منطق همیشگی پیروری می‌کنه ، یعنی مثلا اپراتور ضرب اولیت بالاتری نسبت به + دارهنکته : لازم نیست خروجی این اپراتور ها از جنس خودِ کلاس باشه ، مسلما هر نوع خروجی که در نظر دارید رو می‌تونید استفاده کنید Compound assignment Op.اپراتورهای انتصاب ترکیبی ، مثلا اپراتور =+ ، این اپراتور به صورت لغوی plsuAssign معنی میشه و نکته مهم در اونها اینه که خروجی حتما باید Unit باشه .نکته : این اپراتور ممکنه با اپراتور + یکی تلقی بشه ، یعنی اگه شما هر جفتش رو override کنید به خطا بررخورید (کامپایل تایم) ، پس از یکی از اونجا استفاده کنید .نکته : هر دو نوع اپراتوری که تا الان بررسی کردیم برای Collection ها (مثلا آرایه) قابل استفاده است . اپراتورهای ریاضی (مثل +) یک Collection جدید رو به عنوان خروجی برمی‌گردوند :Unary Op.اپراتورهای یگانه مثلا - پشت یک متغیر ، - در اینجا unrayMinus هست ، این اپراتورها حق گرفتن ورودی رو ندارند و فقط خروجی دارندلیست این اپراتورها :نکته : اولیت ++ پشت متغیر بالاتر از بقیه چیزهاست ، تفاوت ++ جلوی متغیر با پشت متغیر در همینه ، مثلا اگه متغیری رو چاپ کنید و درون دستور چاپ پشتش ++ بذارید اول ++ رو انجام میده بعد چاپ ولی اگه جلوی متغیر بذارید اول متغیر رو چاپ می‌کنه بعد ++Comparison Op.متغیر های مقایسه ای مثل == ، در کاتلین سه تیپ برای مساوی داریم ، یکی == ، یکی === ، یکی هم equals ، در جاوا اپراتور == به اینگونه هست که اگه متغیر primitive باشه مقدار رو چک می‌کنه و اگه کلاس باشه رفرنس رو (به یک جای حافظه اشاره کردن) ، اما در کاتلین این طور نیست ! در کاتلین == برای مقایسه مقادیر نه رفرنس استفاده میشه و در زیرلایه اون داره همون equals رو صدا می‌زنه (پس برای override کردنش باید همون equals رو override کرد) ، اما در مورد == شما حتما باید دومتغیر از یک جنس رو با هم مقایسه کنید (ولی در مورد equals این طور نیست) ، حواستون باشه که اگه == رو برای کلاس ها صدا می‌زنید باید حتما equals رو override کنید وگرنه بهتون false برمی‌گردونه .اپراتور === این رو چک می‌کنه که آیا دو متغیر دارای رفرنس یکسان هستند یا نه ، یعنی به یک جا از حافظه اشاره می‌‎کنند یا خیر !نکته : equals رو نمی‌تونید به صورت Extended اضافه کنید ، چون این متد متعلق به کلاس Any هست و به هر حال اونی که برای کلاس هست ارجخیت به Extended دارهنکته : === قابل override کردن نیستدر جاوا ما اینترفیسی به نام Comparable داریم که برای مقایسه بین دو متغیر استفاده میشه ، در کاتلین هم این مساله هست با این تفاوت که شما می‌تونید این قضیه رو تبدیل به اپراتورهای مقایسه مثل &lt; و ... بکنید .نکته : تابع compareValuesBy یک تابع از کاتلینه که میاد دومتغیر (ورودی اول و دوم) و معیار مقایسه رو (که یک varargs هست (لیستی از متغیرها) می‌گیره و مقایسه رو انجام میدهنکته : در تابع compareTo اگر خروجی بزرگتر از صفر شود یعنی بزرگتر ، مساوی صفر یعنی مساوی و منفی یعنی کوچکتر Collection and Range Op.مسلما با آرایه و لیست کار کردید ، وقتی نیاز به عنصر دوم از آرایه دارید دستوری مثل a[1] رو داریم ، خب این اپراتور [index] رو چطوری باید override کرد ؟ دو اسم get و set برای این قضیه به کار میره .نکته : set نیاز به یک ورودی علاوه بر index داره ، در مورد اینکه Index ها چی باشند هم می‌بینید که هر چی دوست داشته باشید می‌تونید بذارید ، حتی می‌تونید چندین index داشته باشید ! یکی دیگه از اپراتور ها اپراتورِ in هست که نشون دهنده اینه که یک آیتم عضو یک مجموعه هست یا نه ، برای پیاده سازی in باید تابع contains رو override کنید :اپراتوری با علامت .. داریم که مشخص کننده رنجی از اعداد هست ، مثلا 10..1 از عدد یک تا ده رو شامل میشه ، برای این اپراتور باید تابع rangeTo رو override کنید :نکته : اولیت اپراتور .. نسبت به عملیات ریاضی (مثلا +) کمتر استآدرس کانال تلگرامی ما : لینکلینک گیت مقاله رو هم در این لینک می‌تونید ببینید .من رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!اگه دوست داشتید می‌تونید به صفحه Spotify و SoundCloud بنده هم برید و موسیقی های منو گوش بدید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Thu, 08 Jul 2021 17:10:44 +0430</pubDate>
            </item>
                    <item>
                <title>دوره آموزشی معماری های MVVM و MVI در Android</title>
                <link>https://virgool.io/@shobeyri.ali/%D8%AF%D9%88%D8%B1%D9%87-%D8%A2%D9%85%D9%88%D8%B2%D8%B4%DB%8C-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-mvvm-%D9%88-mvi-%D8%AF%D8%B1-android-ksqxyqvamxue</link>
                <description>بارها در مقالات قبلی این نکته رو خاطر نشان کردم که معنی واژه &quot;مهندس&quot; که از لغت &quot;هندسه&quot; میاد برای یک مهندس کامپیوتر یعنی چیدن یک &quot;معماری&quot; محکم و کامل برای توسعه اپلیکیشن ، تفاوت یک برنامه نویسِ ساده با یک مهندس کامپیوتر هم از همینجا مشخص میشه ! مثل تفاوت یک نوازنده با یک آهنگساز .دوره آموزشی معماری های سری MV رو که برای شما عزیزان آماده کردم شامل بررسی چهار معماری MVC , MVP , MVVM , MVI می‌باشد که البته تمرکز اصلی بر روی MVVM و MVI بوده .در این دوره دو پروژه با MVVM و MVI برای شما آماده شده ، در کنار این دو معماری ابزارهایی مانند LiveData ، DataBinding , Navigation Component , Hilt (DI) هم برای شما عزیزان بررسی شده که بتونید یک پروژه کامل رو با یکی از دو معماری فوق پیاده کنید .این مجموعه آموزشی در یوتیوب آپلود شده و شما عزیزان می‌تونید از طریق لینک زیر به اون دسترسی داشته باشید .مجموعه آموزشی معماری های سری MV در اندرویدمنتظر نقد و نظر شما عزیزان هستم !آدرس کانال تلگرامی ما : لینکلینک گیت مقاله رو هم در این لینک می‌تونید ببینید .من رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!اگه دوست داشتید می‌تونید به صفحه Spotify و SoundCloud بنده هم برید و موسیقی های منو گوش بدید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Mon, 05 Jul 2021 09:51:38 +0430</pubDate>
            </item>
                    <item>
                <title>پیاده سازی معماری Clean MVVM (اندروید)</title>
                <link>https://virgool.io/@shobeyri.ali/%D9%BE%DB%8C%D8%A7%D8%AF%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%DB%8C-clean-%D8%A8%D8%B1-%D8%B1%D9%88%DB%8C-mvvm-%D8%A7%D9%86%D8%AF%D8%B1%D9%88%DB%8C%D8%AF-qf5yoroqlwbu</link>
                <description>قبل از شروع مقاله این نکته رو توجه کنید ، من در این مقاله بر یک سری مقاله های دیگه متکی بودم که قبلا در ویرگول گذاشتم ، دو مقاله در مورد Hilt و چند سری مقاله در مورد Coroutines ، همین طور باید MVVM رو بدونید ، البته در مورد MVVM مقاله ای نذاشتم منتها یک سری ویدئو در youtube گذاشتم (که البته تمام نشده) که حتما حتما حتما باید قبل از اینکه مقاله رو بخونید اون ها رو خونده باشید ، البته در حین مقاله هر جا که لازم شده رفرنس به اون مقالات دادم .لیست مقالات و ویدئوی هایی که باید قبلش خونده یا دیده باشید :مجموعه Coroutines : مقاله 1 ، مقاله 2 ، مقاله 3 ، مقاله 4 ، مقاله 5مجموعه Hilt : قسمت اول Hilt و قسمت دوم Hiltمجمعه MVVM : لینکدر این مقاله به شما آموزش میدم چطوری معماری MVVM تون رو حالت Clean در بیارید !اول از همه سوال اصلی اینه که اصلا ما چرا باید در برنامه نویسی مون از معماری ها استفاده کنیم ؟معماری نرم افزاریک مثالی که اکثرا می‌زنم اینه ، یک سری ها میرن مهندسی عمران می‌خونند ، یعنی معماری سازه ها رو پیاده می‌کنند ، یک سری مهندسی مکانیک می‌خونن ، یعنی معماری یک دستگاه (ماشین یا ...) رو پیاده سازی می‌کنند ، حالا یک مهندس کامپیوتر چی ؟ برای چی بهش می‌گن مهندس ؟ مهندس از واژه &quot;هندسه&quot; میاد ، یکی از شاخه های علم مهندسی نرم افزار برنامه نویسیه ، اگه شما صرفا بلد باشید به یه زبونی کد بزنید و یه فریم ورکی رو بلد باشید به شما نمیشه گفت مهندس ، بهتون میگن &quot;کد زن&quot; ، اما اگه بلد باشید مثل یک &quot;مهندس&quot; کدهاتون رو لایه بندی ، کامپوننت بندی و ... کنید و یک ساختار منظم و معماری خوبی رو برای کدهاتون بچینید اون وقته که می‌تونیم کلمه &quot;مهندس&quot; رو بهتون بگیم ! شما هم معماری می‌چینید اما برخلاف مهندس عمران ، مکانیک یا ... جنبه فیزیکی نداره و همه چیز رو به صورت مجازی پیاده می‌کنید.هدف از معماری سهولت خوانایی کد ، افزایش قابلیت نگه داری (Maintenance) ، کم کردن تلاش برنامه نویس برای تغییرات/افزودن فیچرها ، قابلیت تست پذیری و ... هست .معماری Clean https://media.giphy.com/media/3zn52gZBFbb21rk2wr/giphy.gif معماری Clean ربطی به MVVM نداره ، بلکه یک روش پیشنهادی از سمت Robert C. Martin (معروف به عمو باب) هست ، ما می‌تونیم این معماری رو با MVVM ترکیب کنیم . در مقاله آقای مارتین گفته شده که یکی از مشکلات برنامه نویسان separation of concerns هست و ما این امر رو از طریق لایه بندی عناصر ایجاد می‌کنیم ، ایشون این پنج مورد رو به عنوان مواردی که باید در نظر گرفت بررسی کردند :معماری شما به Framework وابسته نباشه ، یعنی در هر Framework ای بشه پیاده ش کردتست پذیره باشه بدون اینکه نیاز به UI ، دیتابیس و ... داشته باشهوابسته به UI نباشه (توضیح داده شده که طوری برنامه رو بنویسید که لایه UI جدا باشه که این طوری بشه به فرم های مختلف UI متصل بشه)وابسته به دیتابیس نباشه (دلیلش مثل مورد 3 هست ، بتونیم از هر نوع دیتابیسی استفاده کنیم و لایه دیتابیس جدا باشه)وابسته به external agency ها نباشه ، که در توضیح این نوشته شده لایه بیزینیس لاجیک شما (business rules) چیزی در مورد خارج از دنیای خودش ندونه (external agency باز هم همون مورد 3 و 4 و ... میشه) .حالا وقت اینه که در مورد لایه های مختلف بدونیم ، به شکل زیر نگاه کنید :شمای کلی معماری clean بر پایه مقاله رابرت مارتینمعماری Clean بر 4 لایه استوار شده ، لایه خای داخلی نباید در مورد لایه های بیرونی اطلاعی داشته باشن و نمی‌خوایم هیچ عاملی از لایه های بیرونی بر لایه های درونی اثر بذاره (یعنی مثلا UI از Controller اطلاع داره ولی برعکسش صادق نیست) .لایه Entities(زرد)طبق مقاله مرجع ، این لایه می‌تونه یک object به همراه توابع درونش باشه و یا یک ساختار کلی و توابع مربوط به اون. این لایه مستقل از Framework هست ، یعنی چی ؟ یعنی مثلا ما که توسعه اندروید انجام می‌دیم در این لایه صرفا از کاتلین و جاوا استفاده می‌کنیم و سعی ‌می‌کنیم از خودِ SDK اندروید در این لایه استفاده نکنیم .نکته : همه این مسائل Concept هستند ، یعنی چی ؟ یعنی هر کسی یک برداشتی از این قضیه می‌کنه و پیاده سازی های مختلفی که از Clean می‌بینید ممکنه با هم تفاوت هایی بکنند اما درصد بالایی از قضیه در همه شون یکیه !لایه Use Case(قرمز)این لایه در واقعی کانالی از لایه Entities به لایه بعدیه ، یعنی data flow (مسیر داده) رو مشخص می‌کنه . Use Case در قسمتی که ما پیاده می‌کنیم میشه interact (تعامل) های کاربر با اپلیکیشن شما که سر تایمش توضیح می‌دم .لایه Interface Adapters(سبز)وظیفه این لایه اینه که مدل ها و داده هایی که از طریق دو لایه قبلی میان رو به فرمی در بیاره که قابل فهم برای لایه بعدیش بشه . به طور کلی معنی کلمه Adapt یعنی &quot;وفق دادن&quot; که از معنیش همون جمله اول رو میشه برداشت کرد .لایه Frameworks (آبی)این لایه ، لایه نهایی که شامل دیتابیس ، UI و ... هست .خب این تعاریف بالا خیلی کلی هستن ، ما نیاز داریم این تیپ معماری رو با MVVM در اندروید تلفیق کنیم .در اکثر پیاده سازی هایی که Clean MVVM هستند و برای اندروید صورت گرفتند کدها به سه لایه اصلی (و چند لایه فرعی) تقسیم می‌شن ، . این لایه ها به ترتیب زیر هستند :لایه Data :ما در این لایه  تعاریف انتزاعی مربوط به داده ها رو می‌نویسیم ، &quot;مربوط&quot; یعنی چی ؟ یعنی مثلا این دیتا از کجا میاد ؟ از سرور ؟ پس باید تعریف انتزاعی کدهای مربوط به سرور رو اینجا بذاریم ، تعریف انتزاعی عملیات Database و ... رو هم در این لایه قرار می‌دیم . یکی دیگه از چیزایی که اینجا نگه می‌داریم کلاس های Mapper برای تبدیل مدل سرور به دیتابیس هست (این لایه باید Pure Kotlin/Java باشد) .ما تو این لایه DataSource (منابع داده) رو داریم ، در این لایه تعریف شون رو داریم (یعنی Interface) و در کنارش کلاس های Repository رو خواهیم داشت که از اون DataSource ها استفاده خواهند کرد .لایه Domain :این لایه درونی ترین لایه ما حساب میشه و مثل همون Entity میشه . ما در این لایه بیشتر مدل هامون رو قرار می‌دیم . مثلا مدل دیتاهایی که قراره از سرور ، دیتابیس یا جاهای دیگه بیان ، این لایه هم باز Pure Kotlin/Java هست ، یعنی (ترجیحا) از SDK اندروید قرار نیست استفاده کنیم .لایه Use-Case :در این لایه با استفاده از کلاس های Repository لایه قبلی می‌آییم و Use Case ها رو می‌نویسیم . Use Case ها همون تعاملات کاربر با اپلیکیشن هست ، یعنی کاربر فلان کار رو اگه بکنه چی صدا زده بشه .لایه App :به این لایه Presentation هم می‌گن . این لایه همون لایه MVVM ما حساب میشه که توش View ها و View-Model هامون رو داریم .لایه های فرعی :یک سری چیز مثل Utils و ... که طبقه بندی خاصی نمیشه براشون ارائه داد اینجا هستند ، همین طور می‌تونیم برای DI هم یک لایه جدا در نظر بگیریم و کارایی از این قبیل .خب دیگه تعاریف تئوری بسه ، وقتشه کد بزنیم !!!نکته : یکی از کارهایی که در مقالات دیدم انجام می‌دن جدا کردن لایه Domain و Data به حالت یک ماژول (لایبری) بوده که اسمش رو core میذاشتن ، و ما هم همینکار رو می‌کنیم .خب طبق نکته بالا ابتدا یک ماژول جدید ایجاد می‌کنیم ، نکته ای که باید توجه کنیم اینه که این ماژول نباید کتاب خونه مخصوص اندروید باشه بلکه طبق عکس زیر باید گزینه Java/Kotlin Library رو انتخاب کنید (چون این دو لایه قراره pure kotlin یعنی کاتلین خالص باشند :حتما این گزینه رو انتخاب کنیدبعد از اون هم باید این ماژول رو به App اضافه کنید که یحتمل بلدید ولی اگر نیستید در gradle این طور این کار رو می کنیم :dependencies{// more codeimplementation project(&#039;:core&#039;)}قراره در این بخش سه لایه Domain ، Data و Use-Case (برخی منابع Instructor(تعامل کنند) هم می‌‎گن) رو ایجاد بکنیم :ما برای ارتباط با سرور از این API استفاده می‌کنیم : https://jsonplaceholder.typicode.com/از لیست API هایی که در اختیار داریم فقط با post و user کار داریم ، در لایه Domain که قراره لیست مدل دیتاهای ما باشن این دو کلاس رو ایجاد می‌کنیم : https://gist.github.com/sasssass/44b848b14ef9f69fb8647e7b4e6334b7 و https://gist.github.com/sasssass/3224013164cd6a488d619b065b0250de خب حالا نیاز به مفهومی به نام DataSource داریم ، یک DataSource طبق معنیش یعنی منبع داده و شامل یک Interface به ازای هر مدل هست که توش توابعی برای دسترسی به مدل قرار داده شده ، مثلا توابع مثل گرفتن مدل ، اضافه کردن (مثلا در دیتابیس یا ...) ، حذف و ...چون دو مدل داریم باید دو DataSource داشته باشیم ، این DataSource ها در لایه Data قرار می‌گیرن : https://gist.github.com/sasssass/3eee299940bca271496d6bdf08442920 و https://gist.github.com/sasssass/f0d5980fb2a824d8f7f4ce2c88b503a0 مفهوم دیگری که داریم Repository ها هستند ، به ازای هر DataSource یک Repository خواهیم داشت ، Repository  کلاس هایی هستند که یک جنس از DataSource مورد نظر می‌گیرند (این DataSource در لایه Framework پیاده سازی خواهد شد) و توابعی دارند که از توابع DataSrouce استفاده می‌کنند ، به عنوان نمونه به PostRepository توجه کنید : https://gist.github.com/sasssass/1c3fa3a261072218403c54fc4bdaafa4 نکته : چرا از suspend استفاده شد ؟ اگر معنی این کلمه کلیدی و کاراییش رو نمی‌دونید به سری مقالات Coroutines بنده مراجعه کنید (مقاله 1 ، مقاله 2 ، مقاله 3 ، مقاله 4 ، مقاله 5) چون ما قراره ارتباط با سرورمون با Coroutines ترکیب بشه توابع رو suspend می‌کنیم .تمرین : UserRepository رو خودتون بنویسید .به این کاری که کردیم Repository pattern می‌گن ، این الگو یک نوع انتزاعی کردن دسترسی به داده هاست ، یکی از کاربردهاشم اینه که به وسیله اون میشه unit test ها رو پیاده کرد . چون Repository به DataSource وابسته است نه به DataSourceImp (Imp = implantation) پس جزئیات پیاده سازی DataSource رو نمی‌دونه و این از جهت جدا سازی کلاس های برنامه مفیده .خب حالا باید بریم سراغ Use-Case ، یکبار دیگه Use-Case رو این طور تعریف می‌کنیم : هر کلاسِ Use-Case معادل یک Action کاربر/سیستم در برنامه است . پس به ازای هر حرکت کاربر باید یک Use-Case تعریف کنید . برای مثال من می‌خوام Use-Case ای رو داشته باشم که با اون همه Post ها رو بگیرم ، در Use-Case باید به Repository مورد نظر دسترسی داشته باشیم ، مثلا این یک نمونه از Use-Case ها خواهد بود : https://gist.github.com/sasssass/c780e374568ce71aa76680aebcfffca9 در مورد invoke ، این لغت کلیدی در واقع یک اپراتور هست ، اگر ما به یک کلاسی invoke بدیم (override کنیم) ، می‌تونیم از اون کلاس به عنوان یک تابع استفاده کنیم ، مثلا به این نمونه دقت کنید :class Greeter(val greeting: String) {    operator fun invoke(target: String) = println(&quot;$greeting $target!&quot;)}val hello = Greeter(&quot;Hello&quot;)hello(&quot;world&quot;)  // Prints &quot;Hello world!&quot;برای تمرین GetPostByUserIDUseCase رو خودتون پیاده کنید .خب تا اینجای کار باید قسمت core به این شکل دراومده باشه (من همه Use-Case ها و ... رو پیاده نکردم) :الان کار ما در این قسمت تمومه و باید بریم سراغ قسمت App ، ما در این قسمت نیاز داریم که DataSource ها پیاده سازی بشن ، برای مثال من FromServerPostDataSource رو دارم که مشخص می‌کنه این پیاده سازی DataSource مربوط به Post هاست که قراره از Server خونده بشه (اسم خیلی جالب نیست و صرفا آموزشیه) ، ما در این قسمت به api هم نیاز داریم ، برای قسمت هایی که کامنت گذاشته شده نیاز داریم که یک DB هم اضافه کنیم که از این کار صرف نظر می‌کنیم ، ابتدا کد api رو می‌بینیم (با استفاده از Retorfit) و بعد کد DataSource رو : https://gist.github.com/sasssass/319677b9974ccefddbbab23f24e72496 و https://gist.github.com/sasssass/af3174e6f21dac882257c19955adf560 خب فعلا قسمت Clean تمام شده و باید با MVVM تلفیق کنیم ، در معماری MVVM نیاز به View-Model داریم ، در View-Model نیاز به Use-Case داریم و در Use-Case نیاز به Repository ، در Repository هم نیاز به DataSource ای داریم که همین الان کلاسشو رو ساختیم ، ما به جز View-Model بقیه اجزا رو در بالا معرفی کرده بودیم ، من برای راحتی کار تصمیم گرفتم DI رو هم در قضیه دخیل کنم و از Hilt استفاده کردم ، علاوه بر اون چون از ترکیب Retrofit و Coroutines هم استفاده کردیم پس نیازه این سه مقاله رو بخونید :قسمت اول Hiltقسمت دوم Hiltارتباط سرور و Coroutinesبا توجه به این سه مقاله من این چند کلاس رو اضافه می‌کنم ، RemoteErrorEmitter ، RetrofitBuilder و Api که Api رو قبلا دیدیم ، همین طور ماژول apiCall رو هم خواهیم داشت که در مقاله ارتباط سرور و Coroutines به تفضیل توضیح داده شده : https://gist.github.com/sasssass/2aad2872e04eb30bd783e47cbc62ceea و https://gist.github.com/sasssass/108c01d4e922568504b35e82497c6516 و https://gist.github.com/sasssass/0492db329a527bd7b90eae1cda223e93 حالا نیاز به DI داریم ، کاری که می‌کنیم اینه ، یک AppModule درست می‌کنیم که Repository و این جور چیزا رو برامون Provide کنه (ما می‌تونستیم از constructor injection استفاده کنیم ، ولی ترجیح دادم تک به تک provide بشن چون قرار بوده پارامترهایی که دارن provide میشن داخل خودشون از sdk اندروید استفاده نکنند البته hilt جزو sdk اندروید نیست ولی چون به Framework اندروید ربط داشت این تصمیم رو گرفتم ، ممکنه تصمیم جالبی نباشه و اگه خواستید می‌تونید با همون constructor injection برید) : https://gist.github.com/sasssass/293f9a8394c959c76429e48f161c4aed یک موردی که در مقاله های سری Hilt نیست اینه که به دلایلی به ما اجازه نمیده چیزایی که می‌خوایم رو تو ViewModel تزریق کنیم ، برای همین ما خودِ کلاس ViewModel رو بدون constructor injection درست می‌کنیم : https://gist.github.com/sasssass/3008f35e08f52aa568f1f084e88ad436 توضیحی که لازمه بدم اینه که طوری که من معماری رو چیدم بر پایه این شده که ما در View-Model به Use-Case متکی هستیم ، با استفاده از Use-Case ها درخواست های کاربر رو انجام می‌دیم .حالا  باید ViewModel رو داخل Activity تزریق کنیم برای برای حل قضیه Inject کردن ViewModel نیاز به MyViewModelFactory داریم (رجوع کنید به این مقاله) : https://gist.github.com/sasssass/1290b4f5d2e0d394647d58947965cdc1 حالا به راحتی میشه View-Model رو داخل Activity تزریق کرد ، همچنین ما نیاز داریم Use-Case مورد نظر رو داخل Activity تزریق کنیم تا در ساخت View-Model ازش استفاده کنیم ، منتها برای اینکه اصول DI رو کامل رعایت کنیم خود این ViewModelFactory رو هم باید داخل Activity تزریق کنیم ، پس یک ماژول DI برای Activity می‌سازیم : https://gist.github.com/sasssass/bae6b62860f9689dfb380711068891fb و تمام ، حالا خودِ Activity رو ایجاد می‌کنیم : https://gist.github.com/sasssass/528a2ffe01d16cdc66c43fb328ea91ea وقتی که برنامه رو اجرا می‌کنید می‌بینید که Toast مورد نظر نشون داده میشه ، برای تمرین قسمت های دیگه برنامه رو خودتون کامل کنید تا دستتون بیاد به چه صورته ، مثلا بقیه Repo ها و DataSource ها و ... رو بسازید (پروژه به همین صورت تو گیت پوش شده تا بتونید خودتون کاملش کنید) :لینک گیت مقاله رو هم در این لینک می‌تونید ببینید .من رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید !!!اگه دوست داشتید می‌تونید به صفحه Spotify و SoundCloud بنده هم برید و موسیقی های منو گوش بدید !!!</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Sun, 09 May 2021 09:29:17 +0430</pubDate>
            </item>
                    <item>
                <title>ماژولار سازی Gradle با Kotlin-DSL</title>
                <link>https://virgool.io/@shobeyri.ali/%D9%85%D8%A7%DA%98%D9%88%D9%84%D8%A7%D8%B1-%D8%B3%D8%A7%D8%B2%DB%8C-gradle-%D8%A8%D8%A7-kotlin-dsl-vjzligctxgyy</link>
                <description>فرض کنید در یک پروژه چندین ماژول داشته باشیم و dependency های مشترکی هم داشته باشن ، اگر بخوایم این dependency ها رو آپدیت ، دانگرید یا هر گونه تغییری بدیم باید تک تک بریم و فایل gradle اون ها رو عوض کنیم یا حتی اگر یک ماژول داشته باشیم شاید علاقه داشته باشیم کمی فایل gradle و تنظیمات اون رو مرتب کنیم ، برای این مساله ما نیاز داریم نوعی اسکریپت رو برای gradle مون ایجاد کنیم .زبان های DSLقبل از هر چیز باید بدونیم که می‌تونیم زبان های برنامه نویسی رو به دو دسته DSL و GPL تقسیم کنیم ، DSL مخفف Domain-specific language هست ، یعنی زبان هایی که مختص یک حوزه به خصوص هستند و GPL به معنی General purpose languages یعنی زبان هایی که برای اهداف مختفی طراحی شدند ، اگر بخواهیم از DSL مثال بزنیم میشه به SQL اشاره کرد ، شما با SQL می تونید اپ اندروید بنویسید ؟ یا یک سایت بالا بیارید ؟ نه ! فقط برای کار با دیتابیس طراحی شده اما زبانی مثل Java رو هزار تا کار می‌تونید باهاش بکنید ، می‌تونید اپ جاوا بنویسید ، می‌تونید Backend بنویسید ، می‌تونید در سخت افزار ازش استفاده کنید و ... .حالا زبان Kotlin چیه ؟ مسلما باید GPL باشه و هست اما یک زبان زیرمجموعه هم تحت عنوان Kotlin-DSL داره ، این زبان گرامر متفاوتی نداره و از همون گرامر Kotlin پیروری می‌کنه ، ما در فایل gradle مون از زبانی به اسم Groovy-DSL استفاده می‌کنیم (برای اطلاع بیشتر در مورد Groovy این لینک رو مطالعه کنید) ، حالا ما می‌تونیم برای فایل gradle مون از Kotlin-DSL استفاده کنیم .شروع کاربرای start قضیه طبق عکس زیر این پوشه رو در root پروژه تون ایجاد کنید :ایجاد فایل buildSrcحالا ما به یک gradle جایگزین نیاز داریم ، برای این منظور در پوشه ای که الان ساختیم فایلی به اسم build.gradle.kts رو ایجاد می‌کنیم (فرمت فایل kts خواهد بود) ، حالا باید Kotlin-DSL رو برای پروژه فعال کنیم ، برای این کار کد زیر رو در فایلی که الان ساختید کپی کنید و بعدش پروژه رو synch کنید : https://gist.github.com/sasssass/dedefdc6024df4c6d8bc24ead9d1c4ca خب حالا پلاگین Kotlin-DSL فعال شده ، اگر روی پوشه buildSrc بیایید و یک Directory جدید بسازید به شما پیشنهاداتی میده ، طبق عکس زیر گزینه ای که هایلایت شده رو انتخاب کنید تا این پوشه ساخته بشه :ایجاد پوشه srcخب ، کاری که ما می‌خوایم انجام بدیم اینه که فایل gradle ماژول App و همین طور فایل gradle کل پروژه بیانیه سری اطلاعات رو از اینجا بخونن ، این اطلاعات چیزایی مثل minSdkVersion ، versionName و dependency های ما هستن .در ابتدا در این پوشه ای که الان ساختیم یک فایل به نام Application ایجاد می‌کنیم ، تو این فایل قراره اطلاعات خودِ نسخه (همون versionName و اینا) رو تنظیم کنیم . https://gist.github.com/sasssass/78b676e78fd29ea7bfa3bfcb34007d8f حالا می‌خوایم dependency ها و version هاشون رو مشخص کنیم ، پس دو کلاس به هم اسامی می‌سازیم : https://gist.github.com/sasssass/0d5e5632061d5f85a033a448e1f5cee5 و https://gist.github.com/sasssass/1d9e950f0c9efbb512ae3420a65cd3f5 من برای gradle کلی دیگه این کار رو انجام نمی‌دم چون مشابهه ، حالا باید در فایل gradle ماژول App بیاییم و این ها رو به هم وصل کنیم پس gradle به این صورت در میاد : https://gist.github.com/sasssass/48cf88c47f1e17ed7c429be462ddafc3 خب حالا مزیت های این کارایی که کردیم چیه ؟ برای اینکه بهتر بفهمید چقدر کدهامون قدرتمند تر میشه یک تغییری در کدهای بالا می‌دیم ، می‌خوایم به جای اینکه دونه دونه dependency ها رو اضافه کنیم کلشو با یه خط اضافه کنیم ، برای این کار اول در کلاس Dependency یک تابع ایجاد می‌‎کنیم : https://gist.github.com/sasssass/edeee79872a84b35d672941dc250522c حالا این تیکه از فایل gradle رو به این صورت تغییر می‌دیم : https://gist.github.com/sasssass/4303322ef83ee7adfa84769ed0874841 و این طوری کل dependency هامون یکجا add شدند ! مزیت بزرگی که Kotlin-DSL به ما می‌ده استفاده از syntax خودِ Kotlin برای Gradle هست ، مثلا در مثال بالا ما از یک تابع واسطه استفاده کردیم (که بی مورد بود صرفا مثلا آموزشی بود) .برای مطالعه بیشتر این مقاله رو پیشنهاد می‌کنم .من رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید ???اگه دوست داشتید می‌تونید به صفحه Spotify و SoundCloud بنده هم برید و موسیقی های منو گوش بدید ???</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Sun, 21 Feb 2021 03:23:10 +0330</pubDate>
            </item>
                    <item>
                <title>ساخت UI با Jetpack Compose</title>
                <link>https://virgool.io/CodeLovers/%D8%B3%D8%A7%D8%AE%D8%AA-ui-%D8%A8%D8%A7-jetpack-compose-%D9%82%D8%B3%D9%85%D8%AA-1-rbfgnculbqoy</link>
                <description>برای ساخت UI در اندروید چه راه هایی هست ؟ با xml بسازید یا به صورت کد بنویسید ، راه xml مسلما بسیار راحت تره ، اما جدیدا اندروید به تقلید از Apple ابزاری به اسم Compose رو معرفی کرده که باهاش می‌تونید UI رو به صورت کد ولی خیلی راحت ایجاد کنید ، در این مقاله ما چند مثال کوچک و یک سری کلیات از قضیه رو بررسی می‌کنیم و در سری های بعدی از این سری Compose به شرح و بسط اون می‌پردازیم .Android Composeمقدمه و شروع کاربرای شروع با ملزومات پروژه آغاز می‌کنیم ، فایل gradle شما باید شامل موارد زیر باشه : https://gist.github.com/sasssass/fab9784b07fad1e8fc009bf748676a25 و  https://gist.github.com/sasssass/067e8078f5ce0ee7ae7012b9b931bffc خب حالا چرا می‌گن بهش Compose ؟ در این ابزار ما از توابع composable (قابل ترکیب) استفاده می‌کنیم ، تو این توابع به جای اینکه از View هامون شئ بگیریم می‌آییم ویژگی هاشون رو (مثلا اگه TextView باشه متنشو) مشخص می‌کنیم و تابع مورد نظر اون View رو صدا می‌زنیم .نکته : برای استفاده از Compose (در تاریخی که این مقاله نوشته شده) باید نسخه Canary رو نصب کنید . در حین نصب این نسخه اگه به مشکل خوردید دو تا کار رو انجام بدید ، یکی JDK ورژن 11 رو نصب کنید و این JDK رو بهش بدید و مساله دیگه اینکه خودش بهتون میگه Gradle رو آپدیت کنیداین توابع با انوتیشن Composable مشخص می‌شن ، برای شروع یک پروژه خالی بسازید با یک اکتیویتی ساده ، حالا می‌خوایم یک TextView بندازیم توش ، به جای اینکه از setContentView استفاده کنیم و بهش layout پاس بدیم می‌آییم از تابع setContent استفاده می‌کنیم : https://gist.github.com/sasssass/f8f7a9c4ee17554f35673299ec695a25 حالا فرض کنید به صورت مستقیم نمی‌خوایم Text رو ایجاد کنیم بلکه با یک تابع واسطه قراره این کار رو بکنیم ، توابعی که برای ما عملیات ایجاد View رو در این ابزار انجام می‌دن با انوتیشنِ Composable مشخص می‌شن (اگه خودِ Text رو هم تعریفش رو داخل کتابخونه ببینید ، این انوتیشن رو داره) ، فرضا یک تابع می‌نویسیم که همین Hello World رو برامون چاپ کنه ، رو نمایش بده ، اما یک مساله دیگه رو هم بهش اضافه می‌کنیم ، فرض کنید نمی‌خوایم Run بگیریم تا خروجی رو ببینم و می‌خوایم یک Preview از قضیه رو کنار کد داشته باشیم ، برای این کار باید اون تابع رو با انوتیشن Preview مشخص کنیم : https://gist.github.com/sasssass/50a4fbd28a68c47c76be13637e96b986 و حالا کنار کدهامون این قسمت رو داریم :لایه بندیبه ترتیبی که شما توابع Composable رو صدا بزنید به همون ترتیب لایه بندی تون انجام میشه ، یعنی اگه تابع B درون تابع A صدا زده بشه پس layout تابع B فرزند layout تابع A میشه ، نکته دیگه در مورد Arrange کردن View هاست ، فرضا سه Text پشت هم بنویسیم : https://gist.github.com/sasssass/b5c95d016878ebdaba22fddbb087ea50 خروجی بسیار کثیف خواهد شد :پس باید به نوعی ترتیب قرارگیری عناصر رو هم مشخص کرد ، با استفاده از تابع Column میشه View ها رو به ترتیب از بالا به پایین چید ، کمی کد رو کامل تر کنیم ، فرض کنید قصد دارید style ای هم بهش بدید ، مثلا یک padding ، همین طور فرض کنید نمی‌خوایم همش Text باشه ، می‌آییم یک Image هم اضافه می‌‎کنیم (ورودی اون خودش تابع imageResource خواهد بود) ، برای دادن style ها باید در ورودی توابع Composable مقادیری که می‌خواهیم رو مشخص کنیم : https://gist.github.com/sasssass/8c3907fc904ab852ecf0d738e79747f2 و خروجی :همچنین برای مقادیری مثل فونت ، سایز و ... می‌تونید به تعریف تابع مورد نظرتون رجوع کنید ، مثلا اگه تعریف تابع Text رو ببینیم :حالا فرضا می‌خوایم رنگش رو آبی کنیم و یک پدینگ به خودِ Text هم بدیم ، همین طور می‌خوایم به عکسمون یک ارتفاع ثابت بدیم و ScaleType ش رو هم تغییر بدیم : https://gist.github.com/sasssass/e7cea332a66f1ae749d206e58015afd5 و خروجی :یادآوری : بالاتر گفتیم که برای style دادن از modifier استفاده می‌کنیم ، پس مسائلی مثل ارتفاع ، عرض ، پدینگ و ... رو با این ابزار تغییر می‌دیممتریال دیزاینابزار Compose از قواعد متریال دیزاین پشتیبانی می‌کنه ، فرض کنید عکس بالا رو می‌خوایم دورش رو یه radius بندازیم ، تو xml من این کار رو با CardView انجام می‌دادم ولی اینجا با modifier و تابع clip : https://gist.github.com/sasssass/356cff09159da1bc72275765132c32d5 که خروجی ما میشه :همچنین برای style دادن به متون هم ویژگی های جالبی داره (تقریبا شاید اینجاها متوجه مزیت‌های Compose به XML بشید) : https://gist.github.com/sasssass/5de1bb15ff0fb857ab266da9252c8488 و خروجی به شکل زیبا و راحت به این صورت میشه :نکته : header از 1 تا 6 و body مقدار 1 و 2 می‌تونه باشهخب ، تو این مقاله یک ایده کلی از قضیه گرفتید ، در مقاله‌های سری بعد از این مجموعه ابزار Compose رو با تفضیل بیشتر و جزء به جزء تر بررسی می‌کنیم .من رو در لینکدین ، اینستاگرام و یوتیوب دنبال کنید ???اگه دوست داشتید می‌تونید به صفحه Spotify و SoundCloud بنده هم برید و موسیقی های منو گوش بدید ???</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Tue, 19 Jan 2021 10:21:58 +0330</pubDate>
            </item>
                    <item>
                <title>انواعِ Class ها در کاتلین - قسمت دوم</title>
                <link>https://virgool.io/@shobeyri.ali/%D8%A7%D9%86%D9%88%D8%A7%D8%B9%D9%90-class-%D9%87%D8%A7-%D8%AF%D8%B1-%DA%A9%D8%A7%D8%AA%D9%84%DB%8C%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-booi3y63bqlb</link>
                <description>قبل از شروع این مقاله ترجیحا قسمت اول رو مطالعه کنیدکلاس enumمعنی enum در لغت یعنی شمردن ، پایه ای ترین کاری که شما با enum انجام می‌دید تهیه یک مجموعه از مقادیره ، بر خلاف جاوا در کاتلین enum ها خودشون از جنس class هستند :در شکل بالا enum ما شامل یک سری مقادیر یا نوع هست که وضعیت Network رو شرح میدن ، همچنین شما می‌تونید یک contructor برای enum خودتون ایجاد کنید :در مثال بالا وقتی ما از بین Army ، مقدار Captain رو انتخاب کنیم ، مقدار gun برابر &quot;Beretta Colt&quot; قرار داده میشه ، برای دسترسی به ردیف و اسم هم از توابع زیر استفاده میشه :یکی دیگه از استفاده های enum برای ساخت کلاس های بی نام و نشان (anonymous) هست ، در این حالت شما در بدنه enum یک سری توابع abstract رو می‌نویسد و بعد در عناصر enum (در همه شون) اون رو override می‌کنید (تابع رو باید انتها بنویسید و اون سمیکالن ته رو هم باید بذارید) :نکته : گفتیم enum ها خودشون کلاس هستند ، پس آنچه در کلاس انجام می‌دید اینجا هم می‌تونید انجام بدیدکلاس innerوقتی شما در بدنه یک class بیایید یک class دیگه تعریف کنید بهش می‌گیم nested ، حالا می‌تونیم این کلاس nested رو با کلمه inner مشخص کنیم ، وقتی کلمه inner رو میذاریم حالا می‌تونیم از کلاس nested به کلاس outer (کلاس اصلی) دسترسی پیدا کنیم و مقادیر و توابعش رو استفاده کنیم :کلاس inlineقبل از اینکه به سراغ کلاس inline برویم ، به سراغ تابع inline می‌‍ریم ، وقتی شما یک تابع تعریف می‌کنی این تابع حافظه اشغال می‌کنه و یک سری پردازش مخصوص به خودش رو باید انجام بده ، بعضی وقت ها شما توابعی رو تعریف می‌کنید که لزوما نیاز ندارند تابع باشند ، یعنی می‌تونن مستقیم تو خود کد نوشته بشن پس اینجا یک حافظه بی‌خودی گرفته میشه ، برای اینکه این مساله حل بشه از توابع inline استفاده میشه ، وقتی شما تابع رو inline بکنید ، کامپایلر هر وقت اون تابع صدا زده بشه میاد بدنه اون تابع رو جایگزین می‌کنه با جایی که تابع صدا زده شده :کلاس inline هم تقریبا مفهوم مشابهی داره و بهبود های حافظه در استفاده از این کلاس صورت می‌گیره ، این کلاس یک سری شرایط داره :تابع init ندارهدر constructor فقط یک متغیر می‌تونید تعریف کنید (که باید val باشه)در توابع set و ... نمی‌تونید از field استفاده کنید ، به طور یعنی setter خاصی نمیشه تعریف کرد و متغیرها باید val باشندحتما باید final باشه پس کلاس های دیگه حق ارث بری ازش رو ندارندخب چرا ما باید با وجود این همه محدودیت از این کلاس استفاده کنیم ؟ یک مثال در این زمینه می‌زنیم ، فرض کنید یک کلاس به اسم Item دارید ، این کلاس چند متغیر مثل اسم ، رنگ و قیمت رو داره ، حالا این قیمت هم می‌تونه به ریال باشه هم تومن ، یک راه پیاده سازی به شکل زیره :اما اضافه کردن دو تا کلاس می‌تونه بخش زیادی از حافظه رو درگیر کنه ، پس می‌آییم به این شکل درش میاریم :چیزی که کامپایلر موقع اجرای این کلاس می‌بینه به این شکله (شکل پایین رو نگاه کنید و با توجه به اون فکر کنید که چرا نمی‌تونیم بیشتر از دو متغیر در کلاس inline داشته باشیم) :نوعِ Objectبرخی اوقات نیاز داریم یک تعریف کلی از یک کلاس داشته باشیم بدون آنکه نوعی برای اون تعریف کنیم ، مثلا فرض کنید یک interface دارید ، می‌خواید از اون Interface (یا کلاس عادی یا ...) یک کلاس بگیرید و کلاس گرفته شده رو به یک شئ پاس بدید ، اینجا با استفاده از کلمه object یک کلاس بی نام و نشون می‌سازیم و کاری که می‌خوایم رو باهاش می‌کنیم :در مثال بالا می‌تونید به جای اینکه object رو صرفا از یک Interface بگیرید ، از چندین interface بگیرید و حتی تا یک کلاس رو بهش ارث بری بدید (یادآوری که در جاوا و کاتلین ارث بری چندگانه نداریم) ، حالا فرض کنید صرفا یک کلاس کوچولو می‌خوایم و قصد تعریفش رو نداریم :نکته ای که باید در این مورد رعایت کرد اینه که دسترسی به متغیر ها در مثال بالا فقط وقتیه که اون object به صورت local (مثل همین عکس بالا) یا private باشه ، اگه public باشه حق دسترسی نداریم :حالت دیگه اینه که یک کلاس کلی می‌خوایم که کلا یک instance ازش در برنامه وجود داشته باشه (مثلا مثل Singleton) :شما داخل یک object حق تعریف یک object دیگه رو دارید (مثل عکس بالا) ولی داخل یک class حق این کارو ندارید ، برای اینکه بتونیم داخل یک class یک object تعریف کنیم از companion object استفاده می‌کنیم (مثل static کردن یک تابع یا متغیر در جاوا) :اگر دقت کنید برای دسترسی به doSomething مثل یک object عمل شد و نیازی به Instance گیری از MyClass نبود ولی برای دسترسی به doMyClassThing نیازه که یک شئ بگیریم ، بنابراین جلوی MyClass پرانتزی گذاشتیم تا constructor صدا زده بشه و یک شئ از MyClass گرفته بشه و بعد بتونیم به doMyClassThing دسترسی پیدا کنیم ، شما همچنین می‌تونید این companion object رو از چیزای دیگه ارث بگیرید (مثلا از یک Interface یا ...) ، در مورد singleton قبلا یک مقاله ای گذاشته بودم که برای فهم بهتر می‌تونید اونو بخونید .من رو در لینکدین و اینستاگرام دنبال کنید ???اگه دوست داشتید می‌تونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Fri, 15 Jan 2021 13:00:28 +0330</pubDate>
            </item>
                    <item>
                <title>انواعِ Class ها در کاتلین - قسمت اول</title>
                <link>https://virgool.io/CodeLovers/%D8%A7%D9%86%D9%88%D8%A7%D8%B9%D9%90-class-%D9%87%D8%A7-%D8%AF%D8%B1-%DA%A9%D8%A7%D8%AA%D9%84%DB%8C%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-ushfr4kougn1</link>
                <description>در کاتلین یک Class می تونه انواع مختلفی داشته باشه :کلاس عادیکلاس dataکلاس sealedکلاس enumکلاس innerکلاس inlineنوعِ objectکلاس عادیکلاس عادی از اسمش مشخصه ، عادیه و خیلی چیز خاصی نداره ، تو همه زبان ها هم تقریبا یکیه مفهومش !کلاسِ Dataاین کلاس هم در واقع شبیه کلاس عادیه با این تفاوت که یک سری متدها بهینه شدند، این تیپ کلاس ها همون طوری که از اسمش مشخصه برای Data ها استفاده میشن ، مثلا دیتایی که داره از سمت سرور برمی‌گرده ، مثلا متد equal ، یک تست با هم ببینیم :می‌بینید که equals در کلاسی که با data مشخص شده جواب صحیح میده ولی برای کلاس عادی نه ! برای کلاس عادی شما خودتون باید equals رو override کنید ، یا یک تابع دیگه مثل toString رو مثال بزنیم :تو کلاسی که data هست خیلی شیک میاد مقادیر رو چاپ می‌کنه ولی تو کلاس عادی برای محل مموری شئ رو چاپ کرده ، تابع hashCode هم همین طور :کلاس‌هایی که عادی تعریف شده از نظر سیستم یکی نیستند پس دو تا hash مختلف می‌گیرند ولی کلاس‌های data با اینکه دو شئ مختلفند ولی چون عناصر یکی دارند پس hash یکسان دارند .یک تابعی هم که در data هست اما در کلاس عادی نیست تابع copy هست (و دیگه نیازی به دیزاین پترن prototype نیست) ، در مثال زیر ما مقدار رو کپی می‌کنیم ولی مقدار a رو تغییر می‌دیم :و در آخر ، تابعی با فرمول componentN ، این تابع که به جای N یک شماره قرار می‌دیم ، عنصر شماره N ام اون کلاس رو در کلاسِ data برمی‌گردونه :کلاس sealedکلمه sealed به معنی &quot;مهر و موم شده&quot; هست ، کلاس sealed شبیه یک Enum عمل می‌کنه ولی پیشرفته تر ، تعریف sealed کلاس رو به این صورت میگیم : &quot;یک کلاسِ sealed کلاسی است که امکان ارائه یک سلسله مراتب (hierarchie) محدوده شده را می‌دهد که در آن واحد یک عنوان را انتخاب کنید&quot; ، نفهمیدید ؟ مساله نداره با یک مثال بهتر متوجه میشید ، ببینید در یک کلاسِ sealed ما یک سری subclass هایی رو قرار می‌دیم ، مثلا :ساختمان یک sealed class به این صورته که بعد از نوشتن اسم کلاس درون بلاکِ مربوط به sealed class یک سری class تعریف می‌کنیم ، حالا زمان مقداری دهی می‌تونیم بر اساس شرایط از یکی از این کلاس ها شئ بگیریم .تو کد بالا sealed class ما میشه NetWorkRespone ، این کلاس وظیفه داره وضعیت response رو مشخص کنه ، ما سه نوع وضعیت داریم ، NoInternet ، AnohterError و MyResponse . بر اساس ورودی ما مشخص می‌کنه که متغیر response چه مقداری رو داشته باشه ، می‌بینیم که اولش چون NoInternet گذاشتیم تشخیص داده که از جنس NoInternet هست و بعدش که وضعیت رو تغییر دادیم می‌بینیم که از جنس AnohterError شد .اگه دقت کنید یکی از فواید sealed کلاس ها در نگه داری وضعیت ها هستند ، مثلا همین مثالی که دیدیم وضعیت response رو بر حسب شرایط تغییر داده ، یک مثال دیگه ببینیم :توی این مثال یکمی قضیه فرق کرد ، اولا که ما این دفعه کلاس های داخلیمون رو از خودِ MyState ارث بردیم ، ثانیا دومین آیتم class نیست بلکه object هست ، توی این حالت نیازی به استفاده از &quot;is&quot; نیست (البته می‌تونید هم بذارید ، دلیل اختیاری بودنش هم اینه که object یک نوع یونیک هست ، یعنی از هر object ها واحد هستند (single static instance) ، اگر متوجه نشدید در سری دوم این مقاله که روزهای آینده خواهم نوشت بیشتر object رو مورد بررسی قرار می‌دیم .باقی انواع کلاس ها رو در سری دوم مقاله بررسی می‌کنیم (به زودی ...)من رو در لینکدین و اینستاگرام دنبال کنید ???اگه دوست داشتید می‌تونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Thu, 07 Jan 2021 01:33:31 +0330</pubDate>
            </item>
                    <item>
                <title>توابع و اپراتورهایِ Collection در Kotlin - قسمت 2</title>
                <link>https://virgool.io/@shobeyri.ali/%D8%AA%D9%88%D8%A7%D8%A8%D8%B9-%D9%88-%D8%A7%D9%BE%D8%B1%D8%A7%D8%AA%D9%88%D8%B1%D9%87%D8%A7%DB%8C%D9%90-collection-%D8%AF%D8%B1-kotlin-%D9%82%D8%B3%D9%85%D8%AA-2-itvdk3siftqk</link>
                <description>در ادامه مقاله قبلی توابع دیگری از Collection ها در کاتلین برای شما توضیح میدم ... ، به ادامه مقاله توجه کنید .کالکشنی از تمبر ها
توابع محاسباتیاین توابع عملیات هایی ریاضی مانند ماکسیسمم ، مینیمم ، میانگین و ... را در خود دارند که در کد پایین مشخص هستند ، نکته در مورد کاستومایز کردن این هست که شما با اضافه کردن کلمه By به انتهای هرکدام از این توابع می‌‌تونید یک تابع کاستوم بسازید ، مثلا در مثالی که زده شده تابع مینمم برای لیستی از String ها کاستومایز شده ، اگر String مورد نظر برابر Ali باشه بهش عدد صفر مپ میشه وگرنه عدد یک ، بنابراین مینمم میشه عدد صفر پس در نهایت Ali به عنوان مینیمم برمیگرده ، می‌‌تونیم چیزایی مثل طول رشته یا ... رو هم به عنوان این عدد قرار بدیم : https://gist.github.com/sasssass/48b5299f406afa6475745f9cc0c5e34f حل مشکل OutOfBoundMemoryیکی از مصاعب در کار با Collection ها اینه که یک وقت خارج از محدوده اون Collection (مثلا لیست) نخواید ازش عضو بگیرید ، یعنی اگه کلا ده تا عضو داره نریم سراغ عضو یازدهمی ، این کار بسیار راحت قابل حله ، در کد زیر تابع اول مثل حالت عادی عمل می‌کنه و فایده نداره ، تابع دوم اگه خارج از محدوده باشه Null برمی‌گردونه و تابع سوم اگر خارج از محدوده باشه عدد -1 رو به متغیر میده : https://gist.github.com/sasssass/d9f883b8a2c21ea6f5766185323dc0da توابع Mappiingبه طور کلی Map کردن یعنی نسبت دادن یک مقدار به مقدار دیگر (مثلا بازیکنان فوتبال به شماره هاشون Map شدند ، اگه شما شماره دو رو بگیری به بازیکن فلانی می‌رسی اگه شماره سه رو بگیری به بازکین بهمانی !!) https://gist.github.com/sasssass/97edde15f6f64ca8fc429a624a43379d توابع Zippingاین اپراتور (دقت کنید گفتم اپراتور نه تابع ، چرا؟)دو لیست از شما گرفته و اجزای نظیر (دارای یک index یکسان) رو به هم وصل می‌کنند ، یعنی چی ؟  یعنی مثلا شما لیستی داری مثل : 1.علی 2.حسین 3.نقی 4.تقی و یک لیست دیگه 1.شبیری 2.کاهانی حالا لیست اول رو اگه Zip کنی با لیست دوم جواب میشه : 1.علی شبیری 2.حسین کاهانی . نقی و تقی چون عضو متناظر در لیست دوم ندارن به کار نمیان . https://gist.github.com/sasssass/a328fb4853cccb601b6607ea2a216d36 توابع Plus و Minesدر کاتلین می‌تونید بین دو لیست از اپراتور + و - استفاده کنید ! نمونه آن را در مثال زیر ببینید : https://gist.github.com/sasssass/8015b7ce217f75262fd7b11b3cc65860 توابع بسیار زیادتری در مورد Collection ها وجود دارند ولی من حس می‌کنم با گفتن تعداد بیشتری از این توابع صرفا سرگیجگی برای خواننده ایجاد میشه و سعی کردم اون هایی رو توضیح بدم که مطمئن هستم در طول توسعه یک اپلیکیشن یا ... حتما امکان داره بهش برخورد کنید و نیاز به n خط کد زدن اضافی نداشته باشید ! لینک نسخه اصلی مقاله (که از خود سایت کاتلین برداشته شده) در اختیار شما عزیزان هست که اگر خواستید با توابع بیشتری از دنیای کاتلین آشنا بشید .من رو در لینکدین و اینستاگرام دنبال کنید ???اگه دوست داشتید می‌تونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Sat, 12 Dec 2020 21:07:34 +0330</pubDate>
            </item>
                    <item>
                <title>توابع و اپراتورهایِ Collection در Kotlin - قسمت 1</title>
                <link>https://virgool.io/@shobeyri.ali/%D8%AA%D9%88%D8%A7%D8%A8%D8%B9-%D9%88-%D8%A7%D9%BE%D8%B1%D8%A7%D8%AA%D9%88%D8%B1%D9%87%D8%A7%DB%8C%D9%90-collection-%D8%AF%D8%B1-kotlin-%D9%82%D8%B3%D9%85%D8%AA-1-ktdbxb0tgqna</link>
                <description>کلغتِ Collection به معنی &quot;مجموعه&quot; یا &quot;گردآوری شده ها&quot; هست ، سه Collection معروف در جاوا و کاتلین موارد زیر هستن :لیست (List)مجموعه (Set) - به همون معنایی که در ریاضیات خوندید (عضو تکراری ندارد)مپ (Map) - که به صورت Key-Value است ، یک Key به یک Value مپ می‌شوداین عناصر به دو دسته read-only و mutable (تغییر پذیر) تقسیم بندی میشن که البته توابع لازمه برای cast کردنشون به هم وجود داره :از موارد بالا فقط Iterable رو نگفتم که interface ای هست شامل توابع لازم برای پیمایش Collection سازندهیکی از راه های ساخت اشیای بالا استفاده از فرمول name + of هست ، یعنی چه ؟ یعنی شما یک Set میخوای ؟ پس با setOf می‌تونی بسازیش ، یا یک Map به صورت Mutable میخوای ؟ با mutableMapOf می‌سازیش ، به نمونه های زیر دقت کنید : https://gist.github.com/sasssass/4e9f653443f66e540e4266b5346440a5 زمانی که می‌خواید Collection رو از اول و بدون عنصر اولیه بسازید هم به فرمول empty + name این کار رو می‌شه کرد (یا همون فرمول بالا رو بهش ورودی ندید) : https://gist.github.com/sasssass/d927c5786bc9035acff29fd6f81e714f برای لیست یک سازنده به صورت تابعی هم وجود داره ، ورودی اول میشه تعداد عنصر لیست و ورودی دومش تابع سازنده اجزای لیسته : https://gist.github.com/sasssass/677e8dd385b5b9727b24c3bbb1315e63 عملیات Copy و Castفرض کنید یک لیست داریم ، یک لیست دیگر (خالی) هم ایجاد می‌کنیم ، چطور لیست خالی را با لیست اول پر کنیم ؟ یکی از راه ها اپراتور &quot;=&quot; است که این طوری در واقع شما لیست دوم رو با لیست اول برابر قرار میدید ، پس هر تغییری روی یکی از لیست ها منتجر به تغییر روی لیست دیگر میشه پس این راه درست نیست ، با استفاده از فرمول to + name می‌تونید این کار رو بدون حالت بالا انجام بدید : https://gist.github.com/sasssass/b796169bf59922afa991106c1c854711 شمارشابتدایی ترین راهی که برای شمارش یا iterate کردن یک لیست وجود داره استفاده از حلقه for هست که همه بلدن ! ولی راه های حرفه ای تر چیان ؟هم List و هم Set چون از Iterable مشتق شدن قابلیت استفاده از این interface رو دارند که مبنی بر دیزاین پترن هم نامشه : https://gist.github.com/sasssass/2777983086c739d85f6734ff2a6b4b8e نکته جالب اینه که باز هم مثل توابعی که تا الان استفاده می‌کردیم ، می‌تونیم یک iterator خاص درست کنیم که از فرمول name + iterator بدست میاد ، مثال اول نشان دهنده پیماش رو به عقب و دومی نشان دهنده ویرایش در حین پیمایش است : https://gist.github.com/sasssass/771d7ee6b1ab343ee53defaf2ab34663 خروجیعملیات فیلترمسلما بارها پیش اومده که یک لیستی از سرور می‌گیرید و می‌خواید فیلترش کنید ، در کاتلین به راحتی می‌تونیم به این امر برسیم ، مورد اول فیلتر کردن اعداد زوج ، مورد دوم فیلتر کردن اعدادی که زوج نیستند (یا فرد هستند) ، مورد سوم فیلتر کردن اعداد کوچکتر از 4 با این تفاوت که حین عملیات فیلتر به index آنها هم دسترسی داشته باشیم است : https://gist.github.com/sasssass/06bbb6cf79552ff27091bad42eef16bb خروجیدر مورد لیست هایی که انواع متخلفی از داده با رو دارند فیلتری به نام filterIsInstance  ، تابع زیر مقادیری که از نوع Int باشند را برمی‌گرداند : https://gist.github.com/sasssass/ed8604029432040ba86c19d32ce396b8 اگر می‌خواید در حین فیلتر کردن لیست ها به دو دسته تقسیم شوند : https://gist.github.com/sasssass/110d05c2f95fca21a7c270aac1a30abd خروجیزمانی هست که نمی‌خواهید خروجی بگیرید ، فقط می‌خواهید بررسی کنید آیا فلان عنصری که بهمان شرط رو داره در لیست ما وجود داره یا نداره ، سه تابع برای این کار هست ، تابع any بررسی می‌کنه آیا در لیست عنصری هست که شرط رو داره یا نه ، تابع all بررسی می‌کنه آیا همه اعضا شرط رو دارند یا نه و تابع none بررسی می‌کنه آیا همه اعضا شرط رو ندارند یا نه : https://gist.github.com/sasssass/9c57318eeccb7ce36eadedc325ad835d گروه بندیبه وسیله تابع groupBy می‌تونید لیست رو به لیست های کوچک تر بشکونید ، خروجی این تابع یک key-value خواهد بود که value لیستِ زیرمجموعه لیست اصلی هست ، به مثال زیر دقت کنید ، در این مثال لیست اعداد یک تا شش را به سه مجموعه افراز می‌کنیم و ملاک ما باقی مانده بر سه است : https://gist.github.com/sasssass/bf296c803361db7b062a50e0e60c2cf0 خروجی کد : {1=[1, 4], 2=[2, 5], 0=[3, 6]}تابع groupBy می‌تواند یک ورودی دوم هم بگیرد ، اگر بخواهید مقدایر را تغییر دهید از این ورودی استفاده می‌شود (هر دو ورودی باید به صورت لامبدا باشند) : https://gist.github.com/sasssass/d42d95c516f640ffc95b9856506ae9ce خروجی کد : {1=[-1, -4], 2=[-2, -5], 0=[-3, -6]}مرتب سازیبرای مرتب سازی می‌توان از تابع sortedBy یا sortedByDescending (برعکس) استفاده کرد ، ورودی این تابع یک لامبدا است که مشخص کننده معیار ما برای مرتب سازی است : https://gist.github.com/sasssass/2c295a0e892dd4494994212c1d57d641 در کد بالا اعداد دو بار مرتب می‌شوند ، بار اول بر اساس مقدار و بار دوم بر اساس اینکه ضریب دو هستند یا نه ، بنابراین خروجی نهایی لیستی است که یک طرف آن اعداد فرد به ترتیب از کوچک به بزرگ و سمت دیگر اعداد زوج به همان منوال است :خروجی : [1, 3, 5, 2, 4, 6, 8, 88]توابع دیگری مانند reversed (برعکس کردن) ، shuffled (رندم) ، asReversed (فرق آن با reversed این است که reversed همیشه List برمی‌گرداند ، یعنی اگر شما MutableList هم داشته باشی باز هم List می‌گیری اما asReversed  از همان جنس برمی‌گرداند)در مقالات بعدی به توابع و ویژگی های دیگر از Collection ها می‌پردازیممن رو در لینکدین و اینستاگرام دنبال کنید ???اگه دوست داشتید می‌تونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Sat, 14 Nov 2020 02:01:56 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش HILT در اندروید - قسمت 2</title>
                <link>https://virgool.io/@shobeyri.ali/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-hilt-%D8%AF%D8%B1-%D8%A7%D9%86%D8%AF%D8%B1%D9%88%DB%8C%D8%AF-%D9%82%D8%B3%D9%85%D8%AA-2-kg7mwdx3b7dq</link>
                <description>در مقاله قبلی HILT رو مورد بررسی قرار دادیم و مفاهیم اون رو یاد گرفتیم ، در این قسمت یک پروژه با HILT می‌زنیم و در این بین چیزهای باقی مونده رو هم می‌پوشونیم ، در این پروژه شما با ترکیب HILT با MVVM و Retrofit آشنا می‌شید (در واقع اصلی ترین چیزهایی که برای یک پروژه نیاز دارید)پیش نیاز این مقالهقسمت اول سری HILTارتباط با سرور در اندروید - Coroutines + Retrofitاولی رو حتما باید بخونید ، دومی رو بهتره بخونید ، اگه زمانی که به قسمتی که به دومی ربط داره رسیدیم و دیدید مانع فهمیدنتون شده اونم خوندنش حتمی میشه .پیشنهاد می‌کنم اول پروژه رو clone کنید بعد هم زمان مقاله رو بخونید .صورت مسالهپروژه ای خواهیم نوشت که یک ریکوئست به سرور بزند و از سرور یک مدل حاوی Url بگیرد و این Url که یک عکس هست را نمایش دهدپاسخ به مسالهبذارید قبل از توضیح عکس فولدر های پروژه رو با هم ببینیم :کلاس App که مشخصه ، در پوشه View دو کلاس MainActivity و MainFragment داریم که مشخصا MainFragment داخل MainActivity نشون داده میشه ، در MainFragment ما با استفاده از MyViewModel (در پوشه ViewModel) یک ریکوئست به سرور می‌زنیم ، در MyViewModel این کار رو با ApiRepo (در پوشه Api) انجام می‌دیم ، ApiRepo در اینجا محل اتصال ما به تابعی به نام apiCall در فایلِ safeApi هست که ریکوئست های ما اونجا اجرا میشن .خب قدم به قدم :کلاسِ App ما کاری قرار نیست انجام بده و صرفا یه بدنه خواهد بود که با HiltAndroidApp مشخص شده ، مثل کاری که در مقاله قبلی کردیم : https://gist.github.com/sasssass/cc447d83926bba88a27c38fbf747bb45 برای اضافه کردن Activity و Fragment به HILT باید از AndroidEntryPoint استفاده می‌کردیم ، برای مثال MainActivity به این صورت در میاد : https://gist.github.com/sasssass/74d1312204b33760cdbb420fed7ae013 اینجا سوال پیش میاد که اون دو تا تابع تهِ کلاس ما چی هستند ؟ من قبلا مقاله ای در مورد وصل کردن Coroutines به Retrofit در ویرگول گذاشته بودم که در اون توضیح دادم چطوری دیگه به روش قدیمی برای ریکوئست زدن به سرور عمل نکنیم و بیاییم یک روش بهینه و قشنگ تر رو با استفاده از Coroutines و LiveData به وجود بیاریم ، چون مفصلا در اون مقاله این قضیه توضیح داده شده در مورد خودِ روش توضیحی نمیدم اما در این روش یک interface به نام RemoteErrorEmitter داشتیم ، این interface مشخص کننده این بود که وقتی به error میخوریم چه واکنشی نشون بدیم ، ما اینجا MainActivity رو از اون Implement کردیم که وقتی به طورکلی به error بخوریم (این error ها چیزایی مثل درست نبودن url ، قطعی نت و ... هستند) چه کار کنیم ، من اینجا چیزی در بنده این دو تابع ننوشتم ولی می‌تونید یک دیالوگ نشون بدید یا با یه Toast خشک و خالی قضیه رو جمع کنید . نکته ای که جلوتر خواهم گفت اینه که ما باید این RemoteErrorEmitter رو inject کنیم که سر تایمش بررسیش می‌کنیم .حالا باید dependency های مورد نیازمون رو که اینجا یک instance از Retrofit میشه رو تهیه (Provide) کنیم ، این instance باید به صورتی باشه که در هر Component یا SubComponentای که باشیم بتونیم ازش استفاده کنیم پس مربوط به ApplicationComponent میشه ، این کار رو در AppModule انجام میدیم : https://gist.github.com/63a3535aa95cfc23c679e098153c9281.git کاری که در این کد انجام داده میشه ساده است ، Module مشخص کننده اینه که این کلاس یک ماژوله که قراره dependency های ما رو ایجاد کنه ، InstallIn مشخص کننده اینه که مربوط به کدوم Component میشه و Singleton هم مشخص کننده سراسری بودن تابع درون ماژوله (که می‌تونید نذاریدش) ، بدنه تابع هم که واضحه ، داره یک شی از Retrofit رو برمی‌گردونه ، از این به بعد ما به راحتی Retrofit رو می‌تونیم هر جای App خواستیم Inject کنیم .اما اگه به فایل ها دقت کنید یک ActivityModule ماژول هم داریم ، این مربوط به همون RemoteErrorEmitter میشه که بالا گفتم : https://gist.github.com/a5e3362f6f54cf26d03b7fd4863c5e3f.git ما در safeApi نیاز داریم یک RemoteErrorEmitter داشته باشیم و این رو باید inject کنیم ، برای تهیه اون هم چون این MainActivity از این کلاس implement شده باید خودِ MainActivity رو بهش برگردونید ، حالا چرا تو ورودی های تابع ما activity رو آوردیم ؟ این ورودی کجا پر میشه ؟ وقتی ما MainActivity رو به گرافِ HILT اضافه کردیم می‌تونیم ازش درون ماژول ها استفاده کنیم ، نکته اینه که کلا هر dependency ای رو که provide کردید رو می‌تونید برای ایجاد dependency های دیگه در ورودی ها بنویسید چون قبلا تهیه شده و HILT اون رو خودش داخل ورودی تابع می‌فرسته که البته این به HILT ربطی نداره و مربوط به Dagger میشه .حالا می‌ریم سراغ ApiRepo ، این قسمت در مقاله مربوط به اتصال Coroutine و Retrofit نبوده ، ApiRepo کلاسیه که ما قراره در ViewModel تزریق کنیم : https://gist.github.com/c8a802c2e35cf17a4807f0decb2f6bf2.git صرفا یک یادآوری بکنم که apiCall دو ورودی داشت ، یکی RemoteErrorEmitter و اون یکی یک تابع که ما در این تابع  ریکوئستمون رو صدا می‌زنیم ، حالا خروجی نهایی به صورت liveData خواهد بود که اون رو می‌تونیم observe کنیم (اگه تا اینجا رو خوندید و هنوز نمی‌دونید قضیه apiCall و safeApiCall چیه همین الان stop کنید و برید این مقاله رو سریع بخونید) . ما به صورت constructor injection اومدیم apiService و emitter رو inject کردیم ، طبق توضیح قبلی که دادم emitter در واقع همون MainActivity میشه که provide شده . حالا این کلاس ApiRepo رو کجا صدا بزنیم ؟ داخلِ MyViewModel : https://gist.github.com/e9bd98658a084795caff6602e8bcca0e.git تابع getPhoto که مشخصه ، repository هم که باز به روش constructor injection تزریق شده ولی اون ViewModelInject چیه ؟ این رو در مقاله قبلی نیاورده بودم . اگر شما با Dagger کار کرده باشید می‌دونید که مشکلی که ViewModel داشت این بود که نمی‌تونستیم چیزی داخلش inject کنیم و مجبور بودیم هزار تا مصیبت بکشیم تا بتونیم این قضیه رو اوکی کنیم ، اما اینجا یه ViewModelInject قضیه تموم میشه !حالا دیگه نوبت MainFragment میشه : https://gist.github.com/d1330936814208ac5ae67bb3e0923aad.git مثل Activity و با توجه به توضیحات قسمت اول سری HILT با استفاده از AndroidEntryPoint این Fragment رو داخل گرافِ HILT اضافه می‌کنیم ، با استفاده از ()by viewModels هم MyViewModel رو می‌سازیم که این به همون ViewModelInject ربط داره .نکته :این by چیه ؟ در کاتلین delegateرو با by انجام میدن ، delegate چیه ؟ خیلی مختصر و مفید میشه وقتی شما میخواید یه چیزی رو مقداردهی کنید ولی می‌خواید این کار رو کلا به یک کلاس دیگه انجام بدید ، در کاتلین با by می‌تونیم delegate رو انجام بدیم ، برای مطالعه بیشتر delegate in programming رو در گوگل سرچ کنید (و به نظرم از رو ویکیپدیا انگلیسی بخونید)و تمام ! دیگه هیچ نیازی به اون Component نویسی های مزخرفی که تو Dagger انجام می‌دادید نیست ! به چند تا انوتیشن خیلی ساده و شیک همه چیو به هم وصل کردید و هر چی خواستید رو تو هر کجا خواستید Inject کردید .لینکِ پروژه : https://github.com/sasssass/MVVM_HILT_ANDROID/tree/master من رو در لینکدین و اینستاگرام دنبال کنید ???اگه دوست داشتید می‌تونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Wed, 21 Oct 2020 01:28:15 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش HILT در اندروید - قسمت 1</title>
                <link>https://virgool.io/coderlife/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-hilt-%D8%AF%D8%B1-%D8%A7%D9%86%D8%AF%D8%B1%D9%88%DB%8C%D8%AF-%D9%82%D8%B3%D9%85%D8%AA-1-abamk4nj7xdy</link>
                <description>چند وقتی میشه که Google برای DI ابزار جدیدی رو به نام HILT معرفی کرده (اگه نمی‌دونید DI چیه نگران نباشید ، جلوتر میگم) ، در سری مقالات قبلی به معرفی Dagger Android پرداختیم که اصلی ترین ابزار برای DI در اندروید هست (ابزارهای دیگه مثل Koin و ... هم هستند) ، HILT هم در واقع ورژن پیشرفته و ساده ترِ Dagger هست (یک نوع ورژن از Dagger در گذشته وجود داشته ، گوگل از روی اون ورژن Dagger2 رو درست می‌کنه و بعد برای اینکه توسعه دهنده های اندروید راحت تر باشن یک ورژن مخصوص اندروید هم توسعه میده و الان هم رفته سراغ HILT) .خب سریع یک مروری بکنیم که DI و اینها چی بودند اصلا !تزریق وابستگی ها - Dependency Injectionوابستگی چیه ؟ اولا که وقتی میگیم Dependency منظورمون اون چیزایی که شما تو فایل gradle می‌نویسید نیست ! هر کلاس می‌تواند به کلاس های دیگر وابسته باشد ، مثلا کلاس &quot;ماشین&quot; وابستگی به کلاس &quot;چرخ&quot; داره و این وابستگی باید به اون تزریق بشه ، یکی از راه ها اینه که ما تو &quot;سازنده&quot; یا &quot;constructor&quot; کلاسِ &quot;ماشین&quot; ، اِلمانِ کلاس &quot;چرخ&quot; رو بیاریم و ما با این کار به نوعی عملِ &quot;تزریق وابستگی رو انجام دادیم&quot; ، ولی اگه بعدا سازنده رو عوض کنیم چی ؟ هزار جای کد باید این تغییر رو اعمال کنیم ! پس بهترین کار اینه که به نحوی بیاییم این عملیات رو در لایه های بالاتری از انتزاع (Abstraction) انجام بدیم .ابزارِ HILTدر لغت Hilt به معنای دسته‌ی خنجره (و Dagger به معنای خنجر) ، حالا اینکه چرا این اسم رو این سری انتخاب کردند نمی‌دونم ?? ، هدف ایجادِ HILT راحت تر کردنِ استفاده از Dagger2 برای توسعه دهنده هاست ، اگه قبلا با Dagger Android یا حتی ورژن قبل اون که برای جاوا بوده کار کرده باشید می‌دونید که مصائب زیادی داره :/ ، در عوض با HILT ما بیشترِ کارامون رو با انوتیشن ها انجام می‌دیم .شروعِ کارابتدایِ امر باید کتاب‌خونه HILT رو به پروژه اضافه کنیم ، اول به gradle اصلی برید :classpath &#x27;com.google.dagger:hilt-android-gradle-plugin:2.28-alpha&#x27;و بعد به gradle app برید ، اول دو پلاگین مورد نیاز رو در بالای پروژه اضافه کنید :apply plugin: &#x27;kotlin-kapt&#x27;apply plugin: &#x27;dagger.hilt.android.plugin&#x27;و بعد dependency های مربوط رو اضافه می‌کنیم :implementation &quot;com.google.dagger:hilt-android:2.28-alpha&quot;kapt &quot;com.google.dagger:hilt-android-compiler:2.28-alpha&quot;ابزارِ HILT از جاوا 8 استفاده می‌کنه پس این مورد رو هم باید اضافه کنیم :android {    // other things . . . compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 }}اگه سری مقالاتِ Dagger2 که در ویرگول نوشتم رو خونده باشید با Component آشنایید ، در Dagger2 ما یک Component اصلی به نام AppComponent داشتیم و یک سری SubComponent (که زیرمجموعه Component دیگری حساب می‌شدند) ، قضیه به این صورت بود که اگه یک Dependency توسط AppComponent تهیه (Provide) میشد تمامی SubComponent ها به اون دسترسی داشتند ولی برعکس این موضوع صادق نبود ، مشکلی که در Dagger2 وجود داشت مکافاتی بود که شما برای درست کردن این Component ها باید تحمل می‌کردید ، چیز دیگه ای هم به نام Module داشتیم ، ماژول در Dagger کلاسی بود که برای ما Dependency ها رو Provide می‌کرد ، یعنی چی ؟  فرض کنید یه Dependency پیچیده مثل Retrofit یا ... رو بخواید تزریق کنید ، شما از تریق Module این Dependency رو می‌سازید و بعد به کلاس مورد نظر Inject می‌کنید .معماری کلی Dagger2 ما در Class ها به Dependency ها نیاز داریم ، Component برای ما این Dependency ها رو تزریق می‌کنه و خودِ Component به واسطه Module اونا رو Provide می‌کنه ، Scope چی بود ؟ معنی لغوی Scope یعنی محدوده ، پس کارش اینه که بیاد یک چیزی رو برای ما محدود کنه ، ما با Scope کردن میاییم مشخص می‌کنیم فلان Dependency فقط برای فلان Component هست و بهمان Dependency فقط برای بهمان Component ، حالا در Hilt چطوری باید Module و Component و Scope رو ایجاد کنیم ؟ حالا این Inject یا تزریق در Hilt چطوریه ، مثلا فرض کنید می‌خوایم به کلاسِ Application قابلیت Inject کردن رو بدیم (یعنی توش وابستگی تزریق کنیم) ؟ https://gist.github.com/sasssass/6cbe440658d64c866fcc963484179487 و تمام :) باقی کارها توسط خودِ HILT هندل میشه و دیگه لازم نیست مثل Dagger کلی کد بنویسید و بعد یه بارم Build بگیرید که کلاس ها ساخته بشن و ... ، با همین یه دونه انوتیشن ما کلاسِ App رو وارد HILT کردیم و حالا می‌تونیم توش Dependency ها رو تزریق کنیم !ما دو نوع تزریق (Inject) وابستگی داریم ، یکی به صورت Field و یکی به صورت Constructor ، در واقع Field Injection حالت عادی قضیه حساب میشه ، مثلا شما در کدهاتون با انوتیشن Inject مشخص می‌کنید که برای این شئ باید Inject صورت بگیره اما در Constructor Injection شما Constructor اون شئ رو با کلمه Inject مشخص می‌کنید و بعد از اون هر زمانی که اون شئ Inject بشه ورودی هاش هم Inject میشند ، اگر درست متوجه نشدید مثال پایین کمک می‌کنه : https://gist.github.com/sasssass/2c3ace7faa55f4c997c5721af9519617 در این کد SomeClass به صورتِ Field و SomeOtherClass به صورت Constructor به درون کلاس ها Inject شدند ، حالا فرض کنید بخوایم به درون یک Activity یا ... یک شئ رو Inject کنیم ، چه کار باید بکنیم ؟ما با مشخص کردن HiltAndroidApp برای کلاسِ App این کلاس رو به داخل گرافِ HILT اضافه کردیم ، حالا همین کار رو با انوتیشن دیگه ای باید انجام بدیم و این انوتیشن ، AndroidEntryPoint هست ، این انوتیشن می‌تونه برای Activity ، Fragment ، Service ، BroadcastReceiver و View استفاده بشه ، به کدِ زیر دقت کنید : https://gist.github.com/sasssass/04b3818a384798d958aa445d8a09b915 در این کد ما MainActivity رو به گرافِ HILT اضافه کردیم (منظورم اینه که الان MainActivity زیر مجموعه App حساب میشه از نظر HILT) و با اضافه کردنش به گراف ، توانایی Inject کردن رو بهش دادیم ، شئِ BlawBlaw به صورت Field به درون MainActivity تزریق شده ، از طرفی در شیء BlawBlaw ما یک متغیر به نام SomeClass داریم که اون هم باز به صورت Field تزریق شده ، در کلاسِ SomeClass اما دیگه تزریق رو به صورت Field انجام ندادیم ، در SomeClass کلاسِ دیگه ای به اسم SomeOtherClass به صورت Constructor به درون SomeClass تزریق شده ! امیدوارم با این مثال قشنگ تفاوت این دو براتون جا افتاده باشه !نکته : این مثال ها صرفا آموزشی هستند ، در سری مقالات بعدی مثال های کاربردی و ایجاد یک پروژه با HILT رو مورد بررسی قرار می‌دیمایجاد Componentدر Dagger ما مستقیم خودِ Component رو ایجاد می‌کردیم ولی در HILT این‌کار رو نمی‌کنیم ، در HILT ما از یک سری Component از پیش ساخته شده استفاده می‌کنیم ، یعنی به جای اینکه یک کلاس FolanComponent بسازیم فقط میاییم اون Dependency مورد نظر رو با یک انوتیشن مشخص می‌کنیم تا خودش عملیات ساخت Component مورد نظر و وصل کردنش به اون کلاس رو انجم بده ، این انوتیشن ها مشخص کننده Scope و محدوده مورد نظر ما هستند :ارث بری Componentهااگر به شکل دقت کنید می‌بینید یک حالت درخت/ارث بری برای ما کشیده شده ، یعنی چی ؟ فرض کنید ما یک Dependency داریم ، اون رو باید با Scopeای با نام ActivityScope مشخص کنیم ، حالا وقتی این کار رو کردیم اون Dependency فقط می‌تونه از طریق ActivityComponent به پایین (FragmentComponent و ViewWithFragmentComponent) تزریق بشه ، یعنی Dependency ای که متخص Activity هست رو در کلاس Application نمی‌تونید استفاده کنید ولی برعکسش مشکلی نداره . در مورد قسمت Legend هم برای زمانیه که بخواید یک Component دلخواه بسازید که کاری باهاش نداریم . خب پس تا اینجای کار فهمیدیم که لزومی به ساخت Component نیست و از Componentهای از قبل ساخته شده استفاده می‌کنیم ، حالا بریم سراغ ماژول .ایجاد Moduleفرض کنید یک کلاسِ پیچیده داریم (ComplexModel) که دیگه نمی‌تونیم مثل روش های مثال های قبلی خیلی راحت اونو Inject کنیم بلکه نیاز به تابعی داریم که این کلاس رو برامون تهیه یا Provide کنه ، صورت مساله به این شکله که قصد داریم یک Module به نام ActivityModule بسازیم که وظیفه اش تزریق وابستگی‌ها به کلاس MainActivity باشه ، به کد زیر دقت کنید : https://gist.github.com/sasssass/c7e5ac37decc30f0530f45b461310fd9 در این کد اول از همه MainActivity رو داخل گرافِ HILT کردیم (با AndroidEntryPoint) ، بعد از اون ActivityModule رو ساختیم ، وقتی شما می‌خواید مشخص کنید Module مورد نظر مربوط به کدوم Component باشه باید از InstallIn استفاده کنید و توش جنسِ کلاسِ اون Component رو بنویسید (برای اسم های Componentها به عکس های بالاتر نگاه کنید) ، خودِ Module رو هم با انوتیشن Module مشخص می‌کنیم که HILT بفهمه این کلاس یک Module حساب میشه ، حالا برای تهیه Dependency دو راه داریم ، یکی استفاده از Bind یکی استفاده از Provide (که فعلا ما با همین Provide کار داریم) ، تابعی که داره برای ما Provide رو انجام میده provideComplexModel هست که میاد یک ComplexModel رو برای ما برمی‌گردونه ، خودِ این تابع رو هم می‌تونیم Scopeگذاری کنیم (می‌تونیم هم نکنیم چون به صورت پیش فرض این خودش می‌فهمه) و بعد در کلاسِ MainActivity عملیات Inject رو انجام می‌دیم .نکته : HILT به صورت Compile-Time کدها رو بررسی می‌کنند پس اگر خطایی وجود داشته باشه اجازه اجرای برنامه داده نمیشه و برناه Build نمیشه پس نگران جا به جا نوشتن Scopeها و ... نباشیدنکته : در موردِ Bind نمی‌خوام توضیحی بدم ، در همین حد بدونید که اگه از Bind استفاده کنید نیازی نیست بدنه تابع رو بنویسید و به همین خاطر نمیشه همیشه ازش استفاده کرد (مثلا اگه بخواید Retrofit رو Inject کنید) پس بهتره از همون Provide استفاده کنیددر قسمت های بعدی از سری مقالات HILT ، بیشتر این مبحث رو باز می‌کنیم . . .من رو در لینکدین و اینستاگرام دنبال کنید ???اگه دوست داشتید می‌تونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???</description>
                <category>Ali Shobeyri</category>
                <author>Ali Shobeyri</author>
                <pubDate>Sun, 27 Sep 2020 13:40:14 +0330</pubDate>
            </item>
            </channel>
</rss>