<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Ali</title>
        <link>https://virgool.io/feed/@mohammadali.khandan</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-16 11:38:14</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/901319/avatar/hxopy2.jpg?height=120&amp;width=120</url>
            <title>Ali</title>
            <link>https://virgool.io/@mohammadali.khandan</link>
        </image>

                    <item>
                <title>برداشتی از کتاب Architecture Patterns with Python فصل اول - مدل‌سازی دامنه</title>
                <link>https://virgool.io/ArchPatternsWithPython/%D8%A8%D8%B1%D8%AF%D8%A7%D8%B4%D8%AA%DB%8C-%D8%A7%D8%B2-%DA%A9%D8%AA%D8%A7%D8%A8-architecture-patterns-with-python-%D9%81%D8%B5%D9%84-%D8%A7%D9%88%D9%84-%D9%85%D8%AF%D9%84-%D8%B3%D8%A7%D8%B2%DB%8C-%D8%AF%D8%A7%D9%85%D9%86%D9%87-jqdnjg9dxxld</link>
                <description>طرح از فتانه کهن‌زادهدر این مقاله به فصل اول کتاب می‌پردازیم. نام این فصل مدل‌سازی دامنه یا domain modeling می‌باشد.این مقاله صرفاً ترجمه جمله به جمله کتاب نمی‌باشد و بیشتر شبیه به یک یادداشت شخصی است. امیدوارم که دوستان دیگر هم بتوانند از آن استفاده کنند.در این فصل یادخواهید گرفت کهمدل دامنه چیست.چگونه می‌توان یک مدل دامنه از کسب و کار تهیه کرد.تفاوت بین value object و entity در چیست.عملیات‌های entity می‌توانند در خارج از entity به صورت domain service نوشته شوند.در راستای این مقاله، می‌توانید مقالات زیر را هم مشاهده کنید:برداشتی از کتاب Architecture Patterns with Python - مقدمهمنظور از یک مدل دامنه چیست؟در مقدمه کتاب از اصطلاح business logic layer یا لایه منطقی بیزینس به عنوان لایه میانی در معماری سه‌لایه استفاده شده بود. اما کتاب در ادامه از اصطلاح مدل دامنه یا domain model بجای آن استفاده می‌کند. این اصطلاح از مبحث طراحی دامنه محور یا DDD گرفته شده است. اما مدل دامنه به چه معنی است. در ابتدا دامنه و مدل را به صورت جداگانه تعریف می‌کنیم. سپس از این دو استفاده می‌کنیم و یک تعریف روشن از مدل دامنه ارائه می‌دهیم.دامنه روشی شیک برای بیان مسئله‌ای است که می‌خواهید حل کنید. با یک مثال تعریف دامنه را بیشتر توضیح می‌دهیم. یک فروشگاه آنلاین مبلمان را در نظر بگیرید. با در نظر گرفتن اینکه در مورد چه سیستمی در این فروشگاه آنلاین مبلمان صحبت می‌کنید، دامنه می‌تواند، خرید مبلمان، طراحی محصول و یا بسته‌بندی و تحویل آن باشد. کار برنامه‌نویسان بهبود و اتوماتیک کردن فرایندهای کسب و کار است. پس می‌توان گفت، دامنه مجموعه فعالیت‌هایی است که آن فرایندها پشتیبانی می‌کنند.مدل یک نقشه از یک فرآیند یا پدیده است که یک ویژگی مفید را به تصویر می‌کشد. انسان‌ها در ایجاد یک مدل از اشیاء فوق‌العاده هستند. برای مثال اگر کسی توپی را به سمت شما پرتاب کند، تقریباً به صورت ناخودآگاه می‌توانید حرکت آن را پیش‌بینی کنید. زیرا مدلی از حرکت یک جسم در فضا در ذهن شما وجود دارد. اما مدل‌ها همیشه کامل نیستند. برای مثال نمی‌توانید حرکت آن توپ با سرعت نور در فضا را به راحتی مدل کنید. البته به این معنا نیست که مدل ذهنی شما اشتباه است، بلکه برخی از پیش‌بینی‌ها خارج از دامنه شما می‌باشد.مدل دامنه نقشه ذهنی است که صاحبان مشاغل از کسب و کار خود دارند. همه صاحبان کسب و کار این نقشه‌های ذهنی را دارند - این نقشه‌های ذهنی می‌گوید که انسان‌ها چگونه در مورد فرآیندهای پیچیده فکر می‌کنند.این کتاب قصد دارد که اتوماتیک کردن فرایندهای یک کسب و کار را به صورت واقعی انجام دهد. پس به عنوان مهندس نرم افزار اگر زمانی از شما خواسته شد که نرم‌افزار یک کسب و کار را بنویسید، قدم اول این است که اصطلاحاتی که در آن کسب و کار استفاده می‌شود را یاد بگیرید. کسب و کاری که می‌خواهیم در نظر بگیریم یک شرکت خرده فروشی مبلمان است، که مبلمان خود را از تولیدکنندگان سراسر جهان تهیه می‌کند و آن را به سراسر اروپا می‌فروشد.زمانی که یک مبل و یا یک میز سفارش می‌دهید، باید بدانیم که چگونه می‌توان کالاهای شما را از لهستان یا چین و یا ویتنام به اتاق نشیمن شما وارد کرد. به بیان دیگر، ما سیستم‌های جداگانه‌ای داریم که مسئول خرید کالا، فروش آن به مشتری، و حمل آن کالا برای مشتری هستند. همچنین به یک سیستم میانی نیاز داریم تا فرایند تخصیص کالا به سفارش مشتری را هماهنگ کند.تصور کنید که این کسب و کار تصمیم به یک روش جدید برای تخصیص کالا به مشتری می‌گیرد. تا به حال کسب و کار براساس آنچه که کالا به صورت فیزیکی در انبار موجود بود، زمان عرضه و تحویل آن را مشخص می‌کرد. اگر آن کالا در انبار تمام می‌شد، تا زمانی که آن کالا از سمت کارخانه برسد، به آن برچسب تمام شده می‌دادند.در اینجا یک نوآوری بکار می‌بریم. اگر سیستمی داشته باشیم که بتواند تمام محموله‌های ما را ردیابی کند، و زمانی که قرار است این محموله‌ها به انبار حمل شوند را داشته باشیم، می‌توانیم این کالاهایی که در حال حمل به انبار هستند را به عنوان موجودی واقعی و بخشی از موجودی انبار در نظر بگیریم، اما با زمان تحویل کمی طولانی‌تر. با این کار به نظر می‌رسد که دیگر لازم نیست به محصولات برچسب تمام شده زده شود، و بیشتر می‌فروشیم، و بیزینس می‌تواند با نگهداری کمتر کالاها در انبار در هزینه‌های خود صرفه‌جویی کند.پس تخصیص سفارش‌ها دیگر یک موضوع بی‌اهمیت برای کاهش یک مقدار واحد در سیستم انبار نیست. ما به مکانیزم تخصیص پیچیده‌تری نیاز داریم. حال زمان این رسیده است که مدل دامنه را برای این کسب و کار تعریف کنیم.بررسی زبان دامنهبرای درک مدل دامنه نیاز به زمان، صبوری و تهیه مستندات زیادی از کسب و کار داریم. در ابتدا یک گفتگوی اولیه با کارشناسان کسب و کار انجام می‌دهیم، و بر سر یک واژه‌نامه مشترک و یک سری قوانین که در کسب و کار وجود دارد، به منظور تهیه یک نسخه اولیه از مدل دامنه با هم به توافق می‌رسیم. در این گفتگو تا جایی که امکان دارد، برای توضیح هر قانون، مثال‌های عینی از کارشناسان می‌خواهیم. باید مطمئن باشیم که این قوانین  در اصطلاحات تجاری گفته شده بیان می‌شوند. سپس یک سری نام یا شناسه‌ برای اشیای خود انتخاب می‌کنیم تا صحبت در مورد مثال‌ها راحت‌تر باشد. مثال خرده‌فروشی مبلمان را که در بالا بیان کردیم را در نظر بگیرید. به همین منظور با کارشناسان کسب و کار صحبت کردیم. یادداشت‌هایی که در این گفتگو تهیه کردیم به شرح زیر می‌باشد:یادداشت تهیه شده از گفتگو با کارشناسان کسب و کار:یک محصول با یک SKU مشخص می‌شود. SKU مخفف عبارت stock-keeping unit (واحد انبارداری) است. مشتریان درخواست سفارش می‌دهند. یک سفارش با یک order reference مشخص می‌شود و که می‌تواند شامل چند order line باشد. هر order line هم دو ویژگی دارد، SKU و تعداد آن. برای مثال:۱۰ واحد از میز قرمز۱ واحد از میزنهارخوریواحد خرید شرکت دسته‌های (batches) کوچکی از محصولات را سفارش می‌دهند. یک دسته محصول شامل یک شناسه منحصربفرد به نام reference، یک SKU و تعداد آن می‌باشد.حال نیاز داریم که order line ها را به batch ها اختصاص دهیم. وقتی یک order line را به یک batch اختصاص دادیم، محصول را از  آن batch خاص به آدرس مشتری ارسال خواهیم کرد. پس وقتی x واحد از یک محصول را به یک batch اختصاص می‌دهیم، موجودی آن x واحد کاهش می‌یابد.برای مثال:یک batch یا دسته ۲۰ تایی میز داریم، ۲ میز را به یک order line اختصاص می‌دهیم.در دسته ما ۱۸ میز باقیمانده است.اگر موجودی یک batch کمتر از تعداد گفته شده order line باشد، فرایند اختصاص را نمی‌توانیم انجام دهیم. برای مثال:یک batch شامل یک تشک آبی، و یک order line با ۲ تشک آبی داریم.این line را به این batch نمی‌توانیم اختصاص دهیم.یک order line یکسان را دو بار نمی‌توانیم به یک batch اختصاص دهیم. برای مثال:یک batch از ۱۰ گلدان آبی داریم، به آن یک order line شامل ۲ گلدان را اختصاص می‌دهیم.اگر order line را دوباره به همان دسته اختصاص دهیم، دسته باید هنوز موجودی ۸ عدد را نشان دهد.با توجه به اینکه batch ها در حال حمل به سمت انبار باشند و یا در انبار موجود باشند، هر کدام یک ETA دارند. batch های موجود در انبار نسبت به batch های در حال حمل اولویت دارد. اولویت batch های در حال حمل هم با توجه به اینکه ETA کدام یک زودتر است، مشخص می‌شود.همان طور که در گفتگو با کارشناسان کسب و کار مشاهده کردید، فرایندها را از دید کارشناسان به صورت کامل یادداشت‌برداری کردیم. حال زمان آن است که مدل دامنه خود را طراحی کنیم و برای هر یک از موارد بالا تست unit بنویسیم، تا بتوانیم صحت آنها را در برنامه بررسی کنیم.تست unit برای مدل‌های دامنهزمانی که می‌خواهیم یک تست unit بنویسیم، باید به موارد زیر در آن توجه کنیم:نام تست unit نشان‌دهنده رفتاری است که می‌خواهیم از سیستم مشاهده کنیم.نام کلاس‌ها و متغیرهایی که استفاده می‌کنیم، از اصطلاحات کسب و کاری که از مصاحبه با کارشناسان کسب و کار استخراج کرده‌ایم می‌آید.اگر کد تست unit را به یک همکاری که برنامه‌نویس نمی‌باشد نشان دهیم، باید بتواند توصیف ما را از رفتار سیستم تأیید کند.اولین سناریو این بود که یک batch و یک order line داریم. حال می‌خواهیم order line را به batch اختصاص دهیم، با این کار باید موجودی batch به اندازه تعداد order line کم شود. تست unit آن به صورت زیر است: https://gist.github.com/68ef6c533af494d9e81b6ee2e4c197ac.git مدل دامنه را هم به صورت زیر تعریف می‌کنیم: https://gist.github.com/983162bdedc833d0da05d9ca666a522b.git در گام اول، مدل دامنه را ساده در نظر گرفته‌ایم. به این صورت که در مدل Batch از فقط یک خصوصیت available_quantity به عنوان موجودی استفاده کرده‌ایم. تابع allocate هم تعداد موجود در order line را از موجودی انبار کم می‌کند. در گام‌های بعدی با توجه به توضیحات کارشناسان کسب و کار تست‌هایی را بیان می‌کنیم که در آن نمی‌توانستیم order line را به batch اختصاص دهیم. https://gist.github.com/mohammadali66/e026dc4dd54776d9a104a2f3057d7f3a با توجه به تست‌های unit که برای فرایندهای شکست نوشتیم، نیاز داریم که مدل Batch را کمی تغییر دهیم. https://gist.github.com/mohammadali66/b275517b62fe41aa0c413ce251578998 به مدل دامنه توجه کنید. در این مدل، یک batch مجموعه‌ای از اشیای Order line را که به آن اختصاص داده شده است را در مشخصه allocations_ نگه می‌دارد. وقتی عمل allocate را انجام می‌دهیم، در ابتدا بررسی می‌شود که آیا SKU مربوط به order line با batch یکسان است؟ و موجودی کافی است یا نه؟ سپس به مجموعه allocations_ اضافه می‌شود.اگر به مدل دامنه دقت کنید، می‌بینید که آن را خیلی ساده پیاده‌سازی کرده‌ایم. در واقعیت شاید پارامترها و قوانین دیگری هم دخیل باشند. برای مثال مشتری می‌خواهد سفارش خود را در یک تاریخ خاصی دریافت کند. یا اینکه با توجه به موقعیت مکانی مشتری، ممکن است که از یک انبار خاصی برای تخصیص سفارش استفاده کنیم. پس ممکن است که در یک کسب و کار واقعی پیچیدگی‌های زیاد دیگری داشته باشید که در اینجا از آنها اجتناب کرده‌ایم.اما برای اینکه بتوانیم مدل دامنه بهتری بنویسیم، پایتون امکانات خوبی در اختیار ما گذاشته است. در ادامه در مورد این امکانات پایتون برای بهبود مدل دامنه خود صحبت می‌کنیم.تعریف type در پایتوندر پایتون با استفاده از کلاس NewType می‌توانید یک type جدید تعریف کنید. https://gist.github.com/mohammadali66/11847f8ae2683f4fc55735334d56e39f تعریف Value Objectیک value object شیٔ است که برای خود مشخصه id ندارد، و با داده‌هایی که در خود نگه می‌دارد شناخته می‌شود. اگر هم یکی از داده‌ها تغییر کند، value object تغییر هویت می‌دهد. برای درک این مطلب، سه مدل تعریف value object را در پایتون بیان می‌کنیم. https://gist.github.com/mohammadali66/b4350799ea293d638c5f6427f40ba540 این تعاریف همه یکی هستند. شما می‌توانید یک شئ value object را با dataclass یا با NamedTuple و یا با namedtuple تعریف کنید. رفتار جالبی که value object ها دارند این است که از عملیات‌های ریاضی پشتیبانی می‌کنند. برای مثال: https://gist.github.com/mohammadali66/3f2ba9813b2f7c558747ba2a04a238ce حال که در مورد value object ها صحبت کردیم، به مدل دامنه خود برمی‌گردیم. در کسب و کار ما یک سفارش یا order از چندین line تشکیل می‌شود. هر line برای خود یک SKU و تعداد دارد. برای مثال یک order را می‌توان به صورت زیر درنظر گرفت: https://gist.github.com/mohammadali66/81bc55eae3a38de13d6c9c7a95b5bf13 توجه کنید یک order خود یک reference دارد که از آن به عنوان شناسه یکتا استفاده می‌شود، اما line برای خود یک شناسه یکتا ندارد. با توجه سناریو مطرح شده، به این نکته توجه کنید: زمانی که یک مفهوم کسب و کاری داشته باشیم که شامل داده باشد اما از خود یک شناسه هویتی یکتا نداشته باشد، برای نمایش آن از الگوی value object استفاده می‌شود. پس value object یک شئ دامنه است که با استفاده از داده‌هایی که در خود نگه می‌دارد، شناخته می‌شود. https://gist.github.com/mohammadali66/efadbbad9c6a66deb5b20940e62edf08 مقایسه Value Object با Entityیک order line در کسب وکار مطرح شده با استفاده از order ID و SKU و تعداد محصول شناخته می‌شود. اگر یکی از این مقادیر را تغییر دهیم، یک line جدید خواهیم داشت. این همان تعریف value object است که می‌گوید، هر شئ که تنها با استفاده از داده‌های خودش هویت بگیرد و هویت طولانی مدت نداشته باشد. اما آیا در مورد batch هم می‌توانیم چنین چیزی بگوییم.اصطلاح entity توصیف کننده یک شئ دامنه است که هویت طولانی مدت دارد. در بخش‌های قبل کلاس Name را به عنوان یک value object معرفی کردیم. اگر ما نام Harry Percival را تعریف کرده باشیم، سپس یک حرف آن را تغییر دهیم، دیگر یک نام جدید Barry Percival داریم. برای ما هم مشخص است که Harry Percival با Barry Percival متفاوت است. https://gist.github.com/mohammadali66/95537879772f60c2002dc2c0b746a6de اما اگر Harry را به عنوان یک شخص در نظر بگیریم، چه اتفاقی رخ می‌دهد. در انسان‌ها، اگر نام، ظاهر آنها و یا حتی اگر جنسیت‌شان تغییر کند، باز هم هویت خودشان را دارند. به خاطر اینکه انسان‌ها برخلاف اسامی هویت ثابتی دارند. https://gist.github.com/mohammadali66/ffcba1c5675f606a0d6d1f41401fd085 اشیای entity برخلاف value object ها، برابری هویت دارند. می‌توانید یکی از مقادیر آن را تغییر دهید، با این حال هنوز همان هویت خودش را دارد. batch ها در مثال ما از همین جنس هستند. می‌توانیم به یک batch مقادیر line متعددی اختصاص دهیم، و یا تاریخ دریافت آن را تغییر دهیم، اما همچنان هویت یکسانی دارد.برای این که برابری را در یک entity بررسی کنیم، می‌توانیم از تابع __eq__ استفاده کنیم. با این کار عملگر == را برای آن تعریف کرده‌ایم. https://gist.github.com/mohammadali66/cd4b24987f403fd65daab12e7749167c تابع hash به منظور کنترل رفتار اشیا زمانی که در یک مجموعه‌ای یا به عنوان dict keys استفاده می‌شود، مفید هستند.یک تابع سرویس دامنهعملیات‌های سرویس دامنه می‌توانند در entity یا value object قرار نداشته باشند. اختصاص یک order line به مجموعه‌ای از batch ها بیشتر شبیه به یک تابع می‌ماند، که در اینجا آن را به صورت یک تابع allocate می‌نویسیم. https://gist.github.com/mohammadali66/7ee4796dd0c4878e071d656cf4bdfb4b اگر از استفاده از ()next را دوست ندارید و می‌خواهید بجای آن از ()sorted استفاده کنید، می‌توانید تابع __gt__ مدل دامنه را پیاده‌سازی کنید: https://gist.github.com/mohammadali66/c92c823d53aebf32188b290a750277dc به انتهای فصل اول کتاب رسیدیم. امیدوارم برای شما مفید بوده باشد.</description>
                <category>Ali</category>
                <author>Ali</author>
                <pubDate>Sun, 19 Mar 2023 11:03:19 +0330</pubDate>
            </item>
                    <item>
                <title>برداشتی از کتاب Architecture Patterns with Python - مقدمه</title>
                <link>https://virgool.io/ArchPatternsWithPython/architecture-patterns-with-python-introduction-omrwudmawe0y</link>
                <description>طرح از فتانه کهن‌زادهدر راستای این مقاله، می‌توانید مقالات زیر را هم مشاهده کنید:برداشتی از کتاب Architecture Patterns with Python فصل اول - مدل‌سازی دامنهزمانی که برنامه‌نویسی را به تازگی شروع می‌کنیم، تصور این است که اگر تمام دستورات و ماژول‌های یک زبان برنامه‌نویسی را یاد داشته باشیم، تبدیل به یک برنامه نویس حرفه‌ای می‌شویم. اما همین طور که از عمر برنامه‌نویسی ما می‌گذرد، متوجه می‌شویم که دنیای برنامه‌نویسی فراتر از یادگیری یک زبان برنامه‌نویسی است، و برنامه‌نویسی برای ما از یک حرفه تبدیل به یک هنر می‌شود که با استفاده ابزارهایی که در دسترس است می‌توانیم آنچه که در ذهن ما وجود دارد را آمیخته به خلاقیت کنیم و یک محصول خوب بیافرینیم.کتاب Architecture Patterns with Python از جمله کتاب‌هایی است که پیرامون بحث طراحی نرم‌افزار صحبت می‌کند. این کتاب از زبان پایتون برای بیان مطالب خود استفاده می‌کند، تا بتواند به راحتی مباحث مربوط به طراحی نرم‌افزار را بیان کند.کتاب پیرامون سه محور یا معماری برای توسعه نرم‌افزار صحبت می‌کند:توسعه تست محور یا Test-driven development (TDD)طراحی دامنه محور یا Domain-driven design (DDD) میکروسرویس‌های واکنش‌گرا یا Reactive microservicesدر این پست به مقدمه کتاب می‌پردازیم، و خلاصه‌ای از مطالبی که در آن مطرح شده است را برای شما بیان می‌کنیم.زمانی که کلمه بی‌نظمی (chaos) را می‌شنوید چه چیزی به ذهن شما خطور می‌کند؟ اگر با کلمه نظم (order) مواجه شوید، تداعی‌گر چه چیزی برای شما است؟ برای مثال یک باغچه می‌تواند منظم باشد، اگر علف‌های هرز آن چیده شده باشد، یا کنار باغچه فنس‌کشی باشد و هر کدام از سبزیجات در یک دسته جدا کاشته شده باشند. اما اگر به باغچه رسیدگی نشود، آن باغچه تبدیل به یک باغچه نامنظم می‌شود که پر از علف هرز است و به گیاهان آن رسیدگی نشده است.سیستم‌های نرم‌افزاری هم می‌توانند دچار بی‌نظمی شوند. زمانی که یک سیستم جدید راه‌اندازی می‌کنیم، کدهای ما خیلی تمیز و منظم است. اما در طی زمان، کلاس‌ها و ماژول‌هایی که نوشته‌ایم افزایش پیدا می‌کند. بعد از چند وقت متوجه می‌شویم که برخی از این کلاس‌ها بلااستفاده هستند. تعدادی از آنها کار یکسانی را انجام می‌دهند. در بعضی از موارد هم کد به نحوی نوشته شده است که یکی در دیگری فراخوانی شده است. در این مورد اگر بخواهیم بخشی از کد را تغییر دهیم، باعث می‌شود که روی بخش‌های دیگر هم تأثیر بگذارد و براحتی نتوانیم آن را تغییر دهیم. این کارها به نوعی بی‌نظمی در نرم‌افزار ما به وجود می‌آورد.اما خوشبختانه تکنیک‌هایی وجود دارد تا از این مسئله جلوگیری شود.تکنیک Encapsulation and Abstractionsاصطلاح encapsulation یعنی ساده‌سازی یک رفتار و پنهان کردن داده‌ها. در ابتدا با شناسایی وظیفه‌ای که در کد ما وجود دارد، آن رفتار را شناسایی می‌کنیم. سپس این وظیفه را به یک شئ یا تابع خوش تعریف می‌دهیم. به این کار encapsulation می‌گوییم و آن شئ یا تابع را abstraction می‌نامیم. به دو کد زیر توجه کنید:  https://gist.github.com/2e21faa21bf336147b44265d5650cd7b.git  https://gist.github.com/eaac818f22f4ee30ac804a0ac83939af.git هر دو کد کار یکسانی را انجام می‌دهند. هر دو مقادیر یک فرم را می‌گیرند و آن را به یک url ارسال می‌کنند تا از موتور جستجوی API استفاده کند. اما کد دوم خواناتر و قابل فهم‌تر است، زیرا از سطح بالاتری از abstraction استفاده کرده است.می‌توان گفت که encapsulation و abstraction ابزار قدرتمندی است که باعث می‌شود کد ما خواناتر، تست پذیرتر و نگهداری آن آسان‌تر باشد.لایه‌بندیبا استفاده از encapsulation و abstraction می‌توانیم جزئیات مربوط به کد خود را پنهان کنیم و با این کار از داده‌های خود حفاظت می‌کنیم. اما اگر توجه کنید، می‌بینید که بخش‌های مختلف یک برنامه با هم ارتباط دارند و برای مثال یک تابع ممکن است در تابع یا کلاسی دیگر فراخوانی شده باشد. این وابستگی در بیشتر موارد برای ما مشکل ایجاد می‌کند. زیرا در این صورت تغییرات در کد سخت و باعث اثرگذاری روی بخش‌های دیگر می‌شود. معماری لایه‌ای راه حلی است برای مقابله با این مسئله.معماری سه‌لایه‌ایدر معماری لایه‌ای برنامه به دسته‌های جدا از هم تبدیل می‌شود. سپس مشخص می‌شود که هر دسته کدام دسته را می‌تواند فراخوانی کند. معماری سه‌لایه‌ای یکی از معروف‌ترین آنها است. لایه presentation همان رابط کاربری است. رابط کاربری می‌تواند یک صفحه وب، API و یا یک command line باشد. این لایه با لایه منطقی business ارتباط دارد. لایه business نقش‌های فرایندی و workflow را به عهده دارد. در نهایت هم لایه database است که وظیفه ذخیره و ارسال داده‌ها را دارد.مقدمه کتاب در اینجا تمام می‌شود. کتاب در ادامه به بیان معماری در طراحی نرم‌افزار می‌پردازد. در پست‌های آینده سعی می‌شود که در مورد هر کدام از فصل‌های کتاب به صورت مجزا صحبت شود.</description>
                <category>Ali</category>
                <author>Ali</author>
                <pubDate>Sat, 10 Sep 2022 19:39:36 +0430</pubDate>
            </item>
                    <item>
                <title>چگونه کتابخانه Angular خود را در npm انتشار دهید</title>
                <link>https://virgool.io/aurorabook/%DA%86%DA%AF%D9%88%D9%86%D9%87-%DA%A9%D8%A7%D9%85%D9%BE%D9%88%D9%86%D9%86%D8%AA-angular-%D8%AE%D9%88%D8%AF-%D8%B1%D8%A7-%D8%AF%D8%B1-npm-%D8%A7%D9%86%D8%AA%D8%B4%D8%A7%D8%B1-%D8%AF%D9%87%DB%8C%D9%85-l5iv7z5mq7aa</link>
                <description>اگر با angular به صورت حرفه‌ای کار می‌کنید، همیشه پیش آمده است که کامپوننت‌هایی ایجاد کنید که بتوانید در کل پروژه خودتان چندین بار از آن استفاده کنید. اما آیا تاکنون به این فکر افتاده‌اید که کامپوننت‌هایی که نوشته‌اید را با افراد دیگری در سراسر جهان به اشتراک بگذارید. اگر قصد این کار را دارید، می‌توانید تا انتهای مقاله همراه من باشید تا روش این کار را به شما آموزش دهم.سایت npmjs بزرگترین مکان برای ثبت نرم افزار در جهان است. توسعه دهندگان نرم افزارهای متن باز از npm برای اشتراک گذاری نرم افزارهای خود استفاده می‌کنند. در ابتدا شما نیاز دارید که در npm برای خود یک حساب کاربری باز کنید. شما می‌توانید با استفاده از این لینک به صورت رایگان ثبت نام کنید.نصب Angular اگر قبلا با angular کار کرده‌اید، پس احتمالا آن را روی سیستم خود نصب دارید. در غیر این صورت، در ابتدا نیاز دارید که NodeJS و npm را نصب کنید. برای این کار می‌توانید از لینک https://nodejs.org/en/download استفاده کنید. سپس با استفاده از دستور زیر angular CLI را نصب کنید.npm i -g @angular/cliساخت یک پروژه angularدر ابتدای کار نیاز دارید که یک پروژه angular بسازید. اما قبل از آن نیاز دارید که یک workspace بسازید که پروژه شما متعلق به آن باشد. برای ساخت یک angular workspace از دستور زیر استفاده کنید.ng new &lt;workspace-name&gt; --create-application=falseدر این دستور بجای &lt;workspace-name&gt; نام مورد نظر خود را قرار دهید. از  create-application=false به این علت استفاده شده است تا در پروژه application ایجاد نشود. زیرا قصد داریم که یک library ایجاد کنیم. سپس با دستور زیر به مسیر پوشه workspace خود بروید.cd &lt;workspace-name&gt;برای مثال من یک workspace به صورت زیر می سازم.ng new apple --create-application=falseساخت یک Angular Library جدیدیک پروژه کتابخانه angular کامپوننت یا سرویسی است که می‌تواند به صورت یک بسته npm منتشر شود. این پروژه‌ها خود به تنهایی اجرا نمی‌شوند و در angular application های دیگر استفاده می‌شوند. برای ساخت یک پروژه کتابخانه جدید، در ابتدا وارد مسیر workspace خود شوید، و سپس از دستور زیر استفاده کنید:ng generate library &lt;project-name&gt;با این کار شما یک پروژه در workspace خود ایجاد کرده‌اید که شامل یک ماژول انگولاری با یک کامپوننت و یک سرویس است.اگر قصد انتشار بسته خود را دارید، باید به این نکته توجه کنید که نام بسته باید در npm registry یکتا باشد. پس باید قبل از نام گذاری بررسی کنید که نام کتابخانه شما از قبل در npm registry ثبت نشده باشد.در پروژه ایجاد شده، یک کامپوننت و یک سرویس هم ایجاد شده است. اگر شما فقط به کامپوننت آن نیاز دارید، می‌توانید service و فایل‌های وابسته به آن را حذف کنید.حذف فایل projects/&lt;project-name&gt;/src/lib/&lt;project-name&gt;.service.tsحذف فایل projects/&lt;project-name&gt;/src/lib/&lt;project-name&gt;.service.spec.tsبروزرسانی فایل projects/&lt;project-name&gt;/src/public-api.tsحال می‌توانید کتابخانه خود را در فایل کامپوننت بنویسید. اگر به فایل کامپوننت توجه کنید، مشاهده می کنید که template خود را باید مستقیم در خود فایل typescript بنویسید. اما اگر مانند application ها نیاز دارید که یک فایل مستقل برای template داشته باشید، می‌توانید همانند کامپوننت‌های application عمل کنید. به این صورت که در مسیر فایل کامپوننت یک فایل با نام &lt;project-name&gt;.htmlبسازید. و سپس به صورت زیر در فایل typescript جایگذاری کنید.@Component(
  selector: &#039;lib-apple&#039;,
  templateUrl: &#039;./&lt;project-name&gt;.html&#039;,
  styles: []
})کامپوننت خود را build کنیددستور زیر را اجرا کنید، تا کامپوننت شما build شود.ng build &lt;project-name&gt; --prodفایل های خروجی در پوشه‌ای در مسیر زیر ساخته می شوند.dist/&lt;project-name&gt;انتشار کامپوننت angular در npmدر ترمینال خود دستور npm login را وارد کنید تا اعتبارسنجی شما انجام شود. سپس با دستور زیر به مسیر فایل خروجی رویدcd dist/&lt;project-name&gt;و در این مسیر دستور npm publish را اجرا کنید، تا کامپوننت شما منتشر شود. به همین راحتی شما اولین کتابخانه خود را در npm منتشر کردید. حال برای اینکه کتابخانه خود را مشاهده کنید، به مسیر زیر بروید.https://www.npmjs.com/package/&lt;project-name&gt;همچنین می‌توانید دستور زیر را در ترمینال وارد کنید، تا همه اطلاعات بسته خود را مشاهده کنید.npm info &lt;project-name&gt;اگر در برنامه خود تغییراتی ایجاد کردید، و سپس دوباره می خواهید که این تغییرات شما در بسته منتشر شده اعمال شود، باید در ابتدا ورژن بسته خود را ارتقا دهید و سپس عمل انتشار را انجام دهید. برای این کار به فایل package.json در مسیر کتابخانه مراجعه کنید و مقدار فیلد version را تغییر دهید و سپس دستور publish را دوباره اجرا کنید.{  &amp;quotname&amp;quot: &amp;quot&lt;package-name&gt;&amp;quot,
  &amp;quotversion&amp;quot: &amp;quot0.0.1&amp;quot,                  &lt;-- here
  &amp;quotpeerDependencies&amp;quot: {
      &amp;quot@angular/core&amp;quot: &amp;quot^11.2.14&amp;quot
  },
  &amp;quotdependencies&amp;quot: {
    &amp;quottslib&amp;quot: &amp;quot^2.0.0&amp;quot
  }
}اضافه کردن کاربر به پروژه خوداگر می‌خواهید که کاربران دیگری هم به بسته منتشر شده خود اضافه کنید، به این معنی که در قسمت Collaborators نام کاربر دیگری هم نمایش دهد، در ابتدا کاربر مورد نظر باید در npmjs نام کاربری داشته باشد. سپس با استفاده از دستور زیر می‌توانید این کار را انجام دهید.npm owner add &lt;user&gt; &lt;your-package-name&gt;وابستگی‌های کتابخانه شماممکن است کتابخانه‌ای که شما نوشته‌اید دارای وابستگی هایی باشد. به این معنی که برای اجرا خود نیاز به کتابخانه‌های خارجی دیگری دارد. برای اینکه کاربر هنگام نصب کتابخانه شما بتواند از آن استفاده کند، نیاز دارد که از قبل این کتابخانه‌های وابسته را نصب کند. اما شما می‌توانید در برنامه مشخص کنید که این نیازمندی ها چیست و هنگام نصب کتابخانه شما همه این نیازمندی‌ها خودشان نصب می‌شوند.برای مثال می‌خواهید از bootstrap در کتابخانه خود استفاده کنید. برای این کار bootstrap را در بخش peerDependencies در my-workspace/projects/my-lib/package.json اضافه کنید.&amp;quotpeerDependencies&amp;quot: {
     ...
     &amp;quotbootstrap&amp;quot: &amp;quot^5.0.1&amp;quot,
     ...
 }      با این کار هنگام نصب کتابخانه شما، bootstrap هم نصب می‌شود. سپس یک فایل scss. ایجاد کنید، و کد زیر را در بالای فایل اضافه کنید.@import &amp;quotnode_modules/bootstrap/scss/bootstrap&amp;quotاضافه کردن فایل readme اگر به صفحه اول کتابخانه خود در سایت npmjs.com نگاه کنید، مشاهده می‌کنید که می‌توانید توضیحاتی را به کتابخانه خود اضافه کنید، تا کاربران راحت تر بتوانند از کتابخانه شما استفاده کنند. در مسیر کتابخانه شما فایلی به نام README.md وجود دارد. هر مطلبی که در این فایل بنویسید در صفحه اول کتابخانه شما نشان داده می‌شود.منابع: https://stackoverflow.com/questions/67876397/how-to-add-bootstrap-in-an-angular-libraryhttps://jasonwatmore.com/post/2020/06/16/angular-npm-how-to-publish-an-angular-component-to-npmhttps://docs.npmjs.com/adding-collaborators-to-private-packages-owned-by-a-user-account</description>
                <category>Ali</category>
                <author>Ali</author>
                <pubDate>Sat, 09 Oct 2021 14:30:02 +0330</pubDate>
            </item>
                    <item>
                <title>کتابخانه Select2-Aurora راهکاری جدید در پیاده سازی select در انگولار</title>
                <link>https://virgool.io/aurorabook/select2-aurora-dkdqbcfe3waf</link>
                <description>کتابخانه select-2-aurora یک پیاده سازی جدید از فرم کنترل select می‌باشد. در این کتابخانه همانند قبل می‌توانید لیست option های خود را اضافه کنید. با این تفاوت که این بار امکان جستجو در لیست option ها را هم دارید. یکی از امکانات جالب این کتابخانه دریافت داده ها از API می‌باشد. به این صورت که کافی است آدرس API خود را به ورودی دهید، سپس خود کنترل، داده ها را از API دریافت و نمایش می‌دهد.در زیر یک نمایش demo از کامپوننت را مشاهده می کنید:پیش نمایشی از کنترل select2-auroraروش نصب و استفادهبرای نصب آخرین نسخه می‌توانید از دستور زیر استفاده کنید:npm i select2-aurora@latestدر صورتی که بخواهید نسخه بخصوصی را نصب کنید، می توانید از دستور زیر استفاده کنید:npm i select2-aurora@1.0.0بعد از نصب کتابخانه، باید Select2AuroraModule را به ماژول مورد نظر خودتان اضافه کنید. در اینجا به app.modules.ts اضافه کرده ایم.import { NgModule } from &#039;@angular/core&#039;;
import { BrowserModule } from &#039;@angular/platform-browser&#039;;
import { Select2AuroraModule } from &#039;select2-aurora&#039;;       // &lt;-- here

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    Select2AuroraModule     // &lt;-- here
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }طریقه استفاده از کتابخانه با استفاده از خصوصیت optionList کتابخانه select2-aurora خصوصیتی به نام optionList دارد. optionList لیستی از اشیایی از نوع AuroraSelectModel می‌باشد. برای تعریف optionList در ابتدا کلاس AuroraSelectModel را به کامپوننت خود import کنید. سپس همانند مثال زیر لیست option های خود را بسازید.import { AuroraSelectModel } from &#039;select2-aurora&#039;;

@Component({
  selector: &#039;app-root&#039;,
  templateUrl: &#039;./app.component.html&#039;,
  styleUrls: [&#039;./app.component.css&#039;]
})

export class AppComponent implements OnInit {
  countriesList: Array&lt;AuroraSelectModel&gt; = new Array&lt;AuroraSelectModel&gt;();

  ngOnInit()
  {
    this.initOptionList();
  }

  initOptionList()
  {
    this.countriesList = new Array&lt;AuroraSelectModel&gt;();
    this.countriesList.push(new AuroraSelectModel(1, &#039;Austria&#039;));
    this.countriesList.push(new AuroraSelectModel(2, &#039;Belgium&#039;));
    this.countriesList.push(new AuroraSelectModel(3, &#039;Finland&#039;));
    this.countriesList.push(new AuroraSelectModel(4, &#039;France&#039;));
    this.countriesList.push(new AuroraSelectModel(5, &#039;Germany&#039;));
    this.countriesList.push(new AuroraSelectModel(6, &#039;Spain&#039;));
    this.countriesList.push(new AuroraSelectModel(7, &#039;Portugal&#039;));
  }
}سپس select2-aurora را در template تعریف کنید:‍‍&lt;select2-aurora  [optionList]=&amp;quotcountriesList&amp;quot &gt;
&lt;/select2-aurora&gt;طریقه استفاده select2-aurora در یک فرمهمانند فرم کنترلر های معمولی، از select2-aurora هم می‌توان به عنوان یک فرم کنترلر استفاده کرد. در زیر یک مثال از این نوع کاربرد بیان شده است.import { FormControl, FormGroup, FormBuilder } from &#039;@angular/forms&#039;;
import { AuroraSelectModel } from &#039;select2-aurora&#039;;

export class AppComponent implements OnInit {
  countriesList: Array&lt;AuroraSelectModel&gt; = new Array&lt;AuroraSelectModel&gt;();  
  formGroup: FormGroup;

  constructor(private formBuilder: FormBuilder)
  {}

  ngOnInit()
  {
    this.initOptionList();
    this.createForm();
  }

  createForm()
  {
    this.formGroup = this.formBuilder.group({
      countryFC: new FormControl()
    });
  }

  initOptionList()
  {
    // as previous example
  }

  onSaveForm()
  {
    console.log(this.formGroup.value);
  }
}حتی اگر optionList خود را مقداردهی کرده باشید، می‌توانید به فرم کنترل مقدار پیش فرض هم بدهید.this.formGroup = this.formBuilder.group({
  countryFC: new FormControl(2)
});سپس در template از آن به صورت زیر استفاده کنید:&lt;form [formGroup]=&amp;quotformGroup&amp;quot (ngSubmit)=&amp;quotonSaveForm()&amp;quot&gt;
  &lt;span&gt;Countries:&lt;/span&gt;
  &lt;select2-aurora
    formControlName=&amp;quotcountryFC&amp;quot
    [optionList]=&amp;quotcountriesList&amp;quot
  &gt;
  &lt;/select2-aurora&gt;
  &lt;br&gt;

  &lt;button type=&amp;quotsubmit&amp;quot name=&amp;quotbutton&amp;quot&gt;Save&lt;/button&gt;
&lt;/form&gt;سرویس API همان طور که قبلا ذکر شد، شما می‌توانید optionList خود را با استفاده از یک سرویس API مقداردهی کنید. بدین منظور، کافی است که یک API بنویسید که در پاسخ لیستی از JSON ها با دو خصوصیت id و label را دارا باشد.apiUrl = &#039;http://127.0.0.1:8000/view1/&#039;;

&lt;select2-aurora
  formControlName=&amp;quotcountryFC&amp;quot
  [apiUrl]=&amp;quotapiUrl&amp;quot
&gt;
&lt;/select2-aurora&gt;اگر API نیاز به توکن JWT داشته باشد، می‌توانید آن را به select2-aurora به عنوان ورودی پاس دهید.apiUrl = &#039;http://127.0.0.1:8000/view1/&#039;;
jwtToken = &#039;dfsdfe3423i4jfhsdjnvsjhr3h4j23h4j23h4j232j4&#039;;&lt;select2-aurora
  formControlName=&amp;quotcountryFC&amp;quot
  [apiUrl]=&amp;quotapiUrl&amp;quot
  [jwtToken]=&amp;quotjwtToken&amp;quot
&gt;
&lt;/select2-aurora&gt;به این نکته توجه کنید که اگر همزمان هم از optionList و هم از apiUrl استفاده کنید، کتابخانه فقط apiUrl را در نظر می گیرد.کتابخانه select2-aurora یک پروژه متن باز می‌باشد، که هنوز در ابتدای کار توسعه است. شما می‌توانید از طریق لینک زیر به کتابخانه دسترسی داشته باشید و با حفظ ذکر منبع، آن را برای خود شخصی سازی کنید. https://github.com/mohammadali66/aurora/tree/master/projects/select2-aurora </description>
                <category>Ali</category>
                <author>Ali</author>
                <pubDate>Sun, 30 May 2021 21:21:52 +0430</pubDate>
            </item>
            </channel>
</rss>