<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های vahid almasi</title>
        <link>https://virgool.io/feed/@vahid_almasi</link>
        <description>PHP/Back-End Developer and Freelancer --  می نویسم که بیشتر یاد بگیرم و طولانی تر یادم بمونه :)</description>
        <language>fa</language>
        <pubDate>2026-06-17 14:11:04</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/7582/avatar/avatar.png?height=120&amp;width=120</url>
            <title>vahid almasi</title>
            <link>https://virgool.io/@vahid_almasi</link>
        </image>

                    <item>
                <title>الگوی آداپتور (الگوی وفق دهنده) - Adapter pattern با مثال PHP</title>
                <link>https://virgool.io/@vahid_almasi/%D8%A7%D9%84%DA%AF%D9%88%DB%8C-%D8%A2%D8%AF%D8%A7%D9%BE%D8%AA%D9%88%D8%B1-%D8%A7%D9%84%DA%AF%D9%88%DB%8C-%D9%88%D9%81%D9%82-%D8%AF%D9%87%D9%86%D8%AF%D9%87-adapter-pattern-%D8%A8%D8%A7-%D9%85%D8%AB%D8%A7%D9%84-php-belmzix7oh4k</link>
                <description>Adapter patternالگوی آداپتور یک الگوی که یاد گیریش ساده است چون که همه ما در دنیای واقعی ازش استفاده میکنیم مثل همین تبدیل های سه شاخه به دوشاخه برق، پس درکش برامون ساده اس.تبدیل سه شاخه به دوشاخه برقاول ببینیم آداپتور(مبدل) چه کاری رو برامون انجام میده؟!! من یه مانیتور دارم که به برق نیاز داره که روشنش کنم اما دو شاخه و پریز برق از یک استاندار یا به زبان کد بخوام بگم یک اینترفیس ندارن خب من نیاز به یک وسیله رابط دارم که بتونم دوشاخه رو به پریز وصل کنم خب آداپتور یا به زبان عمیانه تبدیل یا مبدل استفاده میکنم.(آداپتور شارژ لپ تاپ هم از همین موضوع میاد چون برق شهری 220 ولت رو به برق قابل استفاده برای شارژ لپ تاپ یعنی حدود 9 ولت تبدیل میکنه) فکر کنم حالا میشه حدس زد این دیزاین پترن چی کار میکنه، بریم با یه مثال یاد بگیریم چطوری پیاده سازیش کنیم.یک مثال ابتدایی در مورد کتاب بزنیم، بیاین تصور کنیم که ما کتاب کاغذی داریم و هر کسی که میاد کتاب بخونه ما کتاب رو واسش باز میکنیم و براش کتاب رو ورق میزنم.بیاید از درست کردن یک interface برای کلاس کتاب شروع کنیم و سعی کنیم از قوانین SOLID استفاده کنیم. اگه نمی دانید اینترفیس چیه پیشنهاد میکنم یکم در مورد اینترفیس، کلاس و ابسترکت کلاس(class, abstract class, interface) بخونید چیز جالبی هستش و اگه بخوام خیلی خلاصه بگم: یک اینترفیس فقط به شما اجازه می دهد که تا عملکرد(functionality) را تعریف کنید و نه این که آن را اجرا کنید. در حالی که یک کلاس می تواند یک کلاس انتزاعی (abstract class) را گسترش(extend) دهد و می تواند از چندین اینترفیس استفاده کند. https://gist.github.com/vahid-almasi/4d7ad830ce06aa26db24b8aeb2a8d4a1 خب یه interface BookInterface ساختیم و بهش دو تا متد open و turnPage رو دادیم.توی فایل بعدی یک کلاس Book ساخیتم و از اینترفیسکه داریم implements اش کردیم (معنیش این میشه که این کلاس باید دو تا متدی که توی اینترفیس بالا تعریف اش کریدم رو باید داشته باشه) و دو تا متد رو هم واسش ساختیم، داخل متد ها فقط برای این که مشخص شه، کاری که میکنند رو var_dump کردیم.فایل سومی هم همون index.php ما هستش که کلاس person (شخص) رو توش نوشتیم، که یک متد read (خواندن) داره، که شئ ای که کتاب باشه رو بهش میدیم و اون  برامون متد های open و turnPage رو اجرا میکنه, برای جلوگیری از این مشکل که شئ ای به جز کتاب بهش داده نشه از تله type-hinting استفاده کردیم (یه جور مثل ولیدیشن عمل میکنه، که مقدار ورودی حتما شئ (obj) باشه و از BookInterface  ایمپلمنت شده باشه که حتما اون دو تا متد open و turnPage رو داشته باشه)تا اینجا همه چی رو به راهه و سیستم داره درست کار میکنه، اما سیستم نیاز یه گسترش پیدا میکنه و ما باید کتاب خوان های الکترونیکی رو هم وارد همین سیستم کنیم. مثل کتاب جلوی افراد بذاریمش، روشنش کنیم و کتاب داخلش رو ورق بزنیم، اما یه مشکلی هست که این دستگاه ها به جای متدهای open و turnPage، متدهای turnOn و pressNextButton دارند. https://gist.github.com/vahid-almasi/f37d96363c4689bc25ba10572ffded8d  https://gist.github.com/vahid-almasi/ef7da848de6328ed1f0914a0102704a2 فک میکنم که واضحه چی شد دقیقا کاری که برای کتاب انجام دادیم برای این هم تکرار شده، فقط اینو یادتون باشه که ما داریم توی یه شرایط فرضی این مطلب رو میگیم حتی میتونید فرض کنید که این کلاس داخل یک پکیج به شما داده شده و حق بازنویسی این پکیج رو ندارید اما باید از اون استفاده کنید. حالا دقیقا اون جاییه که ما نیاز به یک آداپتور(مبدل) داریم. برای این کار باید کلاسی بسازیم که از ورودیش eReaderInterface باشه و خروجیش BookInterface پس میشه چیزی شبیه این https://gist.github.com/vahid-almasi/f122d21013316e1974dc01726b2712b0 برای این که ورودی تابع قوانین این &quot;ReaderInterface&quot; اینترفیس باشه همین اینترفیس رو گذاشتیم واسه type-hinting (قبل آرگومان ورودی متد کانستراکتور) و برای این که کلاس خروجیش تابع قوانین این &quot;BookInterface&quot; اینترفیس باشه کلاس رو از همین اینترفیس ایمپلمنتس میکنیم، حالا متد turnOn رو داخل Open و pressNextButton رو داخل turnPage بر میگردونیم.و از آداپتوری که ساختیم اینجوری استفاده میکنیم  https://gist.github.com/vahid-almasi/fdf996c151257bb6f0081178903cc752 امیدوارم قابل فهم بوده باشه، اگه نظری انتقادی برای بهتر شدن مطلب هست لطفا از یه طریقی به من نظرتون رو برسونید خوشحال میشم.و در آخر لینک کامل پروژه روی گیت هاب و منبع که همون جفری وی عزیز هست و من فقط برداشت های خودم رو در قالب این مطلب نوشتم. https://github.com/laracasts/Getting-Jiggy-With-Adapters  https://laracasts.com/series/design-patterns-in-php/episodes/2 </description>
                <category>vahid almasi</category>
                <author>vahid almasi</author>
                <pubDate>Thu, 18 Jul 2019 02:29:44 +0430</pubDate>
            </item>
                    <item>
                <title>الگوریتم آذینگر - Decorator pattern با زبان PHP</title>
                <link>https://virgool.io/@vahid_almasi/%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D8%A2%D8%B0%DB%8C%D9%86%DA%AF%D8%B1-decorator-pattern-%D8%A8%D8%A7-%D8%B2%D8%A8%D8%A7%D9%86-php-f2bmakwcr8ks</link>
                <description>الگوریتم آذینگر - Decorator pattern با زبان برنامه نویسی PHP خب بیاید تصور کنیم که یک تعمیرگاه ماشین داریم و میخوایم یک برنامه براش بنویسیم.همونجوری که میتونید تصور کنید این تعمیرگاه میتونه خدمات مختلفی داشته باشه اما اولین و پایه ای ترین سرویسش چک(معاینه) کردن ماشین هستش  https://gist.github.com/vahid-almasi/6f31e2470c5374e5b7b49a1f0811fece وقتی کد رو اجرا کنید 19 رو توی خروجی میبینید که درسته، حالا فک کنید که خدمات دیگه ای مثل تعویض روغن(oil change) یا جابه جایی لاستیک (tire rotation ) رو هم به سرویس ها اضافه کنیم. https://gist.github.com/vahid-almasi/c8ae8665cf2cd13ebedcb23db8b8db3b خروجی عدد درستی هست اما اگر دقت کنید با کوچیک ترین تغییر همه چی به هم میریزه مثلا اگر قیمت معاینه ماشین تغییر کنه! چون ما همه قیمت ها رو هاردکد کردیم باید همه قیمت ها رو پیدا کنیم و تغییرشون بدیم، حالا فک کنید که فقط یک عدد ساده نباشه و مبلغ با یه فرمول و چندین تا شرط محاسبه بشه!! یا اگه کسی فقط نیاز به تعویض روغن داشته باشه تکلیف چی میشه؟!!خب اگر بخوایم بهتر بنویسیمش میتونیم این کار رو انجام بدیم: https://gist.github.com/vahid-almasi/5b9ec68002817ad6a3f038444612392d خب اول از همه یک interface درست کردیم که همه کلاس ها رو از اون implements کنیم که همه مجبور باشند که یک public function getCost داشته باشن و حتی آرگومان ورودی construct__ رو هم باهاش ولیدیت (راستی آزمایی) کردیم، بعد شئ(object) ورودی رو به یک مقدار protected دادیم و از تابع getCost این شئ، داخل این کلاس استفاده کردیم و مقدار این سرویس رو با سرویس ها قبلی جمع زدیم.چیز باحالی که این الگوریتم داره این هستش که میتونیم حالت های مختلفی رو داشته باشیم و به اندازه ای که نیاز داریم داینامیک(پویا) باشه، میشه تا دلتون میخواد سرویس جدید به تعمیرگاه اضافه کرد و مبلغ هر سرویس رو جدا یا با هم محاصبه کردبیاید یک کم گسترشش بدیم و توضیحات(Description) بهش اضافه کنیم https://gist.github.com/vahid-almasi/fc26e8dc8c3002abcf9c7a8ffbfa4e25 خب راستش برا اولین بار که این الگوی آذینگر یا Decorator pattern  رو دیدم یکم گیج شدم و فک کردم خب این چه کاریه من میتونم اینو اینجوری انجام بدم  https://gist.github.com/vahid-almasi/85b2779734f78bd461e1073a9565b146 ولی این دو تا چه فرقی با هم دارن؟!! چرا وقتی می تونم انقدر ساده موضوع رو حلش کنم انقدر کلاس درست کنم؟!!مهم ترین موضوع اینه که توی حل مسئله بالا یکی از قوانین SOLID رو یعنی  اصل باز/بسته بودن کلاس ها  یا همون  Open-closed principle  رو رعایت نکردیم، اگه شما هم مثل من هستید و یادتون میره این قانون چیه، ساده ترین تعریف اش میشه: &quot; کلاس ها باید به سادگی و بدون نیاز به تغییر قابل گسترش ( extendable ) باشند&quot; و اگه کلا نمی دونید چی هست پیشنهاد میکنم قوانین SOLID  رو بخونید. اون وقت میفهمیم که این الگو به ما کمک میکنه که اصول شئ گرایی رو رعایت کنیم و در نهایت کد های تمیز تر و توسعه پذیری بیشتری داشته باشیم.در اخر با تشکر از Jeffrey Way عزیز منبع : https://laracasts.com/series/design-patterns-in-php </description>
                <category>vahid almasi</category>
                <author>vahid almasi</author>
                <pubDate>Thu, 04 Jul 2019 20:41:39 +0430</pubDate>
            </item>
                    <item>
                <title>پنج اصل اولیه طراحی شی گرا  SOLID</title>
                <link>https://virgool.io/coderlife/%D9%BE%D9%86%D8%AC-%D8%A7%D8%B5%D9%84-%D8%A7%D9%88%D9%84%DB%8C%D9%87-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7-solid-aozniwbsq4nb</link>
                <description>S.O.L.I.D     OBJECT ORIENTED DESIGNسولید ( SOLID ) یک کلمه مخفف برای پنچ اصل اولیه طراحی شئ گرا است که رابرت سیسیل مارتین معروف به عمو باب ( uncle bob ) اون رو مطرح کرد.  این اصول زمانی که دست به دست هم میدن، کار گسترش یا  اضافه کردن قابلیت های جدید به برنامه و نگهداری یا همون دیباگ یک برنامه رو برای برنامه نویس ها آسان می کنند. نکته: این فقط یک مطلب کوچیک و تعریفی از مفهوم S.O.L.I.D برای ورود به این مبحث هستشبیاین یک نگاهی به این کلمه مخفف بندازیم و برای هر کدام یک معادل فارسی شاید یک کم عجیب براشون بنویسیم Single-responsiblity principle - S   اصل مسئولیت واحد یا اصل تک مسئولتی بودن کلاس هاOpen-closed principle - O اصل باز/بسته بودن کلاس هاLiskov substitution principle - L اصل جانشینی لیسکوفInterface segregation principle - I اصل تفکیک اینترفیسDependency Inversion Principle - D  اصل انطباق پذیری  اصل مسئولیت واحد یا اصل تک مسئولتی بودن کلاس ها S - Single-responsiblity principle خب برای درک بهتر این اصول بیاید برای هر اصل توضیح و با یک مثال اون رو برسی کنیم. # اصل مسئولیت واحد یا  Single-responsibility Principle  حرف s به معنی Single-responsibility Principle یا به صورت خلاصه SRP :  که به معنی این است که یک کلاس باید فقط و فقط به یک دلیل تغییر کند یعنی این کلاس باید تنها یک کار انجام دهد.بیاید با یک مثال موضوع رو درک کنیم :برای مثال ما تعدادی اشکال هندسی داریم و میخواهیم که جمع مساحت این شکل ها رو حساب کنیم https://gist.github.com/vahid-almasi/487a16ae68d8847922b2f756e3db469d خب در قدم اول ما کلاس شکل های مختلف رو میسازیم و پارامتر های الزامی هر کدام از شکل ها رو با تابع  constructor سِت میکنیم، در قدم بعدی میریم که کلاس محاسبه کننده مساحت ( AreaCalcuator ) و بعد از اون میریم که منطق برای جمع زدن این مساحت ها رو درست کنیم https://gist.github.com/vahid-almasi/e83c677425543f856ed2533260dd75f6 برای استفاده از کلاس AreaCalculator به سادگی از این کلاس instance  میگیریم و یک آرایه از شکل ها رو به اون پاس میدیم و در آخر خروجی رو نمایش میدیم. https://gist.github.com/vahid-almasi/9096b43f46a24841e1eecf71a820de4c مشکلی که وجود داره تعیین شکل یا نوع خروجی (output) بر عهده کلاس AreaCalculator است یا به عبارت دیگه منطق خروجی داخل کلاسِ AreaCalulator است. خب چی می شد اگر کاربر داده خروجی رو به شکل json یا هر شکل دیگری نیاز داشت؟  در حال حاضر تمام منطق توسط کلاس AreaCalculator داره شکل میگیره و این چیزی نیست که ما به اون SRP میگیم، کلاس AreaCalculator باید تنها مساحت شکل ها رو جمع بزنه و کاری با این که کاربر خروجی Json نیاز داره یا HTML نداشته باشه. خب پس برای درست کردن این موضوع یک کلاس SumCalculatorOutputter درست میکنیم و منطق این که  خروجی چجوری باشه رو داخل این کلاس میگذاریم بنابر این کلاس SumCalculatorOutputter باید به این شکل کار کنه: https://gist.github.com/vahid-almasi/4bf0fdcbe3eefd6395dff702764a33c6 هممم، حالا منطق و شکل داده خروجی در کلاس  SumCalculatorOutputter قرار دارد. # اصل باز/بسته Open-closed Principle  به زبان ساده کلاس ها باید به سادگی و بدون نیاز به تغییر قابل گسترش ( extendable ) باشند. بیاید یک نگاه به کلاس AreaCalculator به خصوص تابع sum. https://gist.github.com/vahid-almasi/657ddcd7d17e02bc8bf1eea0bb2b1346 اگر ما بخواهیم که این تابع قابلیت جمع  زدن مساحت شکل های بیشتری رو برای ما داشته باشه باید شروط (if/else) بیشتری تعریف کنیم، که این برخلاف Open-closed principle است.پس بهتره منطق حساب کننده مساحت هر شکل رو از تابع sum بیرون بیاریم و به کلاس شکل ها اضافه اش کنیم  https://gist.github.com/vahid-almasi/5951433bbd49a33e2b69a140f28ac4e6 همین کار هم باید برای کلاس Circle انجام بشه و  تابع area به این کلاس اضافه بشه. خب برای محاسبه جمع مساحت هر شکل ارائه شده باید به همین اندازه ساده باشه: https://gist.github.com/vahid-almasi/3a5b037f30b2a73bdf6acac2f9db2e49  حالا می تونیم هر شکل دیگه ای که نیاز داریم اضافه کنیم بدون این که اصل دوم SOLID رو زیر پا بزاریم. خب حالا یک مشکل دیگه وجود داره، چطور میشه فهمید که شئی (‌ object) که به AreaCalculator پاس داده میشه آیا یک شکل هندسیه؟ اگر هم شکل باشه آیا تابعی به نام area داره؟  نوشتن یک  interface بخش جدایی ناپذیر از S.O.L.I.D است، پس باید یک interface بنویسیم و هر شکل جدیدی که قرار بود اضافه بشه رو باید از این اینترفیس implements کنیم، در کد پایین این کار برای کلاس Circle انجام شده: https://gist.github.com/vahid-almasi/eaf5b2c8cac485dfac6abd3856bd9f61 و در اخر در تابع sum در کلاس AreaCalculator ما چک می کنیم که همه شکل ها و شی هایی که به ما داده شده از ShapeInterface اینستنس (instance) گرفته شده باشن، در غیر این صورت برای خروجی یک Exception ارسال میکنیم  https://gist.github.com/vahid-almasi/fd076f3be0ebccb2cda8ab30e4853fe1  # اصل جانشینی لیسکوف Liskov substitution principle فرض کنیم (q(x یک ویژگی قابل اثبات در مورد اشیاء x از نوع T است. آنگاه(q(y باید قابل اثبات برای اشیاء y از نوع S باشد که در آن S یک زیر گروه از T است.اینم نسخه اصلی نوشته است:Let Φ(x) be a property provable about objects x of type T. Then Φ(y)should be true for objects y of type S where S is a subtype of T. خوب، بیایید صادق باشیم یک همچین تعریف علمی ممکنه لازم باشه، اما در کار روزمره ما به عنوان توسعه دهنده کمک زیادی نمی کنه. خب، این چه معنی دارد؟ همه این کلمات به این معنی هستند که هر زیرکلاس(subclass) یا کلاس مشتق گرفته شده ( derived class  ) باید قابلیت تعویض با کلاس پایه یا والد( parent ) رو داشته باشن.یا به زبان ساده تر هر کلاسی که از کلاس دیگر ارث بری میکنه هرگز نباید رفتار کلاس والد رو تغییر بده.تعاریف زیاد شد پس بریم سراغ مثال:اجازه بدید که باز هم از کلاس AreaCalculator استفاده کنیم،‌ پس یک کلاس  VolumeCalculator  میسازیم که از این کلاس extends گرفته شد https://gist.github.com/vahid-almasi/17cf0959530b4d52b421da2c6cd591e0  و داخل کلاس SumCalculatorOutputter   https://gist.github.com/vahid-almasi/8cdee8bc20e05b28b32d78bba7a889e5 اگر ما تلاش کنیم که یک همچین چیزی اجرا کنیم  https://gist.github.com/vahid-almasi/f69a08e7be8c3ef7689990184cdf4c9b برنامه بدون مشکل اجرا میشه، اما زمانی که تابع HTML رو از output2 بخواهیم ما یک E_NOTICE میگیریم  که میگه یک آرایه ای باید تبدیل به رشته (string) بشه.برای رفع این مشکل باید به جای خروجی ارایه در تابع sum در کلاس VolumeCalculator ، آن را ساده برگیدانیم https://gist.github.com/vahid-almasi/9dcd66436a9ff63bf949b4df489b250a   حالا دیگه خروجی میتونه یک عدد کسری یا صحیح یا ... باشه  #  اصل تفکیک اینترفیس Interface segregation principle یک توسعه دهنده نباید مجبور  implement کردن یک interface بشه که از اون استفاده نمیکنه یا توسعه دهنده نباید به اجبار وابسته به تابعی باشه که براش بی استفاده اس.یا به عبارت دیگر به جای یک interface بزرگ باید چندین interface تفکیک شده و کوچک داشته باشیم خب ما هنوز میخوایم از همون شکل ها مثال بیاریم، بیایم محاسبه حجم رو هم اضافه کنیم و اول از همه از  ShapeInterface شروع کنیم https://gist.github.com/vahid-almasi/7a4bc628a8c41c6bb2a61438cfabd741 حالا دیگه هر شکل جدیدی که بخوایم اضافه کنیم باید تابع  volume رو داشته باشه، یک لحظه صبر کنید، همه میدونیم مربع شکل دو بعدی (flat) و عملا حجمی نداره و این interface کلاس Square رو مجبور میکنه که تابعی داشته باشه که هیچ وقت قرار نیست مورد استفاده قرار بگیره و این خلاف اصل ISP است.برای رعایت اصل تفکیک اینترفیس  SolidShapeInterface  رو می نویسیم که کلاس های شکل هایی که دارای حجم هستند مثل مکعب از این اینترفیس  implement  بگیرند https://gist.github.com/vahid-almasi/fbf42881c5ee99abb8e993693bd7237f  حالا رویکرد کار خیلی بهتر شد، اما مراقب تله type-hinting برای interface ها باشید. # اصل انطباق پذیری Dependency Inversion Principle این اصل به ما میگه که کدهای موجود باید به مفاهیم (abstractions) متکی باشند نه به خواص. کلاس های سطح بالا نباید وابستگی مستقیم به کلاس های سطح پایین باشن که در صورت بروز تغییر در کلاس های سطح پایین مجبور باشیم که کلاس های سطح بالا رو هم تغییر بدیم.توی تعریف ممکنه سخت به نظر بیاد اما بیایم با یک مثال اون رو کاملا قابل درک کنیم: https://gist.github.com/vahid-almasi/2a33b241f5ca64be318ed8de21d182ce خب توی کد بالا همون طور که میبینید کلاس PasswordReminder سطح بالا (high level) و کلاس  MySQLConnection  سطح پایین (low level) است، اما کد بالا خلاف اصل D از S.O.L.I.D است چون PasswordReminder که سطح بالا است به MySQLConnection وابسته است.یعنی اگر ما بخواهیم  دیتابیس انجین خودمون رو عوض کنیم مثلا از mongoDB استفاده کنیم باید کلاس PasswordReminder رو تغییر بدیم که به این ترتیب اصل باز/بسته یا  Open-close principle رو هم رعایت نکردیم.کلاس PasswordReminder باید وابستگیی به این که چه دیتابیس انجینی استفاده میشه نداشته باشه، و باز هم برای درست کردن این بخش از کد ما میتونیم یک اینترفیس بنویسیم چون کلاس های سطح بالا و پایین باید به مفاهیم  abstractions وابسته باشند به معنی که وابسته بودن به یک اینترفیس مشکلی ندارد: https://gist.github.com/vahid-almasi/d0f12c3c359a08257c1467a21c26c08e اینترفیس ما یک تابع connect دارد و کلاس MySQLConnection  هم از این اینترفیس implements میگیرد، و همچنین مستقیما کلاس MySQLConnection در تابعِ constructor کلاسِ PasswordReminder تایپ هینتینگ (type-hinting) میشه، حالا دیگه مهم نیست که برنامه شما از چه نوع دیتابیسی استفاده میکنه و کلاس  PasswordReminder به سادگی و بدون مشکل و بدون نقض OCP به دیتابیس وصل میشه. https://gist.github.com/vahid-almasi/ace359ae4ce7298ee722b9f1b978c9f5 با توجه به کد بالا ، شما می توانید ببینید که هر دو ماژول سطح بالا و سطح پایین با abstraction یا مفهوم به  مربوط  هستند.این هم از لینک گیت هاب پروژه برای درک بهتر مطلب، داخل این پروژه سعی کردم که کامیت ها به ترتیب توضیحات باشه https://github.com/vahid-almasi/solid منابعی که ازشون توی نوشتن این مطلب استفاده کردم : https://scotch.io/bar-talk/s-o-l-i-d-the-first-five-principles-of-object-oriented-design و طبیعتا ویکی پدیا</description>
                <category>vahid almasi</category>
                <author>vahid almasi</author>
                <pubDate>Sat, 22 Dec 2018 02:09:56 +0330</pubDate>
            </item>
            </channel>
</rss>