<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های محمد ایل بیگی</title><link>https://virgool.ir/feed/@ilbeygi.m</link><description>یک برنامه نویس</description><language>fa</language><pubDate>2026-11-11 16:53:39</pubDate><image><url>https://files.virgool.ir/upload/users/7590/avatar/xBs34x.png</url><title>محمد ایل بیگی</title><link>https://virgool.ir/@ilbeygi.m</link></image><item><title>قسمت ۳ :‌ در مورد اکسچنچ‌ها در  یک  message broker صحبت کنیم</title><link>https://virgool.ir/@ilbeygi.m/در-مورد-اکسچنچ-ها-در-یک-message-broker-صحبت-کنیم-o2rk7lsy3gpb</link><description>در مطلب قبلی در مورد سه اصطلاح یک message broker صحبت کردیم و یک داستان ساده و سلیس و روان گفتم. https://virgool.io/@ilbeygi.m/a-few-basic-message-broker-terms-c4io5olbcznd حالا توی این مقاله میخوایم در مورد exchange ها تو message broker با هم صحبت کنیم. در واقع میشه گفت که exchange کارش انتقال پیام به queue با استفاده از route key ها هستش و در اصل کاری که میکنه message هارو به queue ها bind میکنه.توی rabbitmq یا بهتره بگم تو پروتکل AMQP 0.9.1 چهار نوع مختلف Exchange داریم که در زیر هر کدومش رو در حد دانش خودم توضیح میدم. اولیش : Direct exchangeتو این نوع از exchange پیام‌ها به صورت مستقیم به صف ارسال میشن یعنی یک مسیریابی مستقیم دارن که این مسیریابی با استفاده از route key انجام میشه. اینطور فرض کنید که اگر پیام با routeKey = X رو ارسال کنیم و یک صف داشته باشیم که پیام‌های با   routeKey = Y رو قبول میکنه، این exchange پیام رو ارسال نمیکنه چون routeKey پیام‌ با routeKey مورد پذیرش تو صف متفاوت هستند.و اما یک مثال :Direct Exchangeدر این مثال ما یک سری پیغام رو میخوایم از producer به consumer هامون ارسال کنیم که اسم exchangeای هم که داریم test_direct هست.همونطور که روی عکس هم میبینید سه تا صف داریم که هر کدوم یک routeKey داره و اگر ما سه تا پیغام داشته باشیم میبینیم که هر پیغام فقط به صفی میره که اون routeKey رو داره. مثلا صفی که banana و apple رو به عنوان routeKey داره پیغام‌های 2 و 3 که routeKey شون banana, apple هست رو قبول میکنن ( بهتره بگیم که exchange پیغام‌هارو bind  میکنه). نکته :‌ exchange ها به طور پیشفرض از نوع Direct هستند مگه اینکه شما موقع تعریف بگید که میخواین نوع exchange تون چی باشه ولی اگر نوعش رو مشخص نکنید Direct میزنه براتون.۲. دومیش : Fanout exchangeاین exchange نگاه نمیکنه که اون صف چه routeKey داره و فقط مهم اینه که صف به exchange وصل باشه یا بهتره بگم که bind شده باشه. همین بهونه براش کافیه که هر پیغامی که به رسید رو بخواد روی همه صف‌ها بذاره.خب بریم یک مثال هم برای این ببینیم :Fanout Exchangeخب تو عکس بالا میبینید که producer یک پیام رو میده به exchangeای از نوع fanout و بعد اون exchange پیام رو برمیداره و روی سه تا صف میذاره و اینجا کاری به routekey و ... نداره و پیام رو به همه صف‌هایی که باهاشون در ارتباط هست میده.۳. سومیش : Topic exchangeاین exchange یک طورایی (البته نظر شخصیه‌ها  :) ) محصول مشترک direct و fanout هستش. به این علت اینو میگم که یک پترن به عنوان routeKey میگیره و پیام رو به صف‌هایی که routeKey شون اون پترن رو قبول کنه میده.این نوع exchange یعنی topic خیلی خوبه و شما میتونید یه طورایی فقط از همین مورد تو اکثر معماریتون استفاده کنید. خالی از لطف هم نیست که بدونید توی kafka فقط topic وجود داره و مدل‌های دیگه نیست.و اما خب تا توی عکس نشون ندم نمیشه خوب منظور رو رسوند.Topic Exchange( منبع سایت RabbitMQ ) : تو این مثال، ما پیام‌هایی رو ارسال می‌کنیم که همگی یک سری حیوانات رو توصیف می‌کنن. پیام ها با یک کلید مسیریابی که از سه کلمه (دو نقطه) تشکیل شده ارسال میشن. اولین کلمه در کلید مسیریابی نوع سرعت حیوان، دوم یک رنگ و سوم یک گونه رو توصیف میکنه، به این صورت : &#34;&lt;celerity&gt;.&lt;colour&gt;.&lt;species&gt;&#34;.ما سه اتصال ایجاد کردیم: صف Q1 با کلید  &#34;*.orange.*&#34; و صف Q2 با &#34;*.*.rabbit&#34; و &#34;lazy.#&#34; بایند شده است.این اتصالات (Bindings) را میتونیم اینطور خلاصه کنیم:صف اول یا Q1 به تمام حیوانات نارنجی علاقه مند است.صف دوم یا Q2 می خواهد همه چیز درباره خرگوش ها و همه چیز در مورد حیوانات تنبل بشنود.یک پیام که با کلید مسیریابی &#34;quick.orange.rabbit&#34; تنظیم شده است به هر دو صف تحویل داده میشه. پیام &#34;lazy.orange.elephant&#34; نیز به هر دوی آنها خواهد رفت. از طرف دیگه &#34;quick.orange.fox&#34; فقط به صف اول و &#34;lazy.brown.fox&#34; فقط به صف دوم خواهد رفت. &#34;lazy.pink.rabbit&#34; تنها یک بار به صف دوم تحویل داده می شود، حتی اگر با دو حالت اتصال (binding) مطابقت داشته باشد. &#34;quick.brown.fox&#34; با هیچ نوع binding مطابقت ندارد، بنابراین دور انداخته میشه. ۳. چهارمیش : Headers exchangeو اما آخرین نوع exchange، در این نوع ما routeKey نداریم و پیام‌ها رو با استفاده از header هایی که داریم مسیریابی میکنیم تا ببینیم به کدوم صف تحویل بدیم.و اما عکس :Headers Exchangesهمونطور که در عکس بالا میبینید یک پیام با هدر  {&#34;key1&#34;, &#34;value1&#34;} ارسال شده و exchange اون رو به صف اول میده. شاید براتون سوال پیش بیاد که چرا پیام رو به صف اول داد ولی به صف آخر نداد، این به خاطر x-match هست. اگر x-match مقدار any داشته باشه header اگر با یک مقدار هم برابر بود پیام رو اون صف قرار میگیرده ولی اگر x-match مقدار  all رو داشته باشه باید کل  header پیام با صف یکی باشن تا پیام توی صف قرار بگیره.میدونم خیلی خلاصه گفتم و کلی مطلب دیگه هست که میشه گفت ولی سعی کردم خلاصه باشه.امیدوارم از خوندن این مطلب لذت برده باشید.موفق باشید https://vrgl.ir/wRa30  https://vrgl.ir/7tfxs </description><category>محمد ایل بیگی</category><author>محمد ایل بیگی</author><pubDate>Mon, 22 Nov 2021 23:40:49 +0330</pubDate></item><item><title>قسمت دوم : چند اصطلاح اولیه  message broker</title><link>https://virgool.ir/@ilbeygi.m/a-few-basic-message-broker-terms-c4io5olbcznd</link><description>و اما در ادامه پست‌های مربوط به message broker ها که بیشتر حول rabbitmq هم میچرخه امروز میخوایم با سه مورد مورد اصلی از یک message broker آشنا بشیم.همونطور که توی عکس پست هم مشخص هست و میتونید ببینید، این سه مورد شامل producer , broker و consumer میشن که هر کدوم رو در حد وسع خودم توضیح میدم و دوستان هم اگر در کامنت‌ها کمک برسونن ممنون میشم.برای اینکه با بحث راحت تر مواجه بشیم بذارید من داستان ارسال یک نامه رو بگم.روزی علی میخواد یک کاری رو به محمد بگه انجامش بده.علی کار رو در قالب یک نامه (کاربرگ) مینویسه تا به دست محمد برسونه.علی کاربرگی که نوشته رو میده به دست پستچی تا اون رو پستچی برسونه به دست محمد.محمد کاربرگ رو از پستچی دریافت میکنه و شروع میکنه به خوندن کاربرگ و انجام کارایی که باید انجام بده.خب حالا اینجا ما با سه نفر سروکار داشتیم اول علی بود که میخواست یک پیام رو ارسال کنه که توی اصطلاحات message broker بهش میگیم producer و بعد پستچی که نقش دریافت پیام و ارسالش به محمد رو داشت که در غالب broker برامون عمل کرد و آقا محمدم که میخواست پیام رو دریافت کنه و کار رو انجام بده در نقش consumer ظاهر شد.پس باید یکی پیام رو درست کنه که میشه producer و یکی پیام رو ارسال کنه که میشه broker و یکی هم پیام رو دریافت کنه و … که میشه consumer.این تا اینجای کار !!!خب اما یک نکته دیگه موند.اونم اینکه broker خودش به دو بخش تبدیل میشه : ۱ - exchange  و ۲- queueکه در اصل میشه گفت exchange کار بایند(bind) کردن پیام به یک صف (queue) رو داره و میگه که مثلا پیام علی تو کدوم صف قرار بگیره که محمدم بهش دسترسی داره تا بتونه ازون صف پیام علی رو برداره.امیدوارم که گیج کننده نبوده باشه.ممنون میشم اگر دوستان نکته‌ای میبینن که نیازه در کامنت‌ها محبت کنن‌ و بگن.#message_broker#rabbitmq https://vrgl.ir/wRa30 </description><category>محمد ایل بیگی</category><author>محمد ایل بیگی</author><pubDate>Sun, 12 Sep 2021 00:14:55 +0430</pubDate></item><item><title>قسمت ۱ : و اما message broker چیست !</title><link>https://virgool.ir/@ilbeygi.m/و-اما-message-broker-چیست-y2virwdkupiw</link><description>سلاممدتیه که دارم در مورد message brokerها میخونم و خیلی دوست دارم که بتونم چیزایی هم که ازش یاد میگیرم رو با دوستان درمیون بذارم.خب اول اینکه message broker کلا چی هست !؟در یک نگاه خیلی ساده میشه بهش گفت که وظیفه انتقال (ترجمه) پیام از فرستنده به گیرنده رو داره ! یعنی در واقع میشه گفت یک صرافی پیام هست.و اما بیشتر وقتی به کارمون میاد که ما یک حجم زیادی از پیام‌ها رو داریم که پردازش به یک باره‌شون سخته برامون و اینجاست که ما باید یک سیستم متمرکز داشته باشیم که بتونیم این پیام‌هارو به جاهایی که نیاز داریم برای پردازش ارسال کنیم.مثلا فرض کنید در یک سیستم که معماری microservice داره شما میخواین یک سری داده و پیام رو بین microservice های مختلف پخش کنید که پردازش‌های مورد نیاز رو انجام بدن، اینجا استفاده از message broker میتونه خیلی بهتون کمک کنه و کارتون رو راحت کنه.یا مثلا شما یک پروژه IOT دارید که کلی دیوایس قراره داده ها و پیام هاشون رو ارسال کنن ! اینجا هم با استفاده از message broker ها خیلی راحت میتونید دیتاهارو برای پردازش به جاهایی که میخواین منتقل کنید.خلاصه اینکه وقتی وارد پروژه میشید به جا اینکه هی بخواین دیتاها یا همون پیام‌هاتون رو توی دیتابیس یا جایی ذخیره کنید بعد برشون دارید و پردازش کنید راهکار بهتر اینه که از message broker استفاده کنید.دوتا از message broker های معروف که بیشتر به گوشمون شاید خورده باشه kafka و rabbitmq هستن. (البته موارد دیگه‌ زیادی هستن مثل HiveMQ , .... ولی فعلا به اسم همین دوتا اکتفا میکنیم)اگر جایی از متن مشکل داره یا دوستان میتونن اطلاعات بهتری اضافه کنن ممنون میشم در کامنت ها همراهی کنن.سپاس از همگی شما#rabbitmq #message_broker #kafka</description><category>محمد ایل بیگی</category><author>محمد ایل بیگی</author><pubDate>Sun, 12 Sep 2021 00:09:03 +0430</pubDate></item><item><title>قسمت دوم :‌ دیزاین پترن Factory Method</title><link>https://virgool.ir/@ilbeygi.m/part-2-factory-method-design-pattern-dsr8vwaammdf</link><description>هدف :دیزاین پترن Factory Method یک دیزاین پترن خلاقانه می باشد که یک اینترفیس برای ساخت اشیا در یک سوپر کلاس را فراهم می کند، اما اجازه می دهد که کلاس های فرزند ( زیر کلاس ها ) نوع اشیاءی که ساخته می شوند را تغییر دهند.مسئله :تصور کنید که شما در حال ساخت یک اپلیکیشن مدیریت لوجستیک هستید.  اولین ورژن از اپ شما تنها قادر به هندل کردن حمل و نقل با کامیون ها می باشد، بنابراین بخش عمده ای از کد شما در کلاس Truck قرار می گیرد.بعد از مدتی، اپ شما مورد توجه واقع می شود و بسیار محبوب می شود. هر روز ده ها درخواست از شرکت های حمل و نقل دریای برای وارد کردن تدارکات درایی در برنامه دریافت خواهید کرد.افزودن یک کلاس جدید به برنامه در صورتی که بقیه کد با کلاسهای موجود همراه باشد، کار آسانی نیست.و اما یک خبر عالی ! در حال حاضر اکثر کد شما با کلاس Truck همراه است. افزودن Ships به اپ نیازمند تغییرات زیاد در کدهای پایه ای شما دارد به علاوه اینکه اگر بعدا تصمیم به افزودن یک نوع جدید حمل و نقل در اپ داشته باشید شما مجدد مجبور هستید که همه این تغییرات را مجدد انجام دهید.درنتیجه اینکه شما در این وضعیت با یک کد بسیار نامطبوع مواجه خواهید شد، کدی که رفتار برنامه را بسته به نوع کلاس اشیاء حمل و نقل تغییر می دهد.راه حل :پترن Factory Method به شما پیشنهاد می دهد که فراخوانی های ساخت یک شی به صورت مستقیم را ( با استفاده از کلمه new ) با  فراخوانی یک متد factory خاص جایگزین کنید. نگران نباشید، اشیاء از طریق کلمه new ساخته می شوند، اما در داخل متد factory فراخوانی می شوند. اشیاء برگردانده شده توسط Factory Method اغلب به عنوان یک محصول ( products ) معرفی می شوند.ساب کلاس ها (زیر کلاس) می توانند کلاس اشیائی که توسط factory method باز گردانده می شوند را تغییر دهند.در نگاه اول،‌این تغییر ممکن است که بیهوده باشد: ما فقط فراخوانی تابع سازنده کلاس را از یک بخش از برنامه به بخش دیگری تغییر می دهیم. همچنین، این را در نظر بگیرید: حال شما می توانید که factory method را در یک زیر کلاس override کنید و کلاس محصولاتی که با این روش ایجاد شده است را تغییر دهید.محدودیت های جزئی نیز وجود دارد: ممکن است زیر کلاس ها تنها در صورتی که محصولات کلاس پایه یا interface مشترکی داشته باشند انواع مختلفی از محصولات را برگردانند. همچنین، factory method در کلاس پایه بایستی نوع بازگشت خود را به عنوان این interface اعلام کند.تمام محصولات بایستی از همان interface پیروی کنند.برای مثال: دو کلاس Truck و Ship بایستی با Interface Transport پیاده سازی شوند، که اعلام می کند یک متد deliver فراخوانی شود. هر کلاس این متد را متفاوت پیاده سازی می کند: trucks ها ( کامیون ها ) محموله ها را به صورت زمینی تحویل می دهند، ships ( کشتی ها )‌محموله ها را به صورت دریاییی تحویل می دهند. factory method در کلاس RoadLogistics اشیاء truck را بر می گرداند، درحالی که factory method در کلاس SeaLogistics اشیاء ships را بر می گرداند.تا زمانی که تمام کلاس های محصول با یک interface مشترک پیاده سازی می شوند، شما می تواند اشیاء آنها را بدون شکستن به کد مشتری منتقل کنید.کدی که در factory method استفاده می شود ( که اغلب به آن کد client گفته می شود) تفاوت کالاهای واقعی برگشتی توسط زیر کلاس های مختلف را مشاهده نمی کند. client با تمام محصولات به صورت یک abstract Transport رفتار می کند. client می داند که تمام اشیاء transport قرار بود متد deliver را داشته باشند، اما اینکه دقیقا چطور کار می کند برای client مهم نیست.ساختار : با توجه به عکس بالا :۱ . در ابتدا interface Product اعلام می شود، که برای همه اشیائی که می تواند توسط creator و زیر کلاس های آن ساخته شود مشترک است.۲ . در اینجا Concrete Products پیاده سازی های متفاوت از product interface هستند.۳ . کلاس Creator مشخص می کند factory method اشیاء جدید product را بر می گرداند. این مهم است که نوع برگشتی این متد با product interface مطابقت دارد.شما می توانید factory method را به عنوان abstract برای همه زیر کلاس ها اجبار کنید تا در نسخه های متد خود پیاده سازی کنند. به عنوان جایگزین، پایه factory method می تواند نوع محصول پیش فرض را برگرداند.توجه داشته باشید، با وجود این نام گذاری، تولید محصول مسئولیت اصلی creator نیست.معمولا، کلاس creator قبلا منطق اصلی تجارت مربوط به محصولات را داشته است. factory method به جدا کردن این منطق از کلاس concrete product کمک می کند. در اینجا یک آنالوژی هست: یک کمپانی بزرگ توسعه نرم افزار می تواند یک دپارتمان آموزشی برای برنامه نویسان داشته باشد. همچنین، عملکرد اصلی شرکت به عنوان یک مجموعه هنوز نوشتن کد است، نه تربیت و تولید برنامه نویس.۴ . در آخرین قسمت Concrete Creators پایه factory method آورراید (‌override‌)‌ می شود بنابراین آن یک نوع مختلف از محصول را بر می گرداند.توجه داشته باشید که در factory method نیاز به ایجاد نمونه های جدید برای همیشه نیست. بلکه می توان اشیاء موجود را از یک کش، یک استخر شی یا منابع دیگر برگرداند.شبه برنامه : این مثال نشان می دهد که چطور می توان از Factory Method برای ایجاد عناصر UI کراس پلتفرم بدون اتصال کد client به کلاس های concrete UI استفاده کرد.مثالی از کراس پلتفرم دیالوگ.کلاس پایه  dialog عناصر UI مختلفی را برای ارائه دادن پنجره ( window ) استفاده می کند. تحت سیستم عامل های مختلف، این عناصر ممکن است اندکی به نظر برسند، اما آنها هنوز هم باید به طور مداوم رفتار کننده. یک دکمه در ویندوز هنوز یک دکمه در لینوکس می باشد و ماهیتشان یکی است.زمانی که factory method وارد بازی شد، شما احتیاجی ندارید که منطق dialog را برای هر سیستم عامل بازنویسی کنید. اگر ما یک factory method معرفی کنیم که دکمه های داخل کلاس dialog پایه را بسازد، ما می توانیم بعدا یک زیر کلاس dialog بسازیم که دکمه هایی با استایل ویندوز را از factory method برگرداند. سپس زیرکلاس ما بخش زیادی از کد های dialog را از کلاس پایه به ارث می برد، اما، از factory method تشکر می کنیم، چرا که می تواند دکمه های ویندوز را در صفحه نمایش دهد.برای اینکه این پترن کار کند، کلاس پایه dialog باید با abstract buttons کار کند: یک کلاس پایه یا یک interface که همه دکمه ها از آن پیروی کنند. بدین ترتیب کد dialog به صورت عملکردی باقی می ماند، طوری که هر نوع دکمه ای با آن کار می کند.البته، شما می توانید این رویکرد را برای عناصر UI  دیگر به خوبی درخواست کنید. همچنین، با اضافه کردن هر factory method جدید به dialog، شما به دیزاین پترن Abstract Factory نزدیک تر می شوید. نترسید، در ادامه در مورد این دیزاین پترن نیز صحبت خواهیم کرد.شبه کد : &#xA;class Dialog is&#xA;    abstract method createButton():Button&#xA;&#xA;    method render() is&#xA;        Button okButton = createButton()&#xA;        okButton.(closeDialog)&#xA;        okButton.render()&#xA;&#xA;&#xA;class WindowsDialog extends Dialog is&#xA;    method createButton():Button is&#xA;        return new WindowsButton()&#xA;&#xA;class WebDialog extends Dialog is&#xA;    method createButton():Button is&#xA;        return new HTMLButton()&#xA;&#xA;interface Button is&#xA;    method render()&#xA;    method (f)&#xA;&#xA;class WindowsButton implements Button is&#xA;    method render(a, b) is&#xA;        // Render a button in Windows style.&#xA;    method (f) is&#xA;        // Bind a native OS click event.&#xA;&#xA;class HTMLButton implements Button is&#xA;    method render(a, b) is&#xA;        // Return an HTML representation of a button.&#xA;    method (f) is&#xA;        // Bind a web browser click event.&#xA;&#xA;&#xA;class Application is&#xA;    field dialog: Dialog&#xA;&#xA;    method initialize() is&#xA;        config = readApplicationConfigFile()&#xA;&#xA;        if (config.OS == &#34;Windows&#34;) then&#xA;            dialog = new WindowsDialog()&#xA;        else if (config.OS == &#34;Web&#34;) then&#xA;            dialog = new WebDialog()&#xA;        else&#xA;            throw new Exception(&#34;Error! Unknown operating system.&#34;)&#xA;&#xA;&#xA;    method main() is&#xA;        this.initialize()&#xA;        dialog.render(یک مثال مفهومی در زبان PHP :&lt;?php&#xA;&#xA;namespace RefactoringGuru\FactoryMethod\Conceptual;&#xA;&#xA;abstract class Creator&#xA;{&#xA;&#xA;    abstract public function factoryMethod(): Product;&#xA;&#xA;    public function someOperation(): string&#xA;    {&#xA;        // Call the factory method to create a Product object.&#xA;        $product = $this-&gt;factoryMethod();&#xA;        // Now, use the product.&#xA;        $result = &#34;Creator: The same creator&#39;s code has just worked with &#34; .&#xA;            $product-&gt;operation();&#xA;&#xA;        return $result;&#xA;    }&#xA;}&#xA;&#xA;&#xA;class ConcreteCreator1 extends Creator&#xA;{&#xA;&#xA;    public function factoryMethod(): Product&#xA;    {&#xA;        return new ConcreteProduct1;&#xA;    }&#xA;}&#xA;&#xA;class ConcreteCreator2 extends Creator&#xA;{&#xA;    public function factoryMethod(): Product&#xA;    {&#xA;        return new ConcreteProduct2;&#xA;    }&#xA;}&#xA;&#xA;interface Product&#xA;{&#xA;    public function operation(): string;&#xA;}&#xA;&#xA;class ConcreteProduct1 implements Product&#xA;{&#xA;    public function operation(): string&#xA;    {&#xA;        return &#34;{Result of the ConcreteProduct1}&#34;&#xA;    }&#xA;}&#xA;&#xA;class ConcreteProduct2 implements Product&#xA;{&#xA;    public function operation(): string&#xA;    {&#xA;        return &#34;{Result of the ConcreteProduct2}&#34;&#xA;    }&#xA;}&#xA;&#xA;function clientCode(Creator $creator)&#xA;{&#xA;    // ...&#xA;    echo &#34;Client: I&#39;m not aware of the creator&#39;s class, but it still works.\n&#34;&#xA;        . $creator-&gt;someOperation();&#xA;    // ...&#xA;}&#xA;&#xA;&#xA;echo &#34;App: Launched with the ConcreteCreator1.\n&#34;&#xA;clientCode(new ConcreteCreator1);&#xA;echo &#34;\n\n&#34;&#xA;&#xA;echo &#34;App: Launched with the ConcreteCreator2.\n&#34;&#xA;clientCode(new ConcreteCreator2);خروجی :App: Launched with the ConcreteCreator1.&#xA;Client: I&#39;m not aware of the creator&#39;s class, but it still works.&#xA;Creator: The same creator&#39;s code has just worked with {Result of the ConcreteProduct1}&#xA;&#xA;App: Launched with the ConcreteCreator2.&#xA;Client: I&#39;m not aware of the creator&#39;s class, but it still works.&#xA;Creator: The same creator&#39;s code has just worked with {Result of the ConcreteProduct2}یک مثال از دنیای واقعی در PHP :&lt;?php&#xA;&#xA;namespace RefactoringGuru\FactoryMethod\RealWorld;&#xA;&#xA;abstract class SocialNetworkPoster&#xA;{&#xA;  &#xA;    abstract public function getSocialNetwork(): SocialNetworkConnector;&#xA;&#xA;    public function post($content): void&#xA;    {&#xA;        // Call the factory method to create a Product object...&#xA;        $network = $this-&gt;getSocialNetwork();&#xA;        // ...then use it as you will.&#xA;        $network-&gt;logIn();&#xA;        $network-&gt;createPost($content);&#xA;        $network-&gt;logout();&#xA;    }&#xA;}&#xA;&#xA;&#xA;class FacebookPoster extends SocialNetworkPoster&#xA;{&#xA;    private $login, $password;&#xA;&#xA;    public function __construct(string $login, string $password)&#xA;    {&#xA;        $this-&gt;login = $login;&#xA;        $this-&gt;password = $password;&#xA;    }&#xA;&#xA;    public function getSocialNetwork(): SocialNetworkConnector&#xA;    {&#xA;        return new FacebookConnector($this-&gt;login, $this-&gt;password);&#xA;    }&#xA;}&#xA;&#xA;&#xA;class LinkedInPoster extends SocialNetworkPoster&#xA;{&#xA;    private $email, $password;&#xA;&#xA;    public function __construct(string $email, string $password)&#xA;    {&#xA;        $this-&gt;email = $email;&#xA;        $this-&gt;password = $password;&#xA;    }&#xA;&#xA;    public function getSocialNetwork(): SocialNetworkConnector&#xA;    {&#xA;        return new LinkedInConnector($this-&gt;email, $this-&gt;password);&#xA;    }&#xA;}&#xA;&#xA;interface SocialNetworkConnector&#xA;{&#xA;    public function logIn(): void;&#xA;&#xA;    public function logOut(): void;&#xA;&#xA;    public function createPost($content): void;&#xA;}&#xA;&#xA;class FacebookConnector implements SocialNetworkConnector&#xA;{&#xA;    private $login, $password;&#xA;&#xA;    public function __construct(string $login, string $password)&#xA;    {&#xA;        $this-&gt;login = $login;&#xA;        $this-&gt;password = $password;&#xA;    }&#xA;&#xA;    public function logIn(): void&#xA;    {&#xA;        echo &#34;Send HTTP API request to log in user $this-&gt;login with &#34; .&#xA;            &#34;password $this-&gt;password\n&#34;&#xA;    }&#xA;&#xA;    public function logOut(): void&#xA;    {&#xA;        echo &#34;Send HTTP API request to log out user $this-&gt;login\n&#34;&#xA;    }&#xA;&#xA;    public function createPost($content): void&#xA;    {&#xA;        echo &#34;Send HTTP API requests to create a post in Facebook timeline.\n&#34;&#xA;    }&#xA;}&#xA;&#xA;class LinkedInConnector implements SocialNetworkConnector&#xA;{&#xA;    private $email, $password;&#xA;&#xA;    public function __construct(string $email, string $password)&#xA;    {&#xA;        $this-&gt;email = $email;&#xA;        $this-&gt;password = $password;&#xA;    }&#xA;&#xA;    public function logIn(): void&#xA;    {&#xA;        echo &#34;Send HTTP API request to log in user $this-&gt;email with &#34; .&#xA;            &#34;password $this-&gt;password\n&#34;&#xA;    }&#xA;&#xA;    public function logOut(): void&#xA;    {&#xA;        echo &#34;Send HTTP API request to log out user $this-&gt;email\n&#34;&#xA;    }&#xA;&#xA;    public function createPost($content): void&#xA;    {&#xA;        echo &#34;Send HTTP API requests to create a post in LinkedIn timeline.\n&#34;&#xA;    }&#xA;}&#xA;&#xA;function clientCode(SocialNetworkPoster $creator)&#xA;{&#xA;    // ...&#xA;    $creator-&gt;post(&#34;Hello world!&#34;);&#xA;    $creator-&gt;post(&#34;I had a large hamburger this morning!&#34;);&#xA;    // ...&#xA;}&#xA;&#xA;echo &#34;Testing ConcreteCreator1:\n&#34;&#xA;clientCode(new FacebookPoster(&#34;john_smith&#34;, &#34;******&#34;));&#xA;echo &#34;\n\n&#34;&#xA;&#xA;echo &#34;Testing ConcreteCreator2:\n&#34;&#xA;clientCode(new LinkedInPoster(&#34;john_smith@example.com&#34;, &#34;******&#34;));خروجی : Testing ConcreteCreator1:&#xA;Send HTTP API request to log in user john_smith with password ******&#xA;Send HTTP API requests to create a post in Facebook timeline.&#xA;Send HTTP API request to log out user john_smith&#xA;Send HTTP API request to log in user john_smith with password ******&#xA;Send HTTP API requests to create a post in Facebook timeline.&#xA;Send HTTP API request to log out user john_smith&#xA;&#xA;&#xA;Testing ConcreteCreator2:&#xA;Send HTTP API request to log in user john_smith@example.com with password ******&#xA;Send HTTP API requests to create a post in LinkedIn timeline.&#xA;Send HTTP API request to log out user john_smith@example.com&#xA;Send HTTP API request to log in user john_smith@example.com with password ******&#xA;Send HTTP API requests to create a post in LinkedIn timeline.&#xA;Send HTTP API request to log out user john_smith@example.comلینک گیت هاب جهت حمایت شما دوستان : لینک گیت هابمنبع : ریفکتورینگگردآورنده :‌ تیم فنی نتیرالبا مشاهده قسمت اول می توانید لینک های قسمته های بعد را نیز مشاهده کنید : قسمت اول </description><category>محمد ایل بیگی</category><author>محمد ایل بیگی</author><pubDate>Wed, 22 Jul 2020 02:06:41 +0430</pubDate></item><item><title>قسمت اول : دیزاین پترن چیست ؟</title><link>https://virgool.ir/@ilbeygi.m/قسمت-اول-دیزاین-پترن-چیست-vlzsegpgpbhq</link><description>دیزاین پترن چیست ؟دیزاین پترن ها ‌( الگو های طراحی ) چی هستن ؟دیزاین پترن ها راه حل هایی معمولی برای مشکلاتی هستن که معمولا در طراحی نرم افزار اتفاق می افتد. دیزاین پترن ها مثل طرح ها از پیش ساخته هستن که شما می تونید برای حل مشکل طراحی در کد خودتون استفاده شون کنید.شما نمیتوید فقط یک تیکه کد پیدا کنید و اونو در برنامه خودتون کپی کنید، راه و روش شما می تواند چیزی خارج از چارچوب کتابخانه ها یا توابع باشد. یک پترن یا طرح یک تیکه کد نیست، اما یک مفهوم عمومی برای حل یک مشکل خاص هست. شما می توانید جزییات الگو یا پترن را دنبال کرده و راه حلی را متناسب با واقعیت های برنامه خود پیاده سازی کنید.پترن ها اغلب با الگوریتم ها اشتباه گرفته میشن،‌ به این دلیل که هر دو مفهوم راه حلهایی معمولی برای برخی از مشکلات شناخته شده رو توصیف می کنن. در حالی که یک الگوریتم همیشه مجموعه ای مشخص از اعمال را انجام میده تا به یک هدف مشخص برسه، اما یک پترن یک تعریف سطح بالا از یک راه حل هستش. ممکن است که کدهای پترن های یکسان برای دو برنامه متفاوت مشابه هم نباشن.مقایسه پترن با الگوریتم مثل یک دستور پخت و پز است، هر دو روش های روشنی برای رسیدن به هدف دارن. به عبارت دیگر، یک پترن بیشتر شبیه یک طرح است: شما می تونید ویژگی های اونو و اینکه چه چیزی به عنوان نتیجه و خروجی دارد را ببینید، اما اینکه چطور پیاده سازی بشه به عهده شما ( برنامه نویس ) هستش.پترن ها از چه چیزی تشکل شده اند؟اکثر پترن ها طوری تعریف می شوند که مردم بتونن در تمام زمینه ها از آنها استفاده کنند. همچنین در اینجا بخش هایی که معمولا در توضیحات هستند آورده شده است :هدف از پترن ها به طور خلاصه تعریف هم مشکل و هم راه حل می باشد.انگیزه مشکل را توضیح می دهند و راه حل پترن را ممکن می سازد.ساختار کلاس ها نشان دهنده هر قسمت از پترن و نحوه ارتباط آن هاست.نمونه کد در زبان های برنامه نویسی معروف و محبوب، سبب آسان تر شدن درک ایده پترن خواهد شد ( در این مجموعه آموزشی سعی می شود تا از نمونه کد ها زبان PHP استفاده شود).برخی از کاتالوگهای الگویی جزئیات مفید دیگری، مانند کاربرد پترن، مراحل اجرای و روابط با سایر پترن ها را ذکر می کند.کاتالوگ دیزاین پترن ها :پترن ها خلاقانه :این پترن های مکانیزم های مختلف ایجاد شی را ارائه می دهند، که انعطاف پذیری و استفاده مجدد از کد را افزایش می دهند.پترن های ساختاری :این پترن ها نحوه اسمبل کردن اشیاء و کلاس ها را در ساختار های بزرگتر با حفظ انعطاف پذیری و کارآمدی این ساختار ها توضیح می دهند.پترن های رفتاری :این پترن ها مربوط به الگوریتم ها و تعیین مسئولیت بین اشیا هستند.پایان قسمت اول.قصد دارم تا اگر وقت یاری کرد آموزشی های سایت منبع رو ترجمه کنم اینجا بذارم تا هم مروری برای خودم باشه هم کمکی به منابع فارسی در این زمینه کرده باشم.ممنون بابت وقتی که گذاشتید و این ترجمه ناقص رو خوندین.لینک گیت هاب جهت حمایت شما دوستان : لینک گیت هابمنبع : ریفکتورینگگردآورنده :‌ تیم فنی نتیرالقسمت دو : Factory Method</description><category>محمد ایل بیگی</category><author>محمد ایل بیگی</author><pubDate>Wed, 15 Jul 2020 10:58:23 +0430</pubDate></item><item><title>قوانین طلایی نام گذاری متغییر ها (variables) !!!</title><link>https://virgool.ir/@ilbeygi.m/the-golden-rule-of-variable-naming-dcnlzldrdaco</link><description>! توجه کنید که این نوشته یک ترجمه هستش که لینکش رو در پایین میذارم !در ابتدا به تعریف 10 دستور برای نامگذاری متغییر ها می پردازیم :نام متغییر ها خاص باشند !از کلمات غیر ضروری و من در آوردی استفاده نکنید !از اختصارات مبتکرانه ( مبتکرانه از نگاه خودتون ینی، نه کسی که میخواد کد رو بخونه )  استفاده نکنید!برای نام گذاری از کلمات یک زبانی (زبان انسانی) استفاده کنید که افراد تیم با آن آشنا هستند مثلا اگر در تیم همه انگلیسی صحبت می کنن شما از کلمات اسپانیای استفاده نکنید !از کلمات خودساخته استفاده نکنید !!! ( این خیلی مهمه )نوع متغییر رو توی نام متغییر وارد نکنید ( هر چیز جای خودش ) مثلا فرض کنید بگن افشین باریک ( میدونم خیلی بی ربط بود ولی خواستم یه طوری لپ مطلب رو ادا کنم )سعی کنید از کلماتی که واضح و مشخص نیستن استفاده نکنید مگر اینکه طی یک پروتکل برای  تیم مشخص شده باشه که چی به چیه.کلمه ای رو انتخاب کنید که در صحبت بیشتر گفته میشه مثلا در صحبت ترجیح داده میشه بگن Transform تا اینکه بگن GetTransformationاز یک سینتکس استوار استفاده کنیدو قانون اخر می خواد بگه قوانین رو بشکن اگر جایی نیاز بود بشکنی !!!!این دستورات برای نام گذاری کافی به نظر میاد، اما بعد از گذشت مدتی من به این نتیجه رسیدم که به یک روند برای نامگذاری متغییر ها رسیدم، به یک روند یا روش که می تونم ازش برای نامگذاری دقیق هر چیزی استفاده کنم !به روشی که من میدونستم چیه ولی نمیدونم چطور میدونستم !!! ( اینارو دارم از زبون اون بنده خدایی میگم که نوشته ). byte[] ctnt = docClass.Content(dID);بعد از کمی آزمایش و خطا، میشه یه جورایی اسامی نام گذاری کد بالارو به این صورت جایگزین کرد:byte[] content = documentRepository.GetContent(docID);اما اگر یکی ازم سوال کنه که &#39;چرا اسمای متغییر هاتو تغییر دادی به این اسامی خاص&#39; بهترین توضیحی که من میتونم بدم اینه که &#39; زیرا این تنها مواردی هستن که درست به نظر میرسند&#39; که این ناخوشایند و راضی کننده نیست !!!!اما الان، من به این سوال میتونم پاسخ بدم،‌اما نه با 10 قانون بلکه تنها با یک قانون :  &#34; قانونی طلایی نام گذاری متغییر ها &#34; .قانون طلایی :این قانون طلایی چی میتونه باشه ؟ اون میتونه فقط این باشه :اسامی متغییر ها باید در حد امکان یک توصیفی باشند مختصر از چیزی که میخوایم.من صدای شما خوانندگان عزیز را می شنوم که میگید هنوزهم موارد دیگه وجود داره برای نامگذاری،‌که من میگم بله درست میگید ! نامگذاری فقط یک هنر و مهارت هست ، چیزی که ما فقط با تمرین و عدم موفقیت به دست میاریمش. اما این قانوم گرچه مفیده ولی همه  شرایط رو در بر نمیگیره. ( یک خط رو نتونستم درکش کنم برای ترجمه ببخشید !)پس با این وجود این وجود مثال قبلی رو در نظر بگیرید :byte[] ctnt = docClass.Content(dID);با توجه به قانونی که گفته شد ما می تونیم نتیجه گیری کنیم که :نام ctnt مخفف یا مختصر شده اما توصیفی نیست. این یک کلمه نیست تنها مجموعه ای از حروف هست که تفسیرشونم راحت نیست. ما باید این کلمه رو با نامی جایگزین کنیم که دقیقا اون چیزی رو که نشون میده توصیف هم بکنه.نام docClass خیلی عمومی هستش. خب حالا این کلاس چیه ؟ یک سرویسه؟ یک ریپازیتوریه؟ یک مپرره؟ یا چیز دیگه ؟ خب ما هیچکدوم ازینارو نمیتونم بگیم. خب ما باید این نام رو با نامی جایگزین کنیم که به خواننده بگه این کلاس برای چه کاری استفاده شده و چه کاری رو میخواد انجام بده.متد Content هم خوانا هست هم مختصر شده اما به اندازه کافی توصیفی نیست. این متد میخواد چه کاری رو با محتوا انجام بده؟ آیا میخواد اونو بازیانی کنه؟ یا آپدیته کنه؟ یا حذفش کنه؟ بازم هیچکدوم ازینارو نمیتونم به طور قطع برای این نام بگیم. ما باید این نام رو با یک نام فعال تر جایگزین کنیم، چیزی که دقیقا کاری که این متد انجام میده رو بیان کنه.متغییر dID مخفف و مختصر هست و قابل فهم نیست. به احتمال زیاد شناسه سند خاص هستش، نمی توان بدون اینکه وارد کد شد فهمید که برای چه استفاده شده. ما باید این نام رو با یک توصیف بیشتر که قابل فهم تر باشه جایگزین کنیم.بنابراین با استفاده از قانون نامگذاری طلایی، و نکاتی که در بالا ذکر شد،‌می تونیم به یک مثال بهتر برسیم :byte[] content = documentRepository.GetContent(docID);این خیلی بهتر از اون چیزی هست که اول شروع کردیم. حالا مشخصه که این کد داره محتوای ذخیره شده یک سند رو از پایگاه داده بازیابی میکنه.و اما خلاصه موارد بالا :قانون نام گذاری طلایی به ما کمک میکنه که متغییر هامونو طوری نام گذاری کنیم که برای بقیه که میخوان کد رو بخونن راحت تر باشه و بهتر بتونن بفهمن قصد ما چیه و چی رو میخوایم منتقل کنیم. این یک قانون تمام عیار نیست، اما به ما کمک میکنه تا به هدف نوشتن کد نویسی قابل خوندن نزدیک بشیم و کدومون قابل فهم باشه.حالا اگر شما دوستان هم تجربه ها یا قوانین خاص خودتونو دارین که کد هارو تمیز تر و قابل خوانا تر میکنه به اشتراک بذارید.متن بالا ترجمه ای از این لینک می باشد. ( میدونم خوب ترجمه نشده و مشکل داره برای همین ببخشید اگر وقتتونو گرفتم دوستان )موفق و پیروز باشید ...</description><category>محمد ایل بیگی</category><author>محمد ایل بیگی</author><pubDate>Tue, 07 Apr 2020 12:12:28 +0430</pubDate></item><item><title>مهاجرت برای کار به سبک یک برنامه نویس !!!</title><link>https://virgool.ir/@ilbeygi.m/مهاجرت-برای-کار-به-سبک-یک-برنامه-نویس-m1cuzukjhm5p</link><description>مهاجرت های کاری !!!سلام دوستان گرامیامیدوارم که جالتون خوب باشهچندباری دیدم که برخی از دوستان سوال می پرسن که آقا ما شهرستانی هستیم و میخوایم بریم یک شهر بزرگتر ( مثلا تهران یا مشهد یا تبریز یا اصفهان یا ... ) کار کنیم چون برای ما برنامه نویس ها در شهر های کوچیک کار نیست و ....میخوام در این پست اندکی از خوبی ها، سختی ها، تجربیات خودم بگم که برای کار به شهر دیگه ای (مشهد) رفتم تا بتونم در حوزه چیزی که بسیار بهش علاقه مند هستم (برنامه نویسی) کار پیدا کنم و کار کنم.خب بریم سر اصل ماجرا !!!!!ارسال رزومهعرضم به حضورتون که اوایل سال 98 بود ( اریبهشت تقریبا ) که خدمت مقدس سربازی من داشت تموم می شد و باید کم کم دیگ دنبال کار می گشتم !!! در مرخصی پایان دوره ( خدمت رفته ها می دونن پایان دوره ینی چی :) ) بودم که به فکر رفتم که باید کم کم دنبال کار باشم و در سایت های کاریابی و استخدامی مثل جابینجا و ... دنبال کار می گشتم اما هنوز می ترسیدم که رزومه ارسال کنم و ترس اصلیمم این بود که هنوز تکلیف خدمتم صددرصد معلوم نیس ! هر چند که در اون موقع برای یکی دو تا شرکت رزومه ارسال کردم و یکیشون گفت بیا برا مصاحبه ولی استرس خدمت انقد زیاد بود که نشد برم و کنسلش کردم .خلاصه گذشت و اواخر اردیبهشت شد و من دیگ اخرین امضا های ترخیصیمو جمع کردم و رسیدم خونه و اولین کاری که کردم یک نفس عمیق کشیدم تا خستگی خدمت از تنم بره بیرون !!! دومین کاری که کردم شروع کردم به پیدا کردن کار در مشهد  !!!دو روز بعد از اتمام خدمت مقدس سربازی شروع کردم به فرستادن رزومه برای کار هایی که پیدا کردم و ازشون خوشم اومد و از روز بعد شروع کردن به تماس گرفتن برای مصاحبه کردن ( 4 جا تماس گرفتن که برم برا مصاحبه ) .همون شرکت اولی که رفتم شروع کردم به صحبت و بخشی از پروژه شونو گفتن و من یک راه حل پیشنهاد دادم که خوششون اومد و با توجه به اینکه میخواستن من بخش بک اند و طراحی API سرویسشونو انجام بدم همونجا لپ تاپم در آوردم و کدی که برای یکی از API های سیستم های تمیرینیم زده بودم رو نشون دادم و تا کد رو دیدم و معماری رو بررسی کردن خوششون اومد و گفتن ک از همین فردا بیا سرکار !!!راستش من خیلی خوشحال شدم و خدارو شکر کردم که اولین جا خوب دراومد اما دوست داشتم بقیه جاهارو هم برم تا ببینم ایا جای بهتری پیدا می کنم یا نه ! که فرداش رفتم و یک جا دیگم منو می خواستن که خودمم خیلی از سبک کاریشون خوشم میمومد اما چون اصولا آدم پایبندی هستم و دوست ندارم که زیر قولم بزنم با توجه به نیمچه قولی که به شرکت اولی دادم قرار رو بر این گذاشتم که برم پیش همون شرکت برای کار !!!شروع آوارگی :شروع آوارگی !! :(در عین حال که کلی خوشحال بودم که کار پیدا کردم در مقابل ناراحت بودم که خب حالا از فردا برم کجا  و شب کجا بخوابمو ... !!!!!اول توافقمون با شرکت بر این باب شد که یک ماهی به صورت آزمایشی برم و کار کنم و بعد اگر از کارم راضی بودن دیگ قرارداد طولانی مدت ببندم، منم برا همین با خودم گفتم خب اول این یک ماهو میرم خونه اقوام و اینور و اونور و اخر هفته ها میرم شهرستان تا اگه بعد از یک ماه اوکی شد و همه چی بر وفق مراد بود برم دنبال خونه بگردم و خونه بگیرم و ... .خلاصه یک ماهی رو به فلاکت آوارگی کشیدم و هر شب خونه یکی و ... به طوری که اواخر دیگ یک حس سرباری حس میکردم :| ... !خلاصه که سرتونو درد نیارم که یک ماه شد و گفتیم خب دیگ بریم دنبال خونه !!! حالا که رفتیم دنبال خونه میبینم ای بابا با پولی که من دارم خونه نمیشه گرفت :(‌و باز هم آش و کاسه ما شد آوارگی و ازین خونه به اون خونه رفتن !تنها شانسی که آوردم این بود که یکی از رفیقام دوستش مشهد خونه داشت و یک ماه اخر رو میرفتم پیش اون ، اما داستان اونجایی جالب شد که اواسط تابستون ( یک ماهی بعد از رفتن به خونه اونا ) بنده خدا گفت من باید خونه رو تحویل بدم و میخوام برم شهرستان !!! گفتنش همانا و آب سرد ریختن روی ماهم همانا !!!روز تحویل رسید و رفتم وسایلامو برداشتم و شبش رفتم خونه یکی از اقوام و فرداش ک از شرکت اومدم بیرون رفتم میدون شهدا ( مشهدی ها میدونن کجاست ) نشستم و داشتم به سمت حرم نگاه میکردم !!!خیلی صحنه عجیبی بود، حس این که دیگ جایی نداری !!! بعضی وقتا انقدر فشار بهم میومد که میگفتم محمد بیا و بیخیال شو برو همون شهر خودت کارگری بکن ولی این آوارگی رو نکش !باز از ی طرف دیگ میگفتم بری میشی سرباز شکست خورده و .... .خلاصه وایستادم و اون شب کوشی رو برداشتم و به یک شماره که چند وقت پیش گیراورده بودمش ( شماره مالک یک پانسیون بود ) تماس گرفتم که برم و یکی از اتاق هاش رو اجاره کنم ( من به خاطر خلقیاتی که دارم دوست داشتم تنها خونه بگیرم تا برم پانسیون ولی دیگ مجبور شدم و ... )خلاصه رفتیم پانسیون، با همه سختی هایی که برام داشت و نمیتونستم باهاش خوب کنار بیام ولی همین که فکر میکردم دیگه سربار کسی نیستم یک حس خیلی خوبی بهم میداد که میگفتم کاش از روز اول سختی پانسیون رو تحمل میکردم ولی سربار کسی نمیشدم.یک نتیجه گیری دوستانه :من توصیم به دوستان اینه که برای علاقه ای که دارید و در محل زندگی شما نیست برای به دست آوردنش، سفر کنید، حتی اگر سختی بکشید.من ازین سفرم فهمیدم به دست آوردن خوشی با خوشی نمیشه،‌باید سختی بکشی تا بتونی به چیزی که باهاش به آرامش میرسی برسی.من با برنامه نویسی آرامش پیدا میکردم و برای پیدا کردن این آرامش پی خیلی از سختی هارو به خودم مالیدم و وارد شهری جدید با کلی چالش جدید شدم.اما اگ سفر کردید سعی کنید اگ اخلاقتون مثل منه و زود حس سرباری بهتون دست میده از همون اول یک پانسیون دانشجویی یا کارمندی پیدا کنید و با دادن مبلغ کمتری نسبت به اجاره خونه با خیال راحت تری به کارتون برسید. همچنین اینایی که گفتم فقط تجربیاتی از سختی نحوه زندگی بود و وارد صحنه های و دوشواری های کاری و فنی نشدم دیگه.امیدوارم وقتی که برای خوندن این مطلب گذاشتین رو الکی هدر نکرده باشم.و من الله توفیق.</description><category>محمد ایل بیگی</category><author>محمد ایل بیگی</author><pubDate>Mon, 16 Sep 2019 22:41:24 +0430</pubDate></item><item><title>پکیچ گروه بندی و دسترسی دادن به کاربران لاراول - userpermission</title><link>https://virgool.ir/laravel-community/grouping-and-accessing-users-in-laravel-userpermission-otcikssypq5x</link><description>  سلام به همه اساتید و دوستان گرامیبنده مدتی پیش که شاید به دو سال پیش بر میگرده، در حال انجام یک پروژه لاراول بودم که نیاز شد در داخل این پروژه از سطح بندی کاربران ( گروه بندی ) و همچنین مجوز دادن دسترسی به کاربران و ... استفاده کنم ینی چیزی مثل همین پکیچ های role بندی و .... .برا همین گفتم بیام یکم ازین پکیچا بخونم که کارمو راه بندازه ، یکم خوندم دیدم چیزی حالیم نمیشه K ( البته مشکل از نحوه خوندنم بود که خیلی هول هولکی می خوندم و دقت نداشتم ) بنابراین تصمیم گرفتم خودم یه چیز بزنم و اون موقع کاری که به ذهنم رسید کار با route ها در لاراول بود، ینی گفتم بیام یک سیستمی بزنم رو این برنامه که کاربرا وقتی خواستن یک route رو ببینن اول چک بشه که ایا دسترسی دیدن این route یا کار بر روی این route به این کاربر از قبل داده شده یا نه ؟ به عبارتی چک کنه ایا این گروه کاربری قادر به چک کردن این route هست و اجازه شو داره یا نه !!!خلاصه بعد از این حرفا گفتم بیام یک پکیچ بزنم بعد از پکیچم توی برنامه خودم استفاده کنم و اومدم پکیچی تحت عنوان userpermission نوشتم و توی گیت هاب در آدرس (اینجا) قرار دادمش !!! اما متاسفانه به علت ننوشتن یک داکیومنت خوب خیلی ازش استقبال نشد و کسی نفهمیدش !!! و الان بعد از این مدت تصمیم گرفتم بیام و کمی در موردش صحبت کنم تا ایرادات محتملی هم که داره بر طرف کنم.قبل از هر چیز نکته ای مهم بگم که این پکیچ رو باید وقتی به پروژه اضافه کنید که دیگه کار تمام هست و فقط گروه بندی کاربران مانده !!!پکیچ userpermission چیست ؟این پکیچ یه قالب کاری کامل هست و صرفا استفاده از کد نیست یعنی با نصب این پکیچ لازم نیست شما کدنویسی خاصی انجام بدین ( کار های کدنویسی که باید انجام بدین که خیلی کوچیک هم هست رو در اخر همین مقاله توضیح دادم ) چرا که برای پکیچ یک رابط گرافیکی ( پنل کاربری ) تعبیه شده که می توانید کار ساخت گروه کاربری و دسترسی دادن به هر گروه کاربری رو از طریق این پنل انجام بدین.نحوه کار پکیچ userpermission چطور است؟به طور کلی نحوه کار به این صورت است که ابتدا کل route ها دریافت میشه و در دیتابیس ثبت میشه ، توجه شود که route هایی ثبت می شوند که متد name برایشان تعریف شده باشه مثل : Route::get(&#39;/home&#39;, &#39;HomeController@index&#39;)-&gt;name(&#39;home&#39;);چرا که در این پکیچ route ها با خاصیت name چک می شوند.بعد از گرفتن تمامی route ها خوده پکیچ به طور خودکار یک سطح دسترسی ( گروه کاربری ) به اسم superadmin می سازه و تمام دسترسی ها رو به این گروه کاربری میده ( وکالت تام الاختیار).نحوه نصب پکیچ userpermission نحوه نصب پکیچ در مخزن گیت هاب مجوز کاربر موجود هست ( به آدرس https://github.com/ilbeygi/userpermission/ ) ولی اینجا هم میگم. ( تنها داکیومنتی که برای پکیچ در گیت هاب نوشتم همین روش نصب هستش که از تنبلی خودم بود. )در گام اول برای نصب ابتدا وارد مسیر پروژه لاراول بشید و ترمینال رو باز کنید و دستور زیر را بزنید :composer require &#34;ilbeygi/userpermission&#34;:&#34;dev-master&#34;گام دوم : بایستی provider مربوط به پکیچ رو در مسیر config/app.php اضافه کنید :&#39;providers&#39; =&gt; [  ...  Ilbeygi\UserPermission\userPermissionServiceProvider::class, // &lt;-- add this line at the end of provider array],گام سوم : فایل های پکیچ رو باید پابلیش کنید که برای این کار در ترمینال دستور زیر رو وارد کنید :php artisan vendor:publish --tag=userPermissionPackage_ilbeygi_irبا این کار فایل های balde و فایل های جداول دیتابیس در محل مورد نظر در پروژه قرار میگیرن.گام چهارم : در این مرحله بایستی که جداول مربوط را با دستور migrate در دیتابیس بسازید :php artisan migrateگام پنجم : در این پکیچ برای مدیریت route ها یک middleware ساختیم که باید به تنظیمات کرنلتون اضافش کنید ، برای این کار وارد فایل app/Http/Kernel.php بشید این کار را انجام دهید ( نام middleware در نظر گرفته شده checkRoles هست ) :protected $routeMiddleware = [....&#39;checkRoles&#39; =&gt; \Ilbeygi\UserPermission\Middlewares\CheckRole::class, // &lt;-- add this line at the end of $routeMiddleware];گام ششم : در این مرحله پروژه لاراول خود را ران کنید :php artisan serveگام هفتم : همونطور که قبلا گفتم این پکیچ کل route های پروژه شمارو میگیره و برای این کار باید پروژه خودتون رو باز کنید و به اخر ادرس پروژه این (saveAllRouteNameInDatabase) عبارت رو اضافه کنید ( مثال : http://localhost:8000/saveAllRouteNameInDatabase )توجه شود که این کار بایستی صددرصد انجام شود چرا که با این کار روت ها و تنظیمات مربوط به پکیچ انجام میشه.http://{your_laravel_address}/saveAllRouteNameInDatabaseگام هشتم : بعد از انجام گام هفتم و دریافت پیغام موفقیت آمیز محتویات روت saveAllRouteNameInDatabase رو پاک کنید تا بعد براتون مشکل ساز نشه و کاربرا شیطنت نکنن و برای این کار به آدرس vendor/ilbeygi/userpermission/src/route.php برید و روت /saveAllRouteNameInDatabase  رو پاک کنید :Route::get(&#39;/saveAllRouteNameInDatabase&#39;, function (){......});گام نهم : در آخرین گام میتونید با وارد کردن آدرس /panel/permissions به پنل مدیریت پکیچ وارد بشید و گروه کاربری بسازید یا روت اضافه کنید و .... . ( مثال : http://localhost:8000/panel/permissions )http://{your_laravel_address}/panel/permissionsگام دهم : برای استفاده بهتر از پکیچ بایستی middleware اضافه شده در گام پنجم رو به کل route  هاتون اضافه کنید .Route::middleware([&#39;web&#39;, &#39;auth&#39;, &#39;checkRoles&#39;])-&gt;prefix(&#39;panel&#39;)-&gt;group(function (){//Write all of your routes}خب تا اینجا پکیچ رو فهمیدیم چیه و نصب کردیم ، حالا یک بحث کوچیک در مورد نحوه کار با پنل هم بگم که دوستانی که قصد استفاده از این پکیچ رو داشتن راحت باشن.نحوه کار با پنل پکیچ :بعد از نصب پکیچ به مسیر پنل با ادرس : (http://localhost:8000/panel/permissions) بروید که بعد از ورود با پنل روبرو میشید :عکس 1افزودن گروه کاربر :جهت افزودن گروه کاربری جدید به سیستم بایستی روی دکمه (create a new user group) در عکس بالا کلیک کنید که بعد از کلیک این فرم برای شما باز میشه : عکس 2در اینجا خیلی راحت اسم گروه کابریتونو مینویسید و ثبت میکنید .افزودن مسیر های جدید به سیستم :برای این کار روی دکمه add new route کلیک میکنید تا فرم زیر باز شه :عکس 3در فیلد اول new path name ، name مربوط به route مورد نظر رو مینویسید و در فیلد دوم یک تعریف از آن route .اضافه کردن دسترسی به گروه کاربری :برای این کار در جدول عکس شماره 1 که گروه های کاربری رو نشون میده از قسمت action روی دکمه add permission کلیک میکنید تا وارد دسترسی ها یا مجوز های اون گروه کاربری بشید.عکس 4افزودن دسترسی به گروه کاربری : بعد از انجام مرحله قبل شما کل مجوز های گروه کاربری انتخاب شده رو میبیند، همچنین شما در عکس 4 شما یک دکمه میبینید با عبارتadd permission  که برای اضافه کردن مجوز به اون گروه کاربری استفاده میشه که بعد از کلیک روی اون ایم فرم رو میبیند : عکس 5در اینجا دسترسی های مورد نظری رو که میخواین به گروه کاربری انتخاب شده بدین رو انتخاب می کنید و روی دکمه register permission کلیک میکنید !!!و اما چند نکته مهم :نکته یک : قبل از هر چیز نکته ای مهم بگم که این پکیچ رو باید وقتی به پروژه اضافه کنید که دیگه کار تمام هست و فقط گروه بندی کاربران مانده !!!نکته دو : این پکیچ نیاز به کد نویسی نداره به جز یک بخش کوچیک ، وقتی پروژه رو اضافه کردین و این کارهارو انجام دادین شما باید یک کد کوچیک موقع ثبت کاربر به کداتون اضافه کنید و اونم اینه : در بین جداول مربوط به این پکیچ جدولی داریم به اسم  user_role که ایدی کاربر و ایدی گروه کاربری رو ذخیره میکنه و منظورش اینه که مثلا کاربر شماره یک گروه کاربری شماره یک رو داره.برای همین موقع ثبت کاربر باید یک کد بزنید که ایدی اون کاربر با گروه کاربری مربوط به اون کاربر توی این جدول ذخیره بشه.به همین سادگی و خوشمزگیو تمامامیدوارم که این پکیچ به دردتون بخوره و همچنین اگه مشکلی یا ارور یا باگی داشت ممنون میشم راهنمایی کنید تا با هم یک پکیچ خوب و کامل بسازیم.ممنون میشم نکته نظراتتون رو برام کامنت کنید ...سپاس فراوان</description><category>محمد ایل بیگی</category><author>محمد ایل بیگی</author><pubDate>Sun, 31 Mar 2019 12:51:38 +0430</pubDate></item><item><title>تجربیات یک برنامه نویس سرباز !!!</title><link>https://virgool.ir/fboard/the-experiences-of-a-soldier-programmer-glwpcj2mzxzk</link><description>سلام و عرض ادب به شما خواننده عزیزمهر ماه 1396 بود که به یکی از شعبه های پلیس +10 رفتم تا کارای اعزام به سربازی رو انجام بدم و خودم رو وارد یکی از مراحل جدید زندگی کنم که برای هر پسری همچون یک غول یاد میشه و حتی بیشتر از یک غول ازش میترسه !!! مخصوصا اگه اون پسر مدرک دانشگاهی داشته باشه + اندکی تجربه که بدونه با نخوندن، هنرش تا حد زیادی از یادش میره !!!اولش که رفتیم آموزشی همه چی برام گنگ بود و فک میکردم دیگ 24 ساعته برنامه داریم و هیچ وقت استراحتی نداریم، تا این که تقسیم شدیم و رفتیم سر یگان ها آموزشیمون، وقتی سر یگان های آموزشی رسیدیم و با وضعیت برنامه ها آشنا شدیم دیدیم که آره واقعا وقت نداریم که بخوایم مطالعه ای چیزی بکنیم :D  !!! خلاصه که این وضع ادامه داشت تا روزای آخر آموزشی که کم کم داشت به وقت های استراحتمون اضافه میشد و یه جورایی وقت برای مطالعه پیدا میشد و تو نستم تقریبا یک سوم یک کتابی رو بخونم !!!بعد از آموزشی تقسیم شدیم و من از قضا و لطف خدا شهر خودم افتادم و از خوشحالی هم درون پوست خودم نمیگنجیدم چون می گفتم خوبه دیگه شبا که برم خونه میشینم برنامه نویسی و ... میخونم تا هم یادم نره همم اگه بشه چیزای جدید تر بخونم !!! اینطور بگم که رفتم شهر خودم و اوضاع تا جایی که شبا میرفتم خونه خوب بود ولی ار فرط خستگی و مشغله ها ذهنی نمی شد بشینم و درست حسابی برنامه نویسی رو بخونم یا کار کنم و .... . دیدم اینطور نمیشه و تصمیم گرفتم که کم کم هر طور شده خودم رو توی چالش قرار بدم که بشه به زورم که شده کار کنم، برای همین رفتم و یه کاری برداشتم برای یک شرکتی که براشون انجام بدم و همون باعث شد شبا که میام خونه به خاطر تعهد کاری هم که شده بشینم پای سیستم و برنامه نویسی کنم و اینجا اولین چیزی که از سربازی یاد گرفتم این بود که اگر وقتی حوصله انجام کاری نبود، خودمون رو در عمل انجام شده قرار بدیم تا بتونم انجامش بدیم و لذت ببریم !!! شمارو نمی دونم ولی من اینطورم که اول که میخوام یک کاری رو شروع کنم خیلی برام سخته حتی اگر کار مورد علاقم باشه چون تا حدودی تنبلم ولی وقتی خودم رو وارد عمل انجام شده گذاشتم و انجامش دادم ، هر لحظه داشتم از کار لذت میبردم و دوست داشتم بیشتر کار کنم و همیشه منتظر بودم وقت خالی تو پادگان پیدا کنم که مرخصی بگیرم و بیام و بشینم پای کار !!!!درس اولم از سربازی این بود که اگر به خاطر هر دلیلی ( چه خستگی، چه بی حوصله گی، چه .... ) حس و حال انجام کار نبود باید خودمون رو در عمل انجام شده مثبت بذاریم که بتونم انجامش بدیم و مثبت رو به این جهت استفاده کردم که کاری باشه که علاقه داریم چون اگه به در عمل انجام شده گذاشتن خودمون علاقه نداشته باشیم دیگه نمیتونیم ازین روش به خوبی دفعات اول استفاده کنیم !!!!و اما درس دومم از سربازی ( که در واقع درس اولم بود و باید بالا می گفتم ولی به علت خراب نشدن داستان گفتم اینجا بگم :D ) ، درس دومم که اولین درسم بود این بود که فهمیدم واقعا وقت طلاس !!!! شاید تا قبل سربازی فک می کردم وقت ارزشی نداره و وقت زیاده و .... ولی به محض ورودم به سربازی دیدم که وقت طلاس و خیلی ارزش داره ، یعنی منی که در حالت عادی در شخصی گری قبل از سربازی خیلی رقبتی به مطالعه نداشتم در اوایل سربازی به حدی از عرفان رسیدم که دوست داشتم فقط یک دقیقه وقت بیکار باشه و که بشه مطالعه کنم و به شدت علاقه مند شده بودم به مطالعه ، ینی اینطور بگم که برای یک دقیقه وقت خالی له له میزدم !!!! و همین خیلی خوب شد برام که بتونم بعد از سربازی هم از وقتمت به نحو احسن استفاده کنم .این بود بخش کوچکی از تجربیات سربازی ما تا حالا !!!اگه دوستان رغبت نشون بدن ادامه شم می نویسم !!! ینی ادامش منوط به ری اکشن دوستانه !!! تا سلامی دیگر بدرود</description><category>محمد ایل بیگی</category><author>محمد ایل بیگی</author><pubDate>Fri, 29 Mar 2019 12:03:48 +0430</pubDate></item></channel></rss>