<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های سجاد رحیمی</title>
        <link>https://virgool.io/feed/@sajjadrahimi</link>
        <description>Frontend Web Developer</description>
        <language>fa</language>
        <pubDate>2026-06-10 14:06:35</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/1113318/avatar/iNrS3o.jpg?height=120&amp;width=120</url>
            <title>سجاد رحیمی</title>
            <link>https://virgool.io/@sajjadrahimi</link>
        </image>

                    <item>
                <title>الگوی طراحی Template Method</title>
                <link>https://virgool.io/@sajjadrahimi/%D8%A7%D9%84%DA%AF%D9%88%DB%8C-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-template-method-lx3kincoc82x</link>
                <description>خب قبلا چند مورد از الگوهای طراحی رو بررسی کرده بودیم و حالا وقت اینه که ادامه بدیم و چنتا دیگه ازونا رو باهم بررسی کنیم. ایندفعه نوبت الگوی  Template method رسیده.طرح مسألهقبل از پرداختن به این الگو، بیاید مسأله رو بررسی کنیم. فرض کنید ما میخوایم یه سرویسی برای middleware توی سیستم داشته باشیم. توی این سرویس اجرا شدن middleware ها یه الگوریتم خاصی داره و از stepهای مشخصی تشکیل شده. حالا ما مثلا میخوایم به subModuleها اجازه بدیم یه step ازین الگوریتم رو اونطوری که خودشون میخوان پیاده‌سازی بکنن. چرا همچین کاری میکنیم؟ چون ممکنه ماژول‌های متفاوتی با middlewareهای متفاوت داشته باشیم. یا مثلا یکسری از routeهای ما middleware خاص خودشون رو داشته باشن.خب راه اول اینه که برای هر ماژول بیایم middleware رو طبق الگوریتمی که درنظر گرفتیم پیاده‌سازی کنیم و فقط step مربوط به خودش رو customize کنیم.ولی این کار خیلی غلطه. چون به شدت duplicate code رو زیاد میکنه. از طرفی دیگه ممکنه پس‌فردا یکی دیگه بیاید و یه middleware جدید با یه ساختار دیگه تعریف کنه که ما اینو دوست نداریم. خب چاره چیه؟ استفاده از template methodکاری که میکنیم اینه که یه کلاس middleware تعریف میکنیم و همونطور که از اسم این الگو مشخصه، یک template method داخل این کلاس تعریف میکنیم.توی این متد، stepهای الگوریتمی که برای middleware درنظر گرفتیم رو مشخص میکنیم. اینجا من میخوام فقط اجازه بدم که step سوم یعنی متد doExecuteMiddleware رو خود subModuleها اونطوری که خودشون میخوان پیاده کنن. بنابراین این متد رو abstract تعریف میکنم و subModuleهارو مجبور میکنم که اون رو پیاده‌سازی بکنن. بنابراین خود کلاس هم باید abstract باشه و این به این معنیه که ما از خود این کلاس نمیتونیم instance بسازیم. شاید هنوز یکم گنگ باشه صبر کنید بریم جلوتر و یه نگاهی به subModuleها بندازیم.خب میبینیم که subModuleهای Middleware1 و Middleware2 از superClass ما ارث‌بری کردن و متد doExecuteMiddleware رو به دلخواه پیاده‌سازی کردن. اگر دقت کنید میبینید که Middleware2 اومده متد  fetchSomeData رو هم override کرده. این رو هم خودمون اجازه دادیم. ما این متد رو توی superClass به صورت protected تعریف کردیم و به subModuleها گفتیم که ما توی step دوم این متد رو صدا میزنیم و یه پیاده‌سازی پیش‌فرض هم خودمون براش داریم. حالا شما اگر خواستید این پیاده‌سازی رو میتونید override کنید و تغییر بدید. در مقابل، step اول الگوریتم ما که initMiddleware باشه بصورت private تعریف شده و هیچ کس نمیتونه تغییرش بده. با استفاده از این الگو و متدهایی که تعریف کردیم، این اطمینان به دست میاد که هم همه‌ی subModuleها، middlewareی که خودشون میخوان رو پیاده‌سازی میکنن، هم کسی ساختار الگوریتمی که ما برای middlewareها تعریف کردیم رو به هم نمیزنه. زیباست نه؟ :)حالا بریم سمت client ببینیم چه خبره.اینجا دیگه دستمون بازه. هم میتونیم یک middleware خاص رو اجرا کنیم و هم اینکه تمام subModuleها رو جمع کنیم و همشون رو instantiate کنیم. دقت کنید اون instanceی که client میسازه، فقط به متد executeMiddleware که همون template method ما باشه دسترسی داره و درستشم همینه. client نباید به ریز متدها و stepهای مختلف الگوریتم ما دسترسی داشته باشه چون این متدها concernش نیستند. بخاطر همین به غیر از متد executeMiddleware، بقیه متدها private و protected هستن.رابطه Template Method و SOLIDکاری که که ما توی این این الگو انجام دادیم، در حقیقت یکی از اصول SOLID هست. Open to Extension But Closed to Modification. این اصل بیان میکنه که entityهای سیستم شما مثل کلاس‌ها و ماژول‌ها باید اجازه بدن که رفتارشون extend بشه اما اجازه ندن تغییر بکنه. یعنی چی؟ توی همین مثال خودمون، ما اومدیم توی کلاس Middleware با تعریف template method، درواقع یک Extension Point معرفی کردیم و گفتیم که آقا شماها میتونید با extend کردن این کلاس، قسمتی از رفتارش رو اونطوری که خودتون میخواید پیاده‌سازی کنید. از یک طرف template method ما و مراحل الگوریتم ما همیشه ثابته و قسمت‌هایی از اون هم به هیچ عنوان overrdiable نیست، بنابراین در عین حالی که جلوی تغییر دادن کلاس Middleware رو گرفتیم، اومدیم به بقیه اجازه دادیم که اون رو extend کنن و اون رفتاری که خودشون میخوان رو توی الگوریتم ما و در اون stepی که ما مشخص کردیم قرار بدن. توجه کنید که template method یک الگوی behavioral یا رفتاری هستش.اگر فیدبک، انتقاد، پیشنهاد یا هرچیز دیگه ای مدنظرتون هست خیلی ممنون میشم ازتون که برام کامنت کنین یا بهم پیام بدینLinkedIn: https://www.linkedin.com/in/sajjad-rahimi-890851231/Telegram: @sajjrhm</description>
                <category>سجاد رحیمی</category>
                <author>سجاد رحیمی</author>
                <pubDate>Fri, 12 Aug 2022 16:55:18 +0430</pubDate>
            </item>
                    <item>
                <title>استفاده از Type Predicates در Typescript</title>
                <link>https://virgool.io/@sajjadrahimi/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-type-predicates-%D8%AF%D8%B1-typescript-nt2mmardq9xf</link>
                <description>قبل از توضیح Type Predicate، بذارید بگم که TS چجوری کار میکنه. بریم از زبون خود TS بشنویم :)« اگر type متغیرهاتون رو برای من(TS) مشخص کنین، من خودم در ادامه براتون type check انجام میدم و موقع assign کردن‌ها و ازین قبیل موارد، میتونم type هارو تشخیص بدم. اما شما اگر خودتون بخواهید وارد عمل شید و یجاهایی خودتون بصورت custom توی برنامه type ها رو تغییر بدید یا اصطلاحا type cast انجام بدید، من به شما به عنوان یه developer اعتماد میکنم و typeی که شما تعیین میکنید اولویت داره برای من »خب داستان چیه که TS انقد داره حال میده بهمون ؟ یعنی چی؟ این مثال رو ببینیداینجا اومدیم یک مقدار از جنس number رو ریختیم توی یه متغیر از جنس string که خب طبیعتا هم TS بهمون گیر میده.د ولی اگه type cast انجام بدیم و بهش بگیم که این مقدار 20 که داریم بهت assign میکنیم درواقع string هست، TS میگه اوکی و حرف ما براش سند هستش.همونطور که میبینین، با type cast ی که انجام دادیم، TS قبول کرد که مقدار ۲۰ از نوع string هستش و متدهای string رو میتونیم روش صدا بزنیم.(فقط توجه کنید که اینجا اول باید typeمون رو به unknown و بعد به string تبدیل میکردیم. چون اگه مستقیما میخواستیم type cast رو از number به string انجام بدیم، TS اجازه نمیداد و میگفت این دوتا type با هم دیگه همپوشانی ندارن یا اصطلاحا همدیگه رو overlap نمیکنن ک بخوای castشون کنی).مثالی که زدم فقط برای توضیح عملکرد TS بود و خب شما قاعدتا نباید این کارو بکنید چون توی runtime به ارور میخورید.حالا ازین قضیه میخوایم توی بحث type predicates استفاده کنیم. ممکنه با عنوان type guard هم بهش اشاره بشه. درواقع type predicate یکی از فیچرای مبحث narrowing توی TS هست که پیشنهاد میکنم در موردش یه سرچ بزنید.اول این ‌interface هایی که تعریف کردم رو درنظر بگیرید.توضیح لازم نداره ، فقط اومدم دوتا interface تعریف کردم که از Animal ارث بری میکنن و ارتیبیوت خاص خودشون رو دارن. حالا مثلا من میخوام یجایی چک کنم که آبجکتی که دارم باش کار میکنم از نوع Bird هست یا نه و اگر هست متد fly رو صدا بزنم روش. من فقط میدونم که آبجکتم از قطعا از نوع Animal هست یعنی interfaceی که برای Animal تعریف کردم رو ارضا میکنه. خب میام خیلی راحت وجود اتریبیوت fly رو چک میکنم.عه؟! ارور داد که. خب معلومه دیگه بهت اجازه نمیده که روی یک آبجکت از نوع Animal این متد رو صدا بزنی. از طرفی من اگه مطمئن بودم که آبجکت من از نوع Bird هست که دیگه اصلا چک نمیکردم. راه حل چیه؟ type predicatesمیام با استفاده از type casting یه فانکشن isBird تعریف میکنم که خروجی اون یک مقدار boolean هست.خب میبینیم که بهمون اجازه داد که متد fly رو صدا بزنیم. یعنی TS فهمید که در این صورت حتما اتریبیوت fly روی اون آبجکت وجود داره. Animal is Bird درواقع یعنی خروجی تابع ما بیان میکنه که این آبجکت از نوع Bird هست یا خیر که در واقع boolean ه. حالا این فقط یه مثال بود. خیلی جاها ما أصلا نمیدونیم type آبجکتمون چی هستش. جدا ازون این کد مشکل maintainability هم داره یعنی پس فردا اگه اتریبیوت fly عوض شد باید بیایم function رو تغییر بدیم. پس میایم یه function کلی تر و بهتر مینویسیم.خب خیلی خوب شد. fullFillsType درواقع یک type parameter میگیره به همراه parameter های obj و attr که به ما میگه که اگر این obj از نوع T باشه، آیا اتریبیوتِ  attr رو داخل خودش داره یا نه. توجه کنید که attr باید از بین key های T انتخاب بشه. حالا هرجا خواستیم ببینیم که یک آبجکت یک type رو روی یک اتریبیوت خاص ارضا میکنه یا نه میتونیم از این function استفاده کنیم. بخاطر اینکه attr رو از بین key های T انتخاب کردیم، اگر این کد رو داخل ادیتورتون بزنید ، میبینید که موقع که میخاید function رو صدا بزنید و متغیر دوم رو بهش پاس بدید، TS خودش لیست مقادیر key های typeتون رو بهتون نشون میده.فیچرهای TS رو دست کم نگیرید. پیشنهاد میکنم داکیومنت TS رو خط به خط بخونید و باهاش پیش برید. فیچرها به شدت کاربردی‌ان و اطلاع نداشتن از اونا ممکنه توی روند توسعه سرعتتون رو کم بکنه و پیچیدگی کدتون زیاد بشه.اگر فیدبک، انتقاد، پیشنهاد یا هرچیز دیگه ای مدنظرتون هست خیلی ممنون میشم ازتون که برام کامنت کنین یا بهم پیام بدینLinkedIn: https://www.linkedin.com/in/sajjad-rahimi-890851231/Telegram: @sajjrhm</description>
                <category>سجاد رحیمی</category>
                <author>سجاد رحیمی</author>
                <pubDate>Sat, 06 Aug 2022 00:40:30 +0430</pubDate>
            </item>
                    <item>
                <title>استفاده از Mapped Type ها در Typescript</title>
                <link>https://virgool.io/@sajjadrahimi/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-mapped-type-%D9%87%D8%A7-%D8%AF%D8%B1-typescript-esw1cchptrz0</link>
                <description>خب توی این پست میخوایم در مورد Mapped Type ها در TS صحبت کنیم که به نظرم فیچر باحالیه و خیلی جاها میتونه کمک کنه که از تکرار کدها جلوگیری و درواقع DRY رو رعایت کنیم.در حقیقت Mapped Type ها یک نوع Generic Type هستند که روی key های یک type دیگه iterate میکنن و برای ما یک type جدید تولید میکنن. شاید یکم گیج‌کننده بنظر برسه ولی اصلا اینطور نیست. بذارید با یه مثال ساده شروع کنیم.فرض کنید ما یک type به اسم Settings داریم که شامل دو تابع برای حالت شب و نمایش پروفایل کاربر هستش.حالا برای مثال، من میخوام یکtype دیگه درست کنم که شامل تمام پراپرتی‌هایSettings باشه، منتها نه به شکل تابع، بلکه به شکل اتریبیوت‌های ساده از نوع boolean. برای اینکار از Mapped Type استفاده می‌کنیم. اول یک type مینویسم به اسم Options.همونطور که میبینید اینجا یک type argument به اسم T داریم. با استفاده از keyof در واقعkeyهای T رو پیمایش کردیم و برای هر کدوم نوع boolean رو درنظر گرفتیم. حالا بذارید به جای T ، اونtypeی که خودمون نوشتیم یعنی Settings رو پاس بدیم و ببینیم چی میشه.با استفاده از اینtype (یعنی Options) کاری که کردیم که type نهایی حاصل شده یعنیSettingOptions مشابه Settings هست با این تفاوت که اتریبیوت هاش از نوع boolean هستن.به طور کلی Mapped Type ها کارشون همینه. معمولا اینطوریه که ما یکGeneric Type مینویسیم و داخل اون با استفادهkeyof، اتریبیوت های یک type رو iterate میکنیم و از آونها تایپ و اتریبیوت‌های مورد نظرمون رو ایجاد میکنیم. حالا اینجا وقتی ازMapped Type ها استفاده میکنیم، موقع ایجاد type جدید از یه‌سری فیچرهایی برخورداریم که بنظرم خیلی باحاله و خدا میدونه چقد میتونه به کارمون بیاد. بریم چنتاشونو ببینیم.حذف یا اضافه کردن Modifier هااینجا منظور از Modifier ها فقط readonly و ? (به معنی optional) هستن. موقع استفاده ازMapped Type ها میتونیم readonly یا optional بودن اتریبیوت‌ها رو حذف کنیم یا مثلا تمام اتریبیوت های type جدید رو optional کنیم. چجوری !؟؟ با استفاده از پیشوندهای + و –این مثال رو ببین. اینجا با اضافه کردن readonly+ ، تعیین کردیم که type جدید همه ی اتریبیوت‌هاش باید readonly باشن و کسی نمیتونه تغییرشون بده. type اونهارو هم تغییر ندادیم و گذاشتیم مثل قبل بمونه.  T[key] در واقع type هر کدوم از اتریبیوت های T را به ما میده. توجه کنید که key داینامیکه و داریم روی تمام اتریبیوت ها type موردنظرمون iterate می زنیم.یا مثلا توی این قطعه کد پایین ما اومدیم و با اضافه کردن ?- ، به TS گفتیم که نمیخوایم هیچکدوم از اتریبیوت‌های type جدیدمون optional باشن.استفاده از Key Remappingیعنی چی؟ یعنی اونجایی که داریkey های یک type روiterate میکنی، میتونی یک سری اعمال روشون انجام بدی و یا یکسری هاشون را با یکسری شرایطی حذف کنی یا مثلا اسمشون رو تغییر بدی. توی TS ورژن 4.1 به بعد با استفاده از کلمه کلیدی as میتونی اینکارو انجام بدی. اینجارو ببین چه کار باحالی انجام دادیم:)اینجا با استفاده از ۲فیچر literal template types و key remapping اومدیم و key های Person (قبل از کلمه کلیدی as) روremap کردیم به اون چیزی که خواستیم (بعد از کلمه کلیدیas) و تبدیلشون کردیم به متد. اینم بگم که &lt;Capitalize&lt;string &amp; key درواقع حرف اول key ها رو بزرگ میکنه و جزو Generic Type های تعریف شده‌ی خود TS هستنش. یه مثال دیگه اگه بخوام ازkey remapping بزنم اینه که ما میتونیم یکسری key هارو فیلتر کنیم.اینجا هم روی key های Shape رو پیمایش کردیم و گفتیم میخوایم type جدیدمون همه ی اتریبیوت‌های Shape رو داشته باشه به غیر ازkind و خیلی راحت تونستیم با استفاده ازExclude (که باز برای TS تعریف شدس) اینکارو انجام بدیم.استفاده از Conditional Typesما میتونیم در Mapped Type ‌ ها از Conditional Type ها هم استفاده کنیم و type های جدید رو با شرط های مختلف چک کنیم و درواقع conditionally تولیدشون کنیم. مثال پایین رو نگاه کنین. اینجا اومدیم برای هر اتربیوت ازObjects چک کردیم که آیا اون اتریبیوت ازShape ارث بری میکنه یا نه.ارث بری کردن از Shape به این معنی هست که اون typeی که داره ارث بری میکنه، حتما اتریبیوت kind رو داشته باشه و مقدارشم یکی از مقادیر ‘square’ ، ‘circle’ و یا‘rectangle’ باشه.بنظرم فیچرهای TS مبحث جذابیه و تسلط به اونها باعث میشه پروژه رو خیلی حرفه‌ای تر دولوپ کنیم. بخاطر همین خوبه که بهشون بپردازیم و سعی میکنم بازم در مورد کاربردهاش بنویسم.اگر فیدبک، انتقاد، پیشنهاد یا هرچیز دیگه ای مدنظرتون هست خیلی ممنون میشم ازتون که برام کامنت کنین یا بهم پیام بدینLinkedIn: https://www.linkedin.com/in/sajjad-rahimi-890851231/ Telegram: @sajjrhm</description>
                <category>سجاد رحیمی</category>
                <author>سجاد رحیمی</author>
                <pubDate>Fri, 29 Jul 2022 20:16:18 +0430</pubDate>
            </item>
                    <item>
                <title>تجربه‌ی استفاده از hygen در پروژه frontend</title>
                <link>https://virgool.io/signal-tech/%D8%AA%D8%AC%D8%B1%D8%A8%D9%87-%DB%8C-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-hygen-%D8%AF%D8%B1-%D9%BE%D8%B1%D9%88%DA%98%D9%87-frontend-swmo18qchrps</link>
                <description>حین یکی از پروژه‌هایی که توی شرکت سیگنال داشتیم به یک چالشی برخوردیم که بنظرم ممکنه خیلیا باهاش مواجه بشن. بخاطر همین این پستو منتشر کردم.پروژه‌ی ما یک پروژه  Entity Based بود و به ازای اضافه شدن هر Entity به سیستم ، یک‌سری فایل‌هایی به پروژه اضافه می‌شدن که ساختار این فایل‌ٰها برای همه Entity  ها یکسان بود. مثلا فایلی که کامپوننت لیست یا فرم اون Entity داخلش بود یا فایلٰ‌های api و config مربوط به اون Entity .چالش اینجا بود که برای هر Entity باید این چندتا فایل رو می‌ساختیم و یکسری مواقع این فایل‌ها نسبت به فایل‌های بقیه Entity ها فرق زیادی نداشتن.اینجا بود که این به ذهنمون رسید که فرآیند اضافه شدن یک Entity به سیستم رو خودکار کنیم. راه‌های مختلفی رو بررسی کردیم ولی در نهایت به پکیج hygen رسیدیم ، که این کارو به بهترین نحو برامون انجام میداد و ما از تکرار خیلی کارا نجات پیدا می‌کردیم. همچنین اگر نیروی جدیدی میخواست با پروژه کار کنه ، دیگه درگیر این نمیشد که برای دولوپ سیستم و ایجاد یک Entity جدید باید چه فایل‌هایی رو اضافه کنه.توی این پست نحوه‌ی کار با ‌hygen رو توضیح دادمامیدوارم براتون مفید واقع بشهدرواقع Hygen یک code generator هست. کار کردن باهاش خیلی راحته و توی اضافه‌کردن فایل‌های مختلف به پروژه خیلی برامون زمان می‌خره. برای مثال توی فریم‌وورک laravel وقتی شما دستور php artisan make:model رو ران می‌کنید ، یک مدل جدید براتون generate میشه. hygen هم کارش تقریبا همینه و براتون فایل generate می‌کنه. بریم ببینیم داستان چیه.خب ابتدا پکیج hygen رو نصب می‌کنیم. هدف ما اینه که با ران کردن دستور hygen ، یه فولدر به همراه اسم و فایل‌های مشخص ، توی یک آدرس مشخص ( که همه‌ی اینارو ما تعیین می‌کنیم ) ، اضافه بشه به پروژه.فرض کنید ما داخل view های پروژه (منظور فولدر views یا pages هستش ) ، برای هر Entity یک فولدر داریم. داخل فولدر هر Entity ، فولدر Components شامل لیست و فرم اون Entity و فایل‌های api و config مربوط به اون Entity هستش (خیلی به محتویات فایل‌ها و فولدر‌ها کاری نداریم).با استفاده از  hygen ، میتونیم این فایل‌ها و فولدر‌ها رو برای هر Entity جدید ، به صورت کاستوم‌شده با اجرای یک command ایجاد کنیم.ابتدا hygen رو initialize می‌کنیم.بعد از اجرای این دستور میبینیم که یک فولدر به اسم templates_ در پروژه ایجاد شده. داخل این فولدر یک فولدر دیگه به اسم  generator هست که به ما میگه چطور یک command با ساختار مشخص برای hygen ایجاد کنیم.همونطور که می‌بینید یک فولدر generator داریم که داخلش فولدر new و فایل hello.ejs.t.خب حالا این به چه دردی می‌خوره ؟این به این معنیه که اگر دستور  hygen generator new --name رو اجرا کنیم ( دقت کنید که اینجا generator اسم فولدری هس که داخل templates_ قرار داره و میتونه هر اسم دیگه‌ای باشه ) ، فایل‌هایی که داخل فولدر new هست (مثلا  hello.ejs.t ) توی مسیری که داخل همین فایل‌ها نوشته شده قرار داده میشه. وارد کردن name در command هم اختیاری هستش که در ادامه میگم کاربردش چیه.محتویات این فایل به این شکله که در قسمت بالای فایل ، آدرسی که این فایل قراره در اونجا قرار بگیره نوشته می‌شه و قسمت پایین فایل محتویات فایل هستش. تصویر پایین محتویات فایل hello.ejs.t هستش که خود hygen به عنوان نمونه برامون ایجاد کرده.فایل hello.ejs.tحالا بیاید با پیاده‌سازی و کاستوم کردن command خودمون ، یک Entity جدید به همراه فایل‌هاش ایجاد کنیم.هدقمون اینه که یه همچین دستوری داشته باشیم :hygen entity new en_3که با ران کردنش فولدر En_3 به همراه فایل‌های همنام و مخصوص خودش ایجاد بشه. برای اینکار :مرحله اول : فولدر entity رو داخل templates_ ایجاد و سپس داخلش یک فولدر دیگه به اسم new می‌ذاریم.مرحله دوم : فایل‌هایی که میخوایم بعد از اجرا شدن این دستور ایجاد بشن رو داخل فولدر new با پسوند .ejs.t قرار می‌دیم. فایل‌های مدنظر Form ، List ، api و config هستن.مرحله سوم : داخل هر فایل آدرس جایی که میخوایم اون فایل ایجاد بشه و محتوای اولیه‌ش رو قرار میدیم. یعنی در نهایت باید ساختار فولدر templates_ اینطوری بشهحالا برای مثال کدی که داخل فایل Form.ejs.t گذاشتم رو ببینید.فایل Form.ejs.t ما داخل این فایل به اون nameی که در command بعد از کلمه new وارد میکنیم دسترسی داریم و با استفاده از متدهای hygen میتونیم اسم فایل یا هرچیز دیگه رو بر اساس name مشخص کنیم. متدهاشو پیشنهاد میکنم از داک خودش بخونید. خیلی ساده و کاربردیه.https://www.hygen.io/docs/templatesیکی از متدهایی که hygen در اختیارمون قرار میده ()h.changeCase.pascal هست که پارامتر ورودی در command ( که اینجا name بود ) رو تبدیل به پاسکال کیس میکنه. یعنی در مثال ما en_3 تبدیل میشه به En_3 . در قسمت بالای فایل آدرس نهایی به این شکل درمیاد :to : src/views/En_3/En_3_Components/Form.vueقسمت پایین این فایل هم محتویات دلخواهم رو گذاشتم. کدها مربوط به کامپوننت Form هستش که حتی داخل این کدها هم باز به name ی که وارد کردیم دسترسی داریم (و میبینید که اسم Entity رو به عنوان prop به کامپوننت v-entity-form پاس دادم). محتویات و آدرس بقیه فایل‌ها رو هم به همین راحتی میتونم وارد کنم.حالا بریم. دستور رو ران کینم ببینیم چی میشهخب میبینیم که فایل‌ها توی مسیری که خواستیم ایجاد شد. یه نگاهی هم فولدر views بندازیم.دقیقا همون‌ چیزی که می‌خواستیم شد. خیلی راحت فقط با ران کردن یه command ، یه فولدر به همراه فایل‌هاش به صورت کاستوم شده به پروژمون اضافه شداگر یه نگاهی هم به فایل Form.vue بندازیم ، می‌بینیم که کدهایی که می‌خواستیم رو داخل فایل قرار داده ( prop ی که تعریف کرده بودیم رو هم به کامپوننت v-entity-form پاس داده ).خب دیدیم که hygen خیلی میتونه سرعت مارو توی ایجاد فایل‌ها بیشتر کنه ، مخصوصاٌ اگر مثل ما پروژتون  entity based باشه. قابلیت‌های hygen همینجا تموم نمیشه و امکانات خیلی جالب و بیشتری رو ارائه میده. مثلا یکی از کارایی که میتونید باهاش انجام بدید اینه که با ران کردن یک دستور ، یک قطعه کد رو append کنید به انتهای یک فایل. و این خیلی جاها مثل اضافه کردن یک  route جدید به فایل router میتونه به کارتون بیاد. خلاصه که پیشنهاد میکنم حتما داکشو بخونید :)مرسی از وقتی که گذاشتید</description>
                <category>سجاد رحیمی</category>
                <author>سجاد رحیمی</author>
                <pubDate>Sat, 16 Apr 2022 23:03:46 +0430</pubDate>
            </item>
                    <item>
                <title>الگوهای طراحی در ‌javascript - بخش دوم</title>
                <link>https://virgool.io/signal-tech/%D8%A7%D9%84%DA%AF%D9%88%D9%87%D8%A7%DB%8C-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%D8%AF%D8%B1-javascript-%D8%A8%D8%AE%D8%B4-%D8%AF%D9%88%D9%85-cyroxkd1aymw</link>
                <description>توی پست قبلی ما الگوهای طراحی رو تعریف کردیم و با کاربردشون آشنا شدیم و علاوه بر اون الگوی Null Object رو باهم بررسی کردیم و دیدیم که چطور با استفاده از این الگو میشه حالت‌هایی که شیء مدنظر ما null یا undefined هست رو هندل کنیم.حالا داخل این پست میخوایم ۲ مورد دیگه از الگوهای طراحی و کاربردشون رو باهم بررسی کنیم :۱ – الگوی Builder که جزء الگوهای طراحی سازنده (Creational Design Patterns) هست۲ – الگوی Facade که جزء الگوهای طراحی رفتاری (Structural Design Patterns) هستالگوی Builder : خیلی از مواقع ما نیاز داریم یک شیء خیلی بزرگ بسازیم که attributeهای زیادی میتونه داشته باشه. مثلا یک شیء user رو درنظر بگیرید که میتونه attributeهایی مثل نام ، سن ، تلفن ، ایمیل ، آدرس ، auth token و ... داشته باشه. اگر بخوایم این شیء و attribute های اون رو با استفاده از constructor کلاس user بسازیم ، کدمون اینطوری میشه.حالا ما موقع ساختن این شیء مجبوریم تمام attribute هارو پاس بدیم. این attribute ها معمولا غیر از نام و گاهی اوقات شماره تلفن ، ‌optional هستن. حالا اگه نخوایم این ‌attribute های optional رو ست کنیم ، باید اینطوری  شیء یوزر رو بسازیم.مجبوریم تک تک فیلدای optional رو براشون undefined ست کنیم. خیییلی جالب نیست نه ؟راه حل این مشکل الگوی Builder هستش. دو مدل پیاده‌سازی الگوی Builder رو باهم بررسی میکنیم. مدل اول شکل اصلی و اورجینال این الگو هستش و مدل دوم راه حلی هست که یه مقدار جاوااسکریپتی ترهمدل اول :- در مرحله اول ما یک کلاس UserBuillder می‌سازیم و داخل constructor فقط مقادیر اصلی و required رو ست میکنیم.- در مرحله بعد برای هرکدوم از attribute های ‌optional یک متد داخل کلاس UserBuilder اضافه میکنیم.- و در آخر یک متد builder اضافه میکنیم که شیء ‌user رو برای ما return میکنه.ازین به بعد برای ساختن شیء user از کلاس UserBuilder استفاده میکنیم و فقط کافیه نام رو ست کنیم. برای بقیه attribute ها هر کدوم رو که خواستیم ست کنیم ، متدش رو روی شیء مدنظرمون صدا می‌زنیم. دقت کنید که داخل متدها this رو return کردیم تا بتونیم متدهارو chain کنیم.مدل دوم (جاوااسکریپتی) :راه حل ساده تر جاوااسکریپت برای ست کردن attribute های optional اینه که اونا به صورت ‌object پاس بدیم. و فقط همین :)در این صورت میتونیم از کلاس UserBuilder صرف نظر کنیم و اینکارو داخل خود کلاس ‌‌َUser انجام بدیم.همونطور که دیده میشه، میتونیم attribute های optional رو به صورت { key: value } پاس بدیم. و چون داخل constructor ، برای attribute های optional ، یک آبجکت خالی رو به عنوان پیش فرض ست کردیم ، اگر موقع ساخت شیء مقداری رو براشون درنظر نگیریم ، برابر با undefined ست میشن. داخل مثال ما اگر user رو چاپ کنیم ، میبینیم که برای phone و email مقدار undefined ست شده.من خودم به شخصه مدل اول رو بیشتر میپسندم. تر و تمیز تره :) و خب مدل دوم شاید یکم از کانسپت اصلی الگو دور بشه ... شماهم نظرتون رو برام کامنت کنیدبریم برای الگوی بعدیالگوی Façade :یطور کلی این الگو برای این هستش که تغییرات کد شما رو در آینده راحت کنه. الگوی Facade بیان میگه که ما باید پیچیدگی منطق برنامه رو انتقال بدیم به زیرسیستم‌ها. چجور اینکار انجام میشه ؟ با استفاده از یک interface. این interface رابط بین ما و زیرسیستم‌هایی هست که منطق اصلی برنامه داخلشون پیاده سازی شده. کارش هم اینه که اون چیزی رو که زیرسیستم‌ها میخوایم دریافت بکنیم رو بهمون ارائه میده. شاید پیچیده به نظر برسه ولی خیلی ساده تر ازین حرفاست و در عین سادگی به شدت پرکاربرده و کد رو تمیزتر و maintainable تر میکنه.بریم یه مثال ازش ببینیم :دوتا ریکوئست داریم که داخل یکی لیست یوزرها و داخل یکی دیگه پست‌‌های یک یوزر رو دریافت میکنیم. و در آخر هم چاپشون میکنیم.الگوی Facade میگه که پیچیدگی منطق کد رو منتقل کنیم به زیرسیستم‌ها. بنابراین یک interface به اسم getFetch میسازیم و مابقی کدمون رو از متدهای‌ getUsers و getPosts خارج میکنیم. متد getFetch به شکل زیر درمیاد که با استفاده از url و param ی که بهش پاس میدیم ، ریکوئست مدنظر مارو return میکنه.الان دیگه داخل متدهای getUsers و getPosts فقط از این interfaceاستفاده میکنیم. درواقع الگوی Facade باعث شد که متد getUsers ، کاری به منطق پیاده سازی ریکوئست‌ها نداشته باشه. فقط ریکوئستی رو که لازم داره با استفاده از getFetchدراختیارش قرار میدیم.هم کد تمیزتری داریم ، هم تصور کنید بعدا خواستید به جای fetch از axios استفاده کنید. دراین صورت کافیه کدتون رو فقط یکجا تغییر بدین که اون هم داخل متد getFetch هستش. خیلی هم عالی :)داستان الگوهای طراحی اینجا تموم نمیشه و هنوز ادامه داره ... خوشحال میشم نظراتتونو و پیشنهاداتتونو برام کامنت کنید :)</description>
                <category>سجاد رحیمی</category>
                <author>سجاد رحیمی</author>
                <pubDate>Sat, 02 Apr 2022 14:04:49 +0430</pubDate>
            </item>
                    <item>
                <title>الگوهای طراحی در ‌javascript - بخش اول</title>
                <link>https://virgool.io/signal-tech/%D8%A7%D9%84%DA%AF%D9%88%D9%87%D8%A7%DB%8C-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%D8%AF%D8%B1-javascript-gxkf2asvrxia</link>
                <description>الگوهای طراحی  (Design Patterns)خیلی خلاصه بخوام بگم ، الگوهای طراحی درواقع راه‌حل‌هایی هستند برای مشکلاتی که در طراحی و توسعه نرم‌افزارها بوجود میاد. در طول زمان ، برنامه‌نویس‌ها به مشکلات رایج و اغلب بزرگی در روند توسعه نرم‌افزار برمی‌خوردند که بسیاری ازین مشکلات فارع از زبان و حوزه برنامه‌نویسی بود. بنابراین برنامه‌نویس‌ها سعی کردند راه‌حل‌هایی برای حل این مشکلات ارائه بدن که به معروف‌ترین و کارآمدترین‌های اونها design patterns یا الگوهای طراحی گفته می‌شه.اینکه بدونیم کجا و چطوری از الگوهای طراحی استفاده کنیم خیلی مهمه. چون هر الگوی طراحی کاربرد خودشو داره و جه بسا ممکنه با استفاده‌ی نادرست از الگوهای طراحی ، ساختار کد نرم‌افزار رو دچار مشکلات دوچندان بکنیم. اگر مشکلات نرم‌افزار رو درست بشناسیم و تشخیص بدیم که باید از کدوم یک از الگوهای طراحی استفاده کنیم ، در این صورت الگوهای طراحی این مزایا رو برامون دارن :· افزایش مقیاس پذیری (scalability)· افزایش انعطاف پذیری (flexibility)· افزایش سرعت توسعه نرم افزار· کاهش و مدیریت بهتر خطاها· افزایش خوانایی کد (readability)الگوهای طراحی با توجه به کاربردها و اهدافی که دارند ، به سه دسته عمومی تقسیم می‌شن :۱) الگوهای طراحی سازنده (Creational Design Patterns) : الگوهای طراحی که برای حل مشکلات مربوط به ایجاد اشیاء به ما کمک میکنن. مثل الگوهای Singleton ، Factory method ، Builder و Null Object۲) الگوهای طراحی ساختاری (Structural Design Patterns) : این الگوهای طراحی برای حل مشکلات توسعه پذیری ساختار نرم افزارها و برای مدیریت بهتر ارتباط بین کلاس‌ها و اشیاء با همدیگه استفاده می‌شن. مثل الگوهای  Adapter، Decorator ،  Composite و Facade۳) الگوهای طراحی رفتاری (Behavioral Design Patterns) : این الگوها درواقع مجموعه‌ای از راهکارهای کدنویسی مربوط به تعامل و ارتباط اشیاء هستند مثل الگوهای Strategy ، Visitor ، Command و Iteratorحالا یکم بریم سراغ بحث اصلیمون. هدف ما اینه که ببینیم چطور و چه مواقعی در javascript از این الگوها استفاده کنیم و چطور کدمون رو بهبود ببخشیم. پس بریم چند تا ازین الگوها رو بررسی کنیم:الگوی Null Object :بذارید با یک مثال شروع کنم. اگر دقت کرده باشید ، خیلی از مواقع ما یک متد رو صدا میزنیم (مثلا getUser) و اون متد قراره یک شیء برگردونه. و یه موقع‌هایی ممکنه اون شیء null یا undefined باشه. خب مشکلش چیه؟مشکلش اینه که ما هرجایی که با اون شیء کار داریم ، باید بیایم شرط بذاریم و چک کنیم که اگر null یا undefined بود ، فلان کارو انجام بده. مثلا اگر null بود یه خطایی نمایش بده یا اگر ‌undefined بود فلان پراپرتی رو به‌صورت پیشفرض ست کنه.الگوی Null Object میگه بجای اینکه چندجای برنامه if و else بذاری و null بودن شیء مدنظرت رو چک کنی ، بیا یه شیء خالی از جنس شیء مدنظرت تعریف کن و یکبار توی متدی که داری شیء مدنظرت رو برمیگردونی هندلش کن ... همین :)این مثالو درنظر بگیرید. ما یه کلاس یوزر داریم که در اون نوع یوزر (ADMIN یا GUEST) و نامش رو مشخص میکنیم.حالا فرض کنید ما میخوایم اطلاعات یوزرهایی که داریم رو مثل نامشون و دستریشون (بر اساس نوع یوزر) رو چاپ کنیم. با استفاده از متد getUser شیء یوزر مدنظرمون برمیگرده و با استفاده از printUser نام و دسترسی یوزر رو چک و بعد چاپ میکنیم. در صورتی که یوزر رو داخل لیست یوزرها پیدا نکردیم و یا نام براش ثبت نشده بود، نام Guest رو براش درنظر میگیریم. به این شکل :همونطور که میبینید ۲ بار مجبور شدیم یوزر رو چک کنیم که ببینیم null هست یا نه. حالا تصور کنید این شرط‌ها توی پروژه‌های بزرگ و واقعی چقد میتونه زیاد و نکراری بشه.حالا بیاید با الگوی Null Object یه دستی به سر و روی این کد بکشیم. کاری که میکنیم اینه یک کلاس Null Object به یوزر اختصاص میدیم. داخل این کلاس مقادیر پیش‌فرض ست میشه. درواقع شیء ساخته شده از این کلاس ، ورژن null شیء یوزر هستش ... جالبه نه ؟حالا با اینکار فقط کافیه داخل متد getUser چک کنیم ببینیم یوزر مدنظر وجود داره یا نه. درصورتیکه وجود نداشت یه شیء از کلاس NullUser رو برمیگردونیم و تمام. از بند مابقی شرط‌ها برای null بودن یوزر رها شدیم. کد نهایی به این شکل درمیاد.ﻣﯿﺒﯿﻨﯿﺪ ﮐﻪ ﮐﺪﻣﻮن ﻣﻨﻄﻘﯽ‌ﺗﺮ و ﺳﺎﺧﺘﺎرﻣﻨﺪﺗﺮ ﺷﺪ .در ﺿﻤﻦ ﻣﺸﮑﻠﺎﺗﯽ ﮐﻪ درﺻﻮرت null ﺑﻮدن ﯾﻮزر ﻣﯿﺘﻮﻧﻪ ﺑﻮﺟﻮد ﺑﯿﺎد اﯾﻨﻄﻮری راﺣﺖ‌ﺗﺮ ﻫﻨﺪل ﻣﯿﺸﻪ .ﻓﺎﯾﺪه‌ی دﯾﮕﻪ‌ش اﯾﻨﻪ ﮐﻪ اﮔﺮ ﺧﻮاﺳﺘﯿﻢ ﻣﻨﻄﻖ ﻫﻨﺪل ﮐﺮدن ﺷﯽء null رو ﺗﻐﯿﯿﺮ ﺑﺪﯾﻢ ﻓﻘﻂ ﮐﺎﻓﯿﻪ ﮐﻠﺎس NullUser رو ﺗﻐﯿﯿﺮ ﺑﺪﯾﻢ. ﺗﻮی ﺑﺨﺶ‌ﻫﺎی ﺑﻌﺪی ﭼﻨﺪ ﻣﻮرد دﯾﮕﻪ از اﻟﮕﻮﻫﺎی ﻃﺮاﺣﯽ رو ﺑﻪ ﻫﻤﺮاه ﮐﺎرﺑﺮد و ﻣﻨﻄﻖ ﭘﯿﺎده‌ﺳﺎزﯾﺸﻮن ﺑﺎﻫﻢ ﺑﺮرﺳﯽ ﻣﯿﮑﻨﯿﻢدرضمن برای مطالعه در مورد design pattern ها این سایت بنظرم رفرنس خیلی خوبیه :dofactory.com/javascript/design-patternsﻣﺮﺳﯽ ازﯾﻨﮑﻪ وﻗﺖ ﮔﺬاﺷﺘﯿﺪ :)</description>
                <category>سجاد رحیمی</category>
                <author>سجاد رحیمی</author>
                <pubDate>Sun, 27 Mar 2022 23:54:08 +0430</pubDate>
            </item>
                    <item>
                <title>تفاوت الگوی imperative و declarative در برنامه‌نویسی</title>
                <link>https://virgool.io/@sajjadrahimi/%D8%AA%D9%81%D8%A7%D9%88%D8%AA-%D8%A7%D9%84%DA%AF%D9%88%DB%8C-imperative-%D9%88-declarative-%D8%AF%D8%B1-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-sdjm4scsrayc</link>
                <description>به طور کلی در برنامه نویسی دو رویکرد یا دو الگو برای کدنویسی داریم ، الگوی imperative و declarative. داخل این این مقاله سعی کردم یه مقدار در موردشون توضیح بدم و بعد ازون به یک‌سری نکات اولیه در مورد functional programming بپردازم.الگوی imperative :این الگو بیان می‌کنه که کدزدن باید به نحوی باشه که برای حاصل شدن یک نتیجه خاص تمام مراحل اون رو قدم به قدم برای برنامه توضیح بدیم. درست مثل دستور پخت غذا. مرحله به مرحله و با جزئیات. مثال زیر رو که با توجه به این الگو نوشته شده درنظر بگیرید.jدر این مثال ما یک آرایه داریم که می‌خوایم یک آرایه‌ی دیگه با عناصر دوبرابر آرایه اول داشته باشم. اگر دقت کرده باشید مرحله به مرحله به برنامه گفتیم چکار کنه. اول اینکه یک متغیر جدید بسازه و اون رو برابر یک آرایه خالی قرار بده. بعد یک حلقه برای اون تعیین کردیم تا به اندازه‌ی طول آرایه اول تکرار بشه و مقادیر آرایه اول رو در ۲ ضرب کنه و در آرایه دوم قرار بده. قشنگ همون طرز پخت غذاس. اول آبو جوش بذار، بعد نمک بریز و بعد فلان کارو بکن تا غذا درست بشهالگوی declarative :اما در عوض الگوی declarative می‌گه که شما باید نتیجه‌ای که میخواید حاصل بشه رو برای برنامه توصیف کنین. درواقع اینطور درنظر بگیرید که الگوی قبلی ‌‌do to How و این الگو do to What هست. دیگه ما مرحله به مرحله تسک‌ها رو به برنامه امر نمیکنیم. دیگه طرز پختی درکار نیست. فقط غذایی رو که میخوایم توصیف میکنیم.مثال قبل رو ایندفعه با الگوی declarative نوشتیم.اینجا اومدیم از متد map استفاده کردیم و درواقع خیلی ساده برای برنامه توضیح دادیم که ما یه آرایه doubled می‌خوایم که عناصرش دوبرابر آرایه اول باشه. الگوی declarative یک الگوی محبوب در برنامه‌نویسی هستش که رفته رفته توسعه پیدا کرده و مفاهیم و زیرالگوهای جدیدی از اون نشأت پیدا کردن که یکی از اونها programming functional هستش. functional programming درواقع بر پایه‌ی این ایده‌ست که ما برناممون رو تبدیل کنیم به مجموعه‌ا ی ازpure function ها که از  side effect ها (در ادامه به اینا میپردازیم) جلوگیری میکنن. درواقع programming functional و کدزنی با استفاده از الگوی declarative روش مدرن پیاده‌سازی برنامه ها در javascript هستش.مفهوم functional programming :حالا بپردازیم به یک‌‌سری از مفاهیم اولیه programming functional.۱) ساید افکت ( side effect ) : اگر داخل یک تابع دیتایی بیرون از تابع رو تغییر بدیم باعث ایجاد effect side شدیم.۲) پیور فانکشن ( pure furnction ) : توایعی هستند که منجر به ایجاد side effect نمیشن و و همیشه به ازای یک ورودی مشخص یک خروجی مشخص به ما میدن۳) ایمیوتبیلیتی ( immuability ) : به معنای اینه که state دیتا هیچوقت تغییر نکنهدرعوض state دیتا کپی بشه و تغییرات روی اون کپی انجام بشه و state اصلی دیتا دست نخورده بمونهحالا چطور برناممون رو بنویسیم که این اصول رو رعایت کنه؟هیچوقت نمیتونیم ۱۰۰ درصد از  side effect ها جلوگیری کنیم ولی یکسری تکنیک هست که میتونیم ازشون کمک بگیریم  :- توابعمون رو به صورتی بنویسیم که فقط یک کار مشخص انجام بدن ( single resposibility ) و دیتای خارج از تابع رو تغییر ندن.- برای تغییر فرم دیتا از متدهایی مثل filter , map , reduce و ... استفاده کنیم.همچنین استفاده از این موارد کمک میکنه تا کد برناممون بیشتر از الگوی declarative پیروی کنه :- destructuring object - operator spread (...)- operator ternary ( condition ? do this : do that )قصد دارم بعدا بصورت مفصل تر در مورد اصول و تکنیک‌های functional programming صحبت کنم و فعلا به همین تکات بسنده کنیم. همچنین در مورد اینکه اگر در javascript به صورت OOP برنامه‌نویسی کردیم چه اصولی رو رعایت کنیم تا کدمون بهتر بشه.مرسی از اینکه وقت گذاشتید :)</description>
                <category>سجاد رحیمی</category>
                <author>سجاد رحیمی</author>
                <pubDate>Mon, 21 Mar 2022 14:02:11 +0330</pubDate>
            </item>
            </channel>
</rss>