<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Aldroid</title>
        <link>https://virgool.io/feed/@al.allahverdi</link>
        <description>کنجکاو پیرامون برنامه نویسی موبایل :)</description>
        <language>fa</language>
        <pubDate>2026-06-17 00:40:15</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/332797/avatar/Gjx3mP.jpeg?height=120&amp;width=120</url>
            <title>Aldroid</title>
            <link>https://virgool.io/@al.allahverdi</link>
        </image>

                    <item>
                <title>برنامه نویسی جنبه گرا (AOP) - مقدمه</title>
                <link>https://virgool.io/@al.allahverdi/%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%AC%D9%86%D8%A8%D9%87-%DA%AF%D8%B1%D8%A7-aop-%D9%85%D9%82%D8%AF%D9%85%D9%87-h503ap84rt8n</link>
                <description>در این نوشته گپِ مختصری میزنیم پیرامون مفاهیم AOP . توی این مدل از برنامه نویسی، همانندِ سایرِ مدل ها، مثل OOP یا برنامه نویسی به شکل Functional ، تلاش اینه که یکسری از دغدغه هایی که توی دنیای توسعه ی نرم افزار وجود داره رو به یک نحوی حل کنیم.برنامه نویسی جنبه گرابرای مثال در OOP سعی میکنیم به یک نحوی Logic رو نزدیک کنیم به Entity هامون، به طوری که بشه برنامه رو به شکل Maintainable توسعه داد، یا به نوعی قابلیت Maintenance توی کدمون بره بالا. یا مثلا وقتی در مورد برنامه نویسی Functional صحبت میکنیم، در واقع تمرکزِ اصلیِ ما روی این مساله هستش که بتونیم Reusability رو تا حد ممکن بالا ببریم و علاوه بر اون تا جای ممکن، برنامه نویسی رو ساده کنیم. به طوری که وقتی شما یک Function رو نگاه میکنید، به سادگی بتونید از روی Signature اون متوجه بشید که به چه شکلی کار میکنه و در واقع به راحتی قابل حدس  و predictable باشه.در AOP چه مباحثی ساده میشه؟در توسعه ی نرم افزار مسائلی وجود دارند که حالت جانبی دارند. به این معنا که گاهی اوقات این مسائل در Functionality هسته ی سیستمِ ما قرار نمی گیرند. زمانی که ما یک نیازمندی داشته باشیم که جزء بیزینسِ اصلیِ برنامه مون نیست، موضوعی که پیش میاد اینه که به احتمال زیاد، این Logic پخش میشه در جاهای مختلفی از برنامه ی ما. برای مثال Non-functional requirements (نیازمندی های غیر وظیفه مند) معمولا از این نوع نیازمندی ها هستند.یا مثلا بحثِ Security رو در نظر بگیرید. زمانیکه در مورد Security یک سرویس صحبت میکنیم، مساله ای که وجود داره اینه که Logic ای که برای این قسمت در نظر میگیریم، به احتمال خیلی زیاد، در جاهای مختلفی از نرم افزارمون، مدام در حال تکرار شدن هستش. برای روشن شدن موضوع بهتره مثال های زیر رو بررسی کنیم.مثال اول:فرض کنید قصد داریم چک کنیم که آیا یک کاربر اجازه ی دسترسی به یک Resource رو داره یا نه. این Resource ممکنه در جاهای مختلفی از برنامه در قالب متدها و ... تکرار بشه. حالا اگر خودمون بخواهیم به صورت دستی این مساله رو مدیریت کنیم، نتیجه ی کارمون یک قطعه کد میشه، که باید همه جا تکرار بشه. به این نقاط، اصطلاحا Cross Cutting Concern گفته میشه. جلوتر این مفهوم رو کامل میشکافیم و توضیح میدیم. برای درک این مساله تصور کنید که از وسط اپلیکیشنِ ما، یک برش افقی زده بشه و توی این برش، مشاهده میکنیم که در همه جا، این نیاز وجود داره که یک مفهومی قرار داده بشه. در این مثال، این مفهوم، Security بود.مثال دوم:یک مثال دیگه که خیلی همیشه در موردش صحبت میشه بحث Logging هستش. احتمالا زمانی که در حال توسعه ی نرم افزار هستیم، نیاز داشته باشیم که خیلی جاها به شکل سیستماتیک یک log به برنامه اضافه کنیم. مدل کلاسیک این عمل، به این صورت میشه که فرضا در ابتدا و انتهای یک متد یک log میذاریم تا بتونیم ورودی و خروجی هامونو چک کنیم. اگر در پروژه، چنین نیازمندی هایی داشته باشیم و بخواهیم بصورت کلاسیک پیاده سازیشون کنیم، نیازه که فرضا براش یک متد بنام log بنویسیم تا از این متد در جاهای مختلفی استفاده کنیم. همونطور که قبلا هم بهش اشاره شد این نقاط همون Cross Cutting Concern ها هستند که به نوعی همه جای برنامه ی ما رو تحت تاثیر خودشون قرار میدن.مثال سوم:مثالی دیگه ای که میشه بررسیش کرد بحثِ Observability هستش. بالا بودنِ این شاخصه در سیستم های نرم افزاری خیلی مهمه. مخصوصا این روزها با اومدن سرویس های جدید، مساله ی Cloud Native بودنِ اپلیکیشن خیلی اهمیت پیدا کرده. به این صورت که یک اپلیکیشن، میتونه روی سرورهای مختلفی بیاد بالا، یا مثلا اگر طول عمر کوتاهی داشته باشه، میتونه منتقل بشه به یک سرور دیگه. در این حالت Observability اهمیت زیادی پیدا میکنه. به این معنی که ما بتونیم مشاهده کنیم اون سیستمی که در حال ساختنش هستیم، تا چه حد قابل مانیتور شدنه. باز هم در اینجا با مفهوم Cross Cutting Concern ها مواجه میشیم. اگر بخواهیم بخش هایی در کدمون مانیتور بشه، نیازمند این هستیم که باز هم یک قطعه کدی رو مدام تکرار کنیم. اتفاقی که در اینجا میوفته اینه که مجددا مثلِ بحثِ log و Security که قبلا بهش اشاره شد، لازم میشه که کدمون رو در جاهای مختلفی Duplicate کنیم. مدیریتِ کد در این حالات به شکل دستی ،بسیار چالش برانگیز میشه.نکته ی مهم:باید توجه زیادی کنیم که AOP مثل بقیه ی پارادایم های توسعه ی نرم افزار، نیومده که همه ی مشکلات رو یکجا حل کنه. به نوعی AOP چیزی نیست که بتونیم بگیم اگر وجود نداشته باشه و ازش استفاده نکنیم، مشکلات زیادی توی توسعه ی نرم افزار پیش میاد. همه میدونیم که کار اصلی ماها سر و کله زدن با مشکلات و چالش هاییه که پیش رومونه. مانند مثال هایی که در بالا گفته شد، اما باید بدانیم که AOP برای ما، تنها راه حلِ جواب دادن به این نوع از مشکلات نیست.باید آگاه باشیم که AOP یک راه حلِ بسیار جذابه که شاید مناسبِ مواجهه با همه ی مشکلات نباشه. یعنی اگر بعنوان یک ابزار در نظر بگیریم، ما نباید زیاد Overuse کنیمش. مثل همه ی ابزارهای دیگه ای که در اختیار داریم.مفاهیم پیرامون AOP :مفهوم Cross Cutting Concern :یعنی Concern هایی که توی قسمت های مختلف اپلیکیشنِ ما پخش هستند. باید بدانیم که پیدا کردن نقاط Cross Cutting Concern بسیار مهمه. به این معنی که میتونیم توی سیستم ذکر کنیم که فرضا، تمام این نقاطی که ما تعریفشون میکنم، نقاطی هستند که ما قصد داریم یک تغییر یا یک مفهومی رو به اپلیکیشن خودمون اضافه کنیم. برای مثال تصور کنید که میخواهیم بگیم که قبل از تمامِ متدهایی که کارِ تغییر بر روی دیتابیس رو انجام می دهند، قصد داریم چیزی رو log کنیم.در واقع Cross Cutting Concern نیازمندی هایی میشن که نقاط مختلفی از اپلیکیشنِ ما رو هدف میگیرند. معمولا این نوع نیازمندی ها، نیازمندی های Non-functional یا غیر وظیفه مند هستند. برای مثال اگر ما یک نیازمندی رو برای یک اپلیکیشن بنویسیم، احتمالا این موارد درون Main Success Scenario پروژه مون نمیاد. مثلا یکیش اینه که میخواهیم هر وقت یک Controller اجرا شد، یک چیزی log بشه. این مورد چیزیه که اگر بخواهیم پیاده سازیش کنیم، همه ی Controller هایی که داخل سیستم داریم رو دستخوش تغییر میکنه. معمولا این موارد چیزهایی نیستند که توی نیازمندی های Product Owner بیاد. مثلا یک Product Specialist هیچوقت نمیاد به ما بگه که من میخوام فرضا فلان log توی برنامه اجرا بشه :)) این موارد چیزهایی هستند که ممکنه فقط تکنیکال باشند. یا مثلا همان بحث Security که بهش اشاره کردیم رو دوباره در نظر بگیرید، در اونجا گفتیم که نیاز بود تا Authenticate در جاهای مختلفی که با Resource سر و کار داشتیم، انجام بشه. در اون حالت میومدیم یک متد مینوشتیم فرضا با نام isUserAuthenticate و در همه جای برنامه ازش استفاده میکردیم.بنابراین این مدل دغدغه ها که نقاط مختلفی از اپلیکیشن رو تحت تاثیر قرار میدن بهشون میگیم Cross Cutting Concern .مفهوم Advice :بطور کلی اون قطعه کد و Logic ای که ما میخواهیم در نقاط مختلف برنامه مورد استفاده قرار بگیره رو بهش میگیم یک Advice.مفهوم Point Cut :به اون نقاطی از اپلیکیشن میگیم که میخواهیم Advice مان در اونجا اجرا بشه.مفهوم Aspect :به مجموعه ی Point Cut و Advice میگیم یک Aspect . به این معنا که اگر فرضا بگیم فلان قطعه کد قراره در فلان جاها اجرا بشه، به این مجموعه میگیم یک Aspect از برنامه مون.مفهوم Weaving :فرض کنید که یک Aspect داریم که قراره بیاد با کد اصلیمون ترکیب بشه. یعنی فرضا ما خودمون تعریف کردیم که برای مثال قبل از اجرا شدن یک سری متد، کار X انجام بشه. حالا اتفاقی که میوفته اینه که درون یک پروسه ای، در یک قسمتی از اجرای نرم افزارمون، لازم میشه که این کدها با کدهای اپلیکیشنِ ما ترکیب بشه. اصطلاحا میگیم که عمل Weave اتفاق بیوفته. به نوعی این دو بخش از کد رو میبافیم توی همدیگه. حالا این مورد توی سیستم های مختلف و در زبان های مختلف میتونه به روش های مختلفی اتفاق بیوفته.برای زبانی مثل جاوا که کامپایلری هستش، سه حالت ممکنه پیش بیاد:1- حالت اول اینه که ما این حالت Weaving رو در زمان اجرا انجام بدیم. این مساله توی زبان های مفسری هم بصورت پیش فرض انجام میشه. موضوعی که وجود داره اینه که در زمان اجرا، یک Manager یا Coordinator ای وجود داره که میاد رصد میکنه. نحوه ی کارش اینجوریه که برای مثال ما قصد صدا زدن متدِ X رو داریم، این Coordinator میدونه که برای متد X باید کدِ Y رو هم اجرا کنه. بنابراین میاد و در زمان اجرا عملِ Weaving رو انجام میده.2- حالت دوم موسوم به Compile time Weaving میشه. فرض کنید که کامپایلرِ ما قادر هستش که Aspect های ما و همینطور کدِ اصلیمون رو در نظر بگیره، و در نهایت اون قطعه کدی که تولید میکنه، ترکیب این دو تا چیز باشه. با این کار دیگه در زمان اجرا لازم نیست اون Coordinator ای که در حالت قبل دیدیم، بیاد رصد کنه و بگه که چه زمانی باید این Aspect صدا زده بشه روی کدِ ما.3- حالت سومی هم وجود داره که همیشه پیش نمیاد. یعنی برای همه ی زبان های کامپایلری وجود نداره. بهش میگیم Load time Weaving . این حالت زمانی میتونه اتفاق بیوفته که زبانی که باهاش کار میکنیم یک Stage لود کردن هم داشته باشه. مثلا جاوا این ویژگی رو داره که ما زمانیکه یک کلاس رو نیاز داشته باشیم، Class Loader میاد از روی دیسکِ ما، کلاس رو میگیره، فایلش رو میخونه و لودش میکنه توی سیستم و داخل مموری (اون کدی که باید اجرا بشه). بنابراین این امکان هم وجود داره که در Load time Weaving بتوانیم Aspect هایی که مد نظرمون هست رو توی کدمون اعمال کنیم.مزیت Load time Weaving چیه؟مزیتش اینه که دیگه با Overhead Runtime مواجه نمیشیم. یعنی دیگه در Runtime نیازی نیست که فرضا یک Coordinator وجود داشته باشه که بیاد و بررسی هاش رو انجام بده که الان متد X داره اجرا میشه، پس من برم Aspect فرضا Y رو اجرا کنم. در واقع کد، از قبل Generate شده و وجود داره.عیب Load time Weaving چیه؟عیبش اینه که باعث میشه Load time بره بالا. یعنی زمانی که داریم یک کلاس رو میخونیم و میبریمش توی حافظه، کارهای بیشتری توسط JVM در حال انجام شدنه. به همین دلیل ممکنه Startup time اپلیکیشنِ ما مقداری افزایش پیدا کنه. البته این زمان هم بستگی به این داره که چه تعدادی Aspect و چند تا Point cut مختلف داریم که داره از اونها استفاده میکنه.مقایسه با Compile time Weaving :کاری که عمل Weaving در زمان Compile time میکنه اینه که زمان کامپایلر رو ممکنه بیاره بالا و در نتیجه Compile time بیشتر بشه. اما نهایتا اون دو تا مشکلی که بهشون اشاره کردیم رو در مورد Runtime و Load time دیگه نداریم. یعنی اون کدی که در زمان Load time داریم و یا اون کدی که در زمان Runtime خواهیم داشت رو دیگه در این حالت نداریم.مثلا فرض کنید که یک متدی نوشتیم و گفتیم که قبل از اجرا شدنش، متدِ Y هم باید اجرا بشه. میتونیم اینجوری در نظر بگیریم که در واقع این متدِ Y اومده توی کدِ ما تزریق شده و در نهایت اون مجموعه به شکل ترکیبی هستش که داره کامپایل و اجرا میشه.مثال:در انتها یک مثال دیگه هم بررسی میکنیم که البته مربوط به AOP نمیشه ولی بیانش در اینجا خالی از لطف نیست. اون هم بحث Annotation Processor ها هستش که پس از اینکه در سیستم خوانده میشن، بر اساس اونها یکسری کد تولید میشه و بایت کدِ ما رو دستخوش تغییر میکنند. این مساله چیزی نیست که در زمان Load time یا Runtime اتفاق بیوفته. به نوعی حتی ما میتونیم این بخش رو از JAR File پروژه مون هم حذف کنیم. انگار که این بخش کارش رو کرده و تمام شده و رفته. دقیقا چیزی شبیه به کاتالیزورها در شیمی هستند :)) که توی ترکیب شیمیایی شرکت می کردند، اما تهش خودشون رو می کشیدند کنار و توی اون محصول نهایی وجود نداشتند. اینم دقیقا همونجوریه و کارش فقط در زمان کامپایله و در زمان اجرا کار خاصی انجام نمیده.پیاده سازی AOP:توی جاوا چند پیاده سازی معروف وجود داره. یکی از این پیاده سازی ها AspectJ هستش  که به نوعی یک پیاده سازیِ پیچیده از AOP در جاواست که کامپایلرِ مخصوص به خودش رو داره. در واقع در این حالت یک AspectJ Compiler داریم که میتونه کدهای Aspect ما رو بگیره، کامپایل کنه و با کدهای اصلی Weave کنه. پس از این توالی، در نهایت بایت کدِ نهایی رو تولید میکنه. در واقع AspectJ به صورت پیش فرض معمولا در Compile time استفاده میشه (Compile time Weaving).یک پیاده سازی دیگه هم داریم بنام Spring AOP که پیاده سازیش به مراتب ساده تره. اما در نهایت قدرت کمتری داره و تمام قابلیت های AspectJ رو نداره. ولی در نهایت برای ما اونقدری قابلیت داره که اکثر نیازمندی هامون رو برطرف کنه.منبع:OH! My Talks!</description>
                <category>Aldroid</category>
                <author>Aldroid</author>
                <pubDate>Sat, 24 Jul 2021 13:38:59 +0430</pubDate>
            </item>
                    <item>
                <title>درک تزریق وابستگی - مقدمه</title>
                <link>https://virgool.io/@al.allahverdi/%D8%AF%D8%B1%DA%A9-%D8%AA%D8%B2%D8%B1%DB%8C%D9%82-%D9%88%D8%A7%D8%A8%D8%B3%D8%AA%DA%AF%DB%8C-%D9%85%D9%82%D8%AF%D9%85%D9%87-ea2es1v5m4cz</link>
                <description>در این نوشته گپ مختصری پیرامون مفهوم تزریق وابستگی میزنیم. در قسمت های بعدی به بررسی چند مثال در قالب کد میپردازیم.Dependency Injection (DI)
برای شروع بهتره در مورد یک اصل مهم صحبت کنیم. اصلی با عنوان Hollywood Principle.مفهوم Hollywood Principle:در واقع یک اصل ساده س! اینجوریه که توی هالیوود وقتی برای یک فیلم بخوان بازیگر استخدام کنند، خودِ اون بازیگر هیچوقت زنگ نمیزنه به هالیوود و بگه که منو انتخاب کنید :)) بطور کلی یک شعار مهم دارن که میگه:Don’t call us! We&#x27;ll call you!همیشه اینجوریه که هالیوود با اشخاص تماس میگیره. حالا همین بحث ساده میاد توی مهندسی نرم افزار و تبدیل میشه به یک بحثِ بنیادی که بر اساس اون به این معنا میرسیم:&quot;من قرار نیست خودم کاری رو انجام بدم! من تنها کارهایی که ازم خواسته بشه رو انجام میدم.&quot;بنابراین Hollywood Principle اینجوری به کارِ ما میاد که به هر کدوم از Entity هایی که توی سیستم داریم، میگیم که این کلاس ها لازم نیست خودشون بگن که به چه Object هایی بعنوان Dependency نیاز دارند. اون ها فقط کافیه یک توصیف اولیه ازشون داشته باشند. ما هر زمانیکه به اون Object ها نیاز داشته باشیم، خودمون مسئولیت تزریق کردنشون رو به عهده میگیریم. دقیقا در همین نقطه هستش که با مفهومی با عنوانِ Inversion Of Control (IOC) مواجه میشیم.مفهوم Inversion Of Control (IOC):به طور کلی IOC به این معناست که کنترل، به جای اینکه دستِ خودِ Object باشه، میاد دستِ ما. بنابراین بجای اینکه خودِ Object تصمیم بگیره که چطوری Dependency هاشو بسازه، ما این کنترل رو بدست میگیریم. در این نقطه ما میتونیم فرضا بعنوان یک فریمورک، که از بالا به همه چیز مسلطه، تصمیم بگیریم که هر کدام از وابستگی ها به چه شکلی ساخته بشه.مثالی از  Hollywood Principle:احتمالا همگی فرق بین Library و Framework رو بدونیم. Hollywood Principle به نوعی فرق بین این دو را به خوبی بیان میکنه. در واقع فریمورک ها همگی این اصلِ Hollywood Principle رو درونِ خودشون دارند، در حالی که Library ها خیر.میدونیم که Library ها مجموعه ای از Function ها هستند که ما از اون ها برای یک هدفی، داخلِ کدمون استفاده میکنیم. در حالیکه در بحثِ فریمورک ها، به ما یکسری Functionality و یا Extension Point داده میشه که ما میتونیم بر اساس اون ها، پیاده سازی خودمون رو دنبال کنیم. در نهایت میتونیم ببینیم که بر خلاف Library ها، این ما نیستیم که از فریمورک ها استفاده میکنه! در واقع این فریمورک ها هستند که از کدهای ما استفاده میکنند.مفهوم Dependency Injection (DI):معمولا از مباحثی که تا اینجا مطرح شد با عنوان IOC یاد میشه، که سطوح مختلفی داره و برای کارهای مختلفی میشه ازش استفاده کرد. یکی از این سطوح، سطحِ ساختنِ Object هستش که در این سطح، با مفهوم DI مطرح میشه که به نوعی همان اصلِ Hollywood Principle رو اجرایی میکنه.در این نقطه ما یک کلاس رو با این تفکر طراحی میکنیم که انگار کل دنیا همون یک کلاسه و بدون هیچ گونه وابستگی ای. به نوعی ما در این مرحله، هیچگونه تصمیمی در مورد اینکه وابستگی ها به چه شکلی پیاده سازی میشن نمیگیریم. فقط میگیم که:&quot;من انتظار دارم که بعنوان ورودی، یکسری Object از یک کلاس پاس داده بشه تا بتونیم ازشون استفاده کنیم.&quot;مفهوم Dependency Inversion Principle (DIP):زمانیکه بخواهیم کلاسی رو پیاده سازی کنیم قاعدتا با یک Specification طرفیم. به نوعی یک مفهومی داریم که قراره ازش یک پیاده سازی داشته باشیم. موضوع اینه که پیاده سازی ای که داریم، نباید به یک پیاده سازیِ دیگه تویِ سطحِ خودش وابستگی داشته باشه. در واقع این پیاده سازی تنها باید وابستگی داشته باشه به High Level Specification هایی که داریم. به این معنی که وقتی داریم کلاسی رو پیاده سازی میکنیم، نباید Dependency داشته باشیم به یک کلاس دیگه ای که داخل Specification ما هست. برای مثال میتونیم یک Interface داشته باشیم که ما وابسته بشیم به اون.حالا این موضوع چه کمکی میکنه؟با پیروی از این اصول، ما وقتیکه داریم پروژه رو Run میکنیم، میتونیم تصمیم بگیریم که کدامیک از پیاده سازی های این Specification باید توی سیستم کار بکنه! حالا اگر این الگو رو رعایت نکرده باشیم و وابستگی داشته باشیم دقیقا به یک کلاسِ خاص، که یکی از این Specification ها رو پیاده سازی کرده، در این حالت فرضا توسعه دهنده ای که بخواد سیستم رو کانفیگ کنه یا هر کسی که بخواد پروژه رو Run کنه، این امکان رو نداره که یک پیاده سازی دیگه ای از اون Specification که نیاز داشته رو استفاده کنه. چی شد؟ بهتره مثالِ زیر رو بررسی کنیم.مثال:فرض کنید بخواهیم اطلاعات مشتری رو از روی یک دیتابیس دولتی بخوانیم. در این حالت فرض میکنیم که یک وب سرویس در اختیار داریم که قراره اون رو صدا بزنیم و اطلاعات رو ازش بگیریم. حالا اگر موقعِ پیاده سازی، وابستگی ایجاد کرده باشیم به اون پیاده سازی ای که مخصوصِ همین دیتابیسه، با این کار، این شانس رو از تیم توسعه گرفتیم که بدون اینکه کلاسِ ما رو تغییر بدن، از اون وب سرویس استفاده کنند. این مساله تنها در پروژه های کوچک ممکنه مشکل حادی بوجود نیاره، اما موضوع Open Close Principle (OCP) در این مورد نقض میشه و برای پروژه های بزرگ قطعا به مشکل میخوریم.مزیت های IOC :- طراحی با رعایت IOC کمک میکنه که نوشتن Unit Test بسیار ساده تر بشه. به نوعی با بهبود Testability مواجه خواهیم شد.- برای ما توسعه ی کد رو راحت تر میکنه که در نتیجه ی اون، دیگه قرار نیست تغییرات زیادی در کد داشته باشیم. اصطلاحا کدمون Pluggable میشه. به این معنا که میتونیم کد رو در اختیار تیم دیگه ای بذاریم و اونها تنها با Customize کردن قسمت های بسیار کمی، از کدِ ما برای پروژه های خودشون استفاده کنند.منبع:OH! My Talks!</description>
                <category>Aldroid</category>
                <author>Aldroid</author>
                <pubDate>Thu, 22 Jul 2021 22:19:26 +0430</pubDate>
            </item>
            </channel>
</rss>