متدها و اعضای کلاس‌ها در C#

معرفی مفاهیم virtual, override, abstract‌ و sealed در #C :

همانطور که مستحضر هستید کلمه‌ی Polymorphism به معنای چندریختی است. در برنامه‌نویسی شیءگرا پلی مورفیسم اغلب به عنوان یک تغییردهنده رفتار یا یک واسط چند متدی مطرح می‌شود.

در زبان برنامه‌نویسی #C پلی مورفیسم به سه شکل ممکن پیاده‌سازی می‌شود:

1- استفاده از متدهای virtual و override کردن آنها در کلاس فرزند

2- بهره‌گیری از متدهای abstract در کلاس والد

3- بهره‌گیری از قابلیت واسط‌ها یا Interfaceها ( واسط‌ها در فصول بعدی به تفصیل توضیح داده خواهند شد)

متدهای virtual

فرض کنید یک کلاس والد به نام Shape دارید که در آن متدی به نام Draw تعریف شده است. متد Draw وظیفه‌ی ترسیم یک شیء یا شکل را به عهده دارد. این متد در تمام کلاس‌هایی که از این کلاس مشتق می‌شوند قابل استفاده است. بنابراین کلاس Shape را به صورت زیر می‌نویسم:

حال باید کلاس‌های فرزند مرتبط با این کلاس را تعریف کنیم بنابراین سه کلاس به نام‌های Triangle و Rectangle و Circle را تعریف می‌کنیم که هر سه از کلاس والد یعنی Shape مشتق شده اند:

هر سه کلاسی که در فوق تعریف کردیم می‌توانند از متد Draw استفاده کنند زیرا این متد در کلاس اصلی والد تعریف شده است. حال اگر شیءای بسازیم آنگاه:

در نهایت خروجی دستورات به صورت زیر است:

اما این خروجی مورد پسند نیست و باید برای هر کلاس یک شکل کشیده شود در نهایت برای رفع این مشکل متد موجود در کلاس والد را به صورت virtual تعریف کرده و آن را درون کلاس فرزند override می‌کنیم. بنابراین تغییراتی در کلاس والد داده و متد Draw را به صورت زیر تعریف می‌کنیم:

حال همین تغییرات را درون کلاس‌های فرزند انجام می‌دهیم:

حال خروجی دستورات فوق به صورت زیر اصلاح می‌شوند:

همچنین اگر از کلمه‌ی کلیدی base درون متد کلاس فرزند استفاده کنیم محتوا و متد کلاس پایه نمایش داده خواهد شد:

استفاده از روش virtual و override‌ تنها به متدها ختم نمی‌شود بلکه می‌توان برای خصوصیات یا Property ها نیز این کار را انجام داد:

معرفی کلاس‌ها و متدهای abstract و sealed

هنگامیکه یک برنامه را می‌نویسیم و کلاس‌ها و اعضای آن را مشخص می‌کنیم باید برای استفاده از کلاس‌ها یک سری محدودیت بگذاریم. مثلا یک کلاس پایه داریم که این کلاس نباید توسط سایر کلاس ها مورد استفاده قرار بگیرد و تنها اعضای آن کلاس و کلاس هایی که از آن به ارث برده‌اند، توانایی دسترسی به متدها و اعضای آن را دارند یا مثلا کلاسی را ایجاد کرده‌ایم که با اعمال محدودیت‌هایی اجاره ایجاد کلاس فرزند از آن را نمی‌دهیم. برای اعمال همچین محدودیت‌هایی از کلاس‌ها یا متدهایی با فرم abstract یا sealed استفاده می‌شود.

کلاس‌ها و اعضاء abstract

به مثال قبلی باز می‌گردیم که یک کلاس والد به نام Shape داشتیم و از روی این کلاس سه فرزند ساخته بودیم:

اگر به مثال بالا مراجعه کنید متوجه می‌شوید که کلاس Shape عملا برای ما کاربردی ندارد. به عبارت دیگر در طول برنامه‌ی اصلی از آن استفاده نشده است. یعنی باید محدودیتی اعمال کنیم که از روی کلاس Shape شیء‌ای ایجاد نشود. برای اینکار کافیست کلاس Shape را از نوع abstract تعریف کنیم. بنابراین طی یک تعریف کلی برای abstract‌ داریم:

اگر کلاسی به صورت abstract ایجاد شود، در طول برنامه نمی‌توان از روی آن شیءای ساخت.

به مثال زیر توجه کنید:

حال اگر بخواهیم از روی کلاس Shape یک شیء ایجاد کنیم با خطای زیر مواجه می‌شویم:

یعنی نمی‌توان از روی کلاس‌هایی که به صورت abstract‌ تعریف شده‌اند شیءای ایجاد کرد.

اما کاربردهای بیشتری از کلاس abstract انتظار می‌رود. در کلاس‌های abstract‌ می‌توان به طور مشابه متدهایی را تعریف کرد که به صورت abstract‌ باشند. این متدها تنها شامل signature هستند یعنی بدنه‌ای نداشته و پس از تعریف آنها به علامت ; ختم می‌شوند.  درصورتیکه یک متد به صورت abstract تعریف شود بدین گونه است که حتما باید آن را جهت استفاده در طی برنامه یا کلاس دیگر override کنند. برای مثال یکبار دیگر کلاس Shape‌ را بازنویسی می‌کنیم:

همانطور که ملاحظه می‌کنید متدی به نام Draw‌ وجود دارد که بدنه‌ای ندارد. علت این امر تعریف این متد به صورت abstract است. حال اگر کلاس فرزندی از کلاس Draw به ارث ببرد باید همواره متد درون آن به صورت abstract قرار بگیرد. بنابراین داریم:

کلاس‌ها و اعضاء sealed

در بخش وراثت آموزش دادیم که همواره می‌توان یک زنجیره‌ی وراثت در اختیار داشت مثلا کلاس B از کلاس A و کلاس C از کلاس B مشتق شود. حال درنظر بگیرید که می‌خواهیم به نحوی این زنجیره‌ی وراثت را قطع کنیم. برای اینکار باید کلاس موردنظر را از نوع sealed تعریف کنیم. بنابراین در طی یک تعریف کلی داریم:

کلاس‌هایی که به صورت sealed مورد استفاده قرار می‌گیرند، باعث حذف زنجیره وراثت می‌شوند.

به مثال زیر توجه کنید:

در این کد کلاس B‌ از نوع sealed تعریف شده است و این موضوع بدین معناست که هیچ کلاس دیگری نمی‌تواند از کلاس B مشتق شود و یا متدها و ویژگی‌هایی را به ارث ببرد. به عنوان مثال اگر کد زیر را پیاده سازی کنیم:

آنگاه با خطای زیر روبه‌رو می‌شویم:

بدین معنی‌ست که شما نمی‌توانید از یک کلاس که به صورت sealed‌ تعریف شده است ویژگی یا متدی را به ارث ببرید.

یکی دیگر از کاربردهای عبارت sealed جلوگیری از override کردن یک متد است. به مثال زیر توجه کنید:

این مثال بدین صورت عمل می‌کند که اگر کلاسی از کلاس Rectangle مشتق شد، دیگر قابلیت override کردن متد Draw را نداشته باشد زیر در متد موجود در کلاس Rectangle، متد به صورت sealed تعریف شده است.

فرق Class و Struct در #C :

Struct در سی شارپ یک جایگزین سبک حجم برای کلاس ها هستند. پس زمانی که می خواهیم نسخه های زیادی از یک داده را مقداردهی کنیم از Struct در سی شارپ استفاده می کنیم. تو این قسمت در مورد مفهوم Struct حرف بزنیم و این که Struct چه فرقی با Class دارد، برای ایجاد Struct ابتدا یک Class اضافه می کنیم

بعد از ایجاد کلاس نام کلیدی کلاس را پاک می کنیم و می توانیم نامی که برای کلاسمان در نظر گرفتیم هم پاک کنیم و نام دلخواه خودمان بگذاریم.

و مثل کلاس می توانیم فیلد و تابع داشته باشیم:

داخل پنجره فرم شده و از Struct نمونه می سازیم:

سوال : اگر Struct تمام قابلیت های Class را دارد و هر دو مساوی هستند چرا هر دو را داخل زبان سی شارپ گذاشتند؟

این دو تا یک تفاوت هایی با هم دارند که الان با هم بررسی می کنیم:

در Struct لازم نیست برای ایجاد شی جدید از دستور new استفاده کنیم، می توانم مثل متغیر ساده int آن را تعریف کنم و بعد به آن مقدار بدهیم:

فیلدها را در struct نمی توان مقدار دهی کرد. پس اینجا را خوب دقت کنید تا به id مقدار ندهیم ، فضایی داخل حافظه به آن اختصاص نمی دهد.

الان یک کلاس هم می نویسیم بالای Struct تا با هم مقایسه کنیم:

خوب دقت کنید class از نوع Reference Type است اما Struct  از نوع Value Type است .

یعنی اگر من دو تا کلاس داشته باشم داخل یکی از آنها تغییر اعمال کنم داخل آن یکی کلاس هم اعمال می شود. با یک مثال بیشتر متوجه می شویم:

داخل پنجره فرم شده تا با نوشتن یک کد تفاوت class و Struct در سی شارپ را بفهمیم:

برنامه را اجرا می کنیم و روی button1 کلیک می کنیم انتظار می رود عدد 10 را نمایش دهد.

Class Struct

امّا مشاهده می کنیم که عدد 20 را نمایش می دهد چون class رفرنسی است یعنی می رود به آدرسش نگاه می کند و چون خاصیت ارث بری هم دارد مقدار خودش را به آدرسش می دهد .

این بار برنامه را اجرا می کنیم و روی button2 کلیک می کنیم تا کد Struct اجرا شود:

Class Struct

مشاهده می کنیدکه عدد 10 را نمایش می دهد چون Struct از نوع Value تایپ است یعنی در Struct هر کدام مقدار خودشان را نمایش می دهند.

تفاوت Struct و class

1- در class به محض ساخته شدن شی فضایی به آن اختصاص داده می شود ولی در Struct حتی با وجود ساخته شدن شی فضایی به آن اختصاص داده نمی شود تا زمانی که مقداری داخل آن فیلد قرار گیرد.

2- در Struct لازم نیست که برای شی از کلمه ی new استفاده شود.

3- class رفرنس تایپ است اما value , Struct تایپ است در نتیجه چون کلاس از فیلد رفرنس استفاده می کند بنابراین حافظه بیشتری اشغال می کند. ولی Struct چون از فیلد رفرنس استفاده نمی کند حافظه کمتری اشغال می کند .

4- کلاس می تواند وراثت داشته باشد امّا Struct نمی تواند وراثت داشته باشد .

5- Struct نمی تواند تابع مخرب داشته باشد.

شباهت Struct و class

هر دو می توانند تابع سازنده داشته باشند.( البته خود Struct دارای تابع سازنده پیش فرض می باشد ولی اگر برای آن یک تابع سازنده تعریف کردیم باید تمام فیلدها را در آن مقداردهی اولیه کنیم. و تابع سازنده در Struct باید حداقل یک پارامتر داشته باشد.)

قوانین پنج گانه SOLID

  • Single Responsibility Principle (اصل مسئولیت واحد) :

هرکلاسی فقط باید یه کار انجام بده و فقط باید به یه دلیل تغییر کنه

  • Open-Closed Principle (اصل باز و بسته) :

اگر من یه روزی بخوام ویژگی جدیدی به کلاسم اضافه کنم بتونم خیلی راحت و بدون دستکاری کد اصلی این کار رو انجام بدم.

در واقع مفهومش استفاده از Interface و Implement کردن در کلاس های دیگه که قرار دستخوش تغییر بشن

  • Liskov Substitution Principle (اصل جایگزینی لیسکوف) :

یعنی اگر کلاس A داشتیم و خواستیم بعد مدتی گسترشش بدیم و ی سری ویژگی ها بهش اضافه کنیم،پس باید ی کلاس دیگه بسازیم به اسم B که از کلاس A رو اکستند (extend) کنه (کلاس B ارث بری کنه از A)  باید این قدر جامع باشه که هر رفتاری که کلاس B انجام میدهد از کلاس A مشتق شده باشد

  • Interface Segregation Principle (اصل تفکیک رابط) :

کلاس ها نباید مجبور باشن متد هایی که به آن ها احتیاج ندارند رو پیاده سازی کنند ، مثلا اگر دو کلاس از یک Interface پیروی میکنند که در اون متدی وجود دارد که نیازی به یکی از آن ها را ندارد پس نباید از آن ارث بری کند و باید یک Interface جدا براش در نظر گرفته شود.

  • Dependency Inversion Principle (اصل تفکیک رابط) :

کلاس ها ی سطح بالا نباید به کلاس های پایین دسترسی داشته باشند.

اصول SOLID مجموعه‌ای از پنج قانون طراحی شی‌گرا هستند که به توسعه‌دهندگان کمک می‌کنند تا کدهای خود را با کیفیت بالاتری بنویسند. در اینجا این پنج اصل را با توضیحات و مثال‌های کد C# توضیح می‌دهیم:

1. Single Responsibility Principle (SRP)

Single Responsibility در قوانین SOILD

هر کلاس فقط باید یک مسئولیت داشته باشد و این مسئولیت کاملاً مشخص باشد.

مثال:

در این مثال، کلاس Employee فقط مسئول اطلاعات و عملیات مربوط به کارمند است و کلاس EmployeeRepository مسئول ذخیره‌سازی کارمند است.

2. Open/Closed Principle (OCP)

Open/Close در قوانین SOLID

کلاس‌ها باید برای توسعه باز و برای تغییر بسته باشند. به عبارت دیگر، باید بتوانیم کلاس‌ها را بدون تغییر در کد موجود توسعه دهیم.

مثال:

در این مثال، کلاس Employee برای اضافه کردن نوع‌های جدید از کارمندان باز است، اما نیازی به تغییر در کلاس‌های موجود ندارد.

3. Liskov Substitution Principle (LSP)

Liskov در قوانین SOLID

کلاس‌های مشتق باید بتوانند جایگزین کلاس‌های پایه خود شوند بدون اینکه رفتار برنامه تغییر کند.

مثال:

در این مثال، می‌توانیم از هر کلاس مشتق شده از Shape استفاده کنیم و متد Area بدون مشکل کار خواهد کرد.

4. Interface Segregation Principle (ISP)

اصل جدا سازی اینترفیس ها در قوانین  SOLID

کلاس‌ها نباید مجبور به پیاده‌سازی اینترفیس‌هایی باشند که از آن‌ها استفاده نمی‌کنند. اینترفیس‌ها باید کوچک و ویژه باشند.

مثال:

در این مثال، کلاس Robot فقط نیاز به پیاده‌سازی متد Work دارد و نیازی به پیاده‌سازی متدهای غیرضروری ندارد.

5. Dependency Inversion Principle (DIP)

اصل Dependency Inversion

ماژول‌های سطح بالا نباید به ماژول‌های سطح پایین وابسته باشند. هر دو باید به انتزاع‌ها وابسته باشند. انتزاع‌ها نباید به جزئیات وابسته باشند، بلکه جزئیات باید به انتزاع‌ها وابسته باشند.

مثال:

در این مثال، کلاس Notification به کلاس‌های سطح پایین (مانند EmailSender) وابسته نیست، بلکه به اینترفیس IMessageSender وابسته است. این باعث می‌شود تا به راحتی بتوان کلاس‌های جدید برای ارسال پیام ایجاد کرد و از آن‌ها استفاده کرد بدون نیاز به تغییر در کلاس Notification.

OOP (object oriented programming)

OOP (object oriented programming)

Abstraction

زمانی که تصمیم داریم برنامه ای را به صورت شئ گرا بنویسیم، باید شروع به تحلیل سیستم و شناسایی موجودیت های آن کنیم. در بالا مثالی را در مورد برنامه کتابخانه بررسی کردیم. شئ عضو را در نظر بگیرید، شاید این عضو خصوصیت های بسیاری داشته باشد، مانند رنگ چشم، رنگ مو، قد، وزن، رنگ پوست و … . اما آیا تمامی این خصوصیات در سیستم به کار می آید؟ در مورد رفتارهای یک شئ نیز همین موضوع صدق می کند. مفهوم Abstraction به ما می گوید زمان بررسی یک موجودیت، تنها خصوصیات و رفتارهایی باید در تعریف موجودیت لحاظ شوند که مستقیماً در سیستم کاربرد دارند. در حقیقت Abstraction مانند فیلتری عمل می کنند که تنها خصوصیات و رفتارهای مورد استفاده در برنامه ای که قصد نوشتن آن را داریم از آن عبور می کنند.

Encapsulation

فرض کنید ماشین جدیدی خریداری کرده اید، پشت فرمان ماشین می نشینید و ماشین را استارت می زنید. استارت زدن ماشین خیلی ساده است، قرار دادن سوئیچ و چرخاندن آن و روشن شدن ماشین. اما آیا پروسه ای که داخل ماشین طی شده برای روشن شدن نیز همینقدر ساده است؟ صد در صد، عملیات های بسیار دیگری اتفاق می افتد تا ماشین روشن شود. اما شما تنها سوئیچ را چرخانده و ماشین را روشن میکنید. در حقیقت پیچیدگی عملیات روشن شدن ماشین از راننده ماشین پنهان شده است. به این عملیات Encapsulation یا پنهان سازی پیچیدگی پیاده سازی عملیات های درون یک شئ می گویند.

Inheritance

می توان گفت Inheritance یا وراثت اصلی ترین مفهوم در برنامه نویسی شئ گرا است. زمانی که شما خوب این مفهوم را درک کنید ۷۰ درصد از مفاهیم برنامه نویسی شئ گرا را درک کرده اید. برای درک بهتر این مفهوم مثالی میزنیم. تمامی انسان های متولد شده بر روی کره خاکی از یک پدر و مادر متولد شده اند. در حقیقت این پدر و مادر والدین انسان هستند. زمانی که انسانی متولد می شود یکسری خصوصیات و ویژگی ها را از والدین خود به ارث می برد، مانند رنگ چشم، رنگ پوست یا برخی ویژگی های رفتاری. در برنامه نویسی شئ گرا نیز به همین صورت می باشد. زمانی که شما موجودیت را طراحی می کنید، می توانید برای آن یک کلاس Base یا والد در نظر بگیرید که شئ فرزند تمامی خصوصیات و رفتارهای شئ والد را به ارث خواهد برد. مهمترین ویژگی وراثت، استفاده مجدد از کدهای نوشته شده است که حجم کدهای نوشته شده را به صورت محسوسی کاهش می دهد.

Polymorphism

در فرهنگ لغت این واژه به معنای چند ریختی ترجمه شده است. اما در برنامه نویسی شئ گرا چطور؟ خیلی از افراد با این مفهوم مشکل دارند و درک صحیحی از آن پیدا نمی کنند. مفهوم Polymorphism رابطه مستقیمی با Inheritance دارد. یعنی شما ابتدا نیاز دارید مفهوم وراثت را خوب درک کرده و سپس به یادگیری Polymorphism بپردازید. باز هم برای درک مفهوم Polymorphism یک مثال از دنیای واقعی میزنیم. در کره خاکی ما انسان های مختلفی در کشور های مختلف و شهر های مختلف با گویش های مختلف زندگی می کنند. اما تمامی این ها انسان هستند. در اینجا انسان را به عنوان یک شئ والد و انسان چینی، انسان ایرانی و انسان آمریکایی را به عنوان اشیاء فرزند که از شئ انسان مشتق شده اند یا والد آنها کلاس انسان می باشد را در نظر بگیرید. کلاس انسان رفتاری را تعریف می کند به نام صحبت کردن. اما اشیاء فرزند آن، به یک صورت صحبت نمی کنند، انسان ایرانی با زبان ایرانی، چینی با زبان چینی و آمریکایی با زبان آمریکایی صحبت می کند. در حقیقت رفتاری که در شئ والد تعریف شده، در شئ های فرزند مجدد تعریف می شود یا رفتار آن تغییر می کند. این کار مفهوم مستقیم Polymorphism می باشد. در زبان های برنامه نویسی شئ گرا، Polymorphism به تغییر رفتار یک شئ در اشیاء فرزند آن گفته می شود. در زبان سی شارپ این کار با کمک تعریف متدها به صورت virtual و override کردن آنها در کلاس های فرزند انجام می شود. همچنین Polymorphism با کمک Interface ها قابل پیاده سازی است

ساخت پروژه با معماری Clean Architecture و پیاده سازیDDD(Domain-Driven Design)

راه اندازی Clean Architecture و پیاده سازی DDD ، دو اقدام اساسی هستند که با کمک آن‌ها، یک سیستم ساختارمند و قدرتمند حاصل می‌شود. در بخش اول این مقاله، به بررسی نحوه راه اندازی Clean Architecture و لایه‌های مختلف آن می‌پردازیم و پس از آن، به سراغ پیاده‌سازی Domain Driven Design می‌رویم. درنهایت، به شما روشی را معرفی می‌کنیم که با کمک آن می‌توانید از صحت معماری پیاده‌سازی‌شده، مطمئن شوید.

DDD (Domain Driven Design)  چیست ؟

 DDD مخفف عبارت Domain-Driven Design است که به معنای “طراحی مبتنی بر دامنه” است. DDD یک رویکرد برای طراحی و توسعه نرم‌افزار است که تاکید بر مدل‌سازی و درک دامنه (domain) کسب‌وکار و ارتباطات آن دارد. این روش توسط اریک ایوانز (Eric Evans) معرفی شد و در کتابی با عنوان “Domain-Driven Design: Tackling Complexity in the Heart of Software”  در سال 2003 به تفصیل توضیح داده شده است.

اصول و مفاهیم کلیدی DDD

  1. دامنه (Domain):
    • دامنه شامل مفاهیم، قوانین، و منطق کسب‌وکاری است که نرم‌افزار باید آن‌ها را پشتیبانی کند. درک کامل دامنه اصلی‌ترین هدف DDD است.
  2. مدل دامنه (Domain Model):
    • مدل دامنه یک نمایش انتزاعی از دامنه است که شامل اشیا، موجودیت‌ها (Entities)، ارزش‌ها (Value Objects)، و سرویس‌های دامنه (Domain Services) است.
  3. موجودیت‌ها (Entities):
    • اشیای دارای هویت متمایز که با گذشت زمان تغییر می‌کنند. هر موجودیت یک شناسه منحصر به فرد دارد.
  4. اشیای ارزش (Value Objects):
    • اشیای بدون هویت که فقط بر اساس ارزش‌هایشان مقایسه می‌شوند. این اشیا باید تغییرناپذیر (Immutable) باشند.
  5. خدمات دامنه (Domain Services):
    • عملیات‌هایی که به یک موجودیت خاص تعلق ندارند ولی به منطق دامنه مربوط می‌شوند.
  6. مجموعه‌ها (Aggregates):
    • گروهی از موجودیت‌ها و اشیای ارزش که به عنوان یک واحد واحد در نظر گرفته می‌شوند. یک موجودیت ریشه‌ای به نام “ریشه‌ی مجموعه” (Aggregate Root) وجود دارد که دسترسی به سایر اعضای مجموعه را کنترل می‌کند.
  7. محدوده‌ی هم‌دست (Bounded Context):
    • یک محدوده مشخص که در آن یک مدل دامنه خاص معتبر است. هر محدوده‌ی هم‌دست می‌تواند یک مدل دامنه متفاوت داشته باشد که نیازهای آن محدوده خاص را برآورده می‌کند.
  8. زبان مشترک (Ubiquitous Language):
    • زبانی که توسط تیم توسعه و متخصصان دامنه استفاده می‌شود تا ارتباطات و مستندات را تسهیل کند. این زبان باید در سراسر پروژه به صورت یکپارچه استفاده شود.

مزایای استفاده از DDD

  • تسهیل درک دامنه:
    • با استفاده از مدل دامنه و زبان مشترک، توسعه‌دهندگان و متخصصان دامنه به راحتی می‌توانند نیازهای کسب‌وکار را درک و مستند کنند.
  • افزایش قابلیت نگه‌داری:
    • کدهای مبتنی بر DDD به دلیل داشتن ساختار واضح و منظم، آسان‌تر نگه‌داری و توسعه می‌یابند.
  • هماهنگی بهتر بین تیم‌ها:
    • با استفاده از محدوده‌های هم‌دست، تیم‌ها می‌توانند به طور مستقل بر روی بخش‌های مختلف دامنه کار کنند بدون اینکه با یکدیگر تداخل داشته باشند.
  • قابلیت توسعه‌پذیری:
    • ساختار مدل دامنه و استفاده از الگوهای طراحی باعث می‌شود که سیستم به راحتی قابل توسعه و تغییر باشد.

نتیجه‌گیری

 DDD یک روش قدرتمند برای طراحی و توسعه نرم‌افزار است که به کمک آن می‌توان سیستم‌هایی پیچیده و بزرگ را با استفاده از مدل‌سازی دقیق دامنه کسب‌وکار و استفاده از اصول و مفاهیم مشخص ساخت. این روش به توسعه‌دهندگان کمک می‌کند تا نرم‌افزارهایی با کیفیت و قابل نگه‌داری بالا بسازند که به خوبی نیازهای کسب‌وکار را برآورده کنند.

Clean Architecture  چیست ؟

Clean Architecture  یا “معماری تمیز” یک الگوی معماری نرم‌افزاری است که توسط رابرت سی. مارتین  (Robert C. Martin)، معروف به  Uncle Bob، معرفی شده است. هدف اصلی این معماری جداسازی نگرانی‌ها (Separation of Concerns) و ایجاد سیستم‌های نرم‌افزاری با ساختاری منعطف، قابل نگه‌داری، و قابل تست است. معماری تمیز به توسعه‌دهندگان کمک می‌کند تا نرم‌افزارهایی بسازند که به راحتی قابل تغییر و توسعه باشند و وابستگی‌ها به حداقل برسند.

اصول و مفاهیم کلیدی Clean Architecture

لایه‌های معماری:

Clean Architecture  سیستم را به چندین لایه تقسیم می‌کند که هر کدام مسئولیت‌های خاص خود را دارند. این لایه‌ها شامل موارد زیر هستند:

Entities :  شامل موجودیت‌های دامنه و منطق اصلی کسب‌وکار. این لایه کاملاً مستقل از سایر لایه‌ها است و می‌تواند در هر پروژه‌ای استفاده شود.

Use Cases  : شامل منطق کاربردی سیستم است. این لایه از موجودیت‌ها استفاده می‌کند و مسئول اجرای عملیات‌های کسب‌وکار است.

Interface Adapters :  شامل کدهایی است که ورودی و خروجی سیستم را به فرمت قابل فهم برای Use Cases و Entities تبدیل می‌کند. این لایه شامل کنترلرها، پریزنتیشن، و مبدل‌های داده است.

Frameworks and Drivers :  شامل کدهای زیرساختی و جزئیات پیاده‌سازی است که وابسته به فریم‌ورک‌ها و ابزارهای خاص هستند. این لایه شامل پایگاه‌داده، رابط‌های کاربری، و سایر سیستم‌های خارجی است.

Dependency Rule ( قاعده وابستگی):

در Clean Architecture، وابستگی‌ها باید از لایه‌های بیرونی به سمت لایه‌های درونی باشد و لایه‌های درونی نباید هیچ وابستگی به لایه‌های بیرونی داشته باشند. این اصل باعث می‌شود که منطق اصلی سیستم به جزئیات پیاده‌سازی وابسته نباشد و قابل تست و نگه‌داری باشد.

جداسازی نگرانی‌ها (Separation of Concerns):

با تقسیم سیستم به لایه‌های مختلف، هر لایه مسئول یک جنبه خاص از سیستم است. این جداسازی باعث می‌شود که تغییرات در یک بخش سیستم تأثیری بر بخش‌های دیگر نداشته باشد.

تست‌پذیری (Testability):

با جدا کردن منطق کسب‌وکار از جزئیات پیاده‌سازی، تست واحد و تست‌های یکپارچگی ساده‌تر می‌شود. می‌توان به راحتی منطق کسب‌وکار را بدون وابستگی به پایگاه‌داده یا سایر سیستم‌های خارجی تست کرد.

انعطاف‌پذیری (Flexibility):

Clean Architecture امکان تغییر و جایگزینی اجزای مختلف سیستم بدون تأثیر بر سایر اجزا را فراهم می‌کند. این انعطاف‌پذیری باعث می‌شود که سیستم به راحتی قابل توسعه و نگه‌داری باشد.

ساختار کلی Clean Architecture

 Clean Architecture معمولاً به صورت مجموعه‌ای از دایره‌های هم‌مرکز نمایش داده می‌شود که هر دایره نمایانگر یک لایه است:

دایره مرکزی (Entities): شامل موجودیت‌های دامنه و منطق اصلی کسب‌وکار است.

دایره دوم (Use Cases): شامل موارد استفاده و منطق کاربردی است.

دایره سوم (Interface Adapters): شامل مبدل‌ها و کنترلرها است.

دایره خارجی (Frameworks and Drivers): شامل پایگاه‌داده، رابط‌های کاربری، و سایر سیستم‌های خارجی است.

مزایای استفاده از Clean Architecture

افزایش قابلیت نگه‌داری:

به دلیل جداسازی نگرانی‌ها و کاهش وابستگی‌ها، سیستم‌های مبتنی بر Clean Architecture به راحتی قابل نگه‌داری و توسعه هستند.

افزایش تست‌پذیری:

منطق کسب‌وکار مستقل از جزئیات پیاده‌سازی است و می‌توان به راحتی تست‌های واحد و یکپارچگی را انجام داد.

انعطاف‌پذیری و مقیاس‌پذیری:

امکان تغییر و جایگزینی اجزای مختلف سیستم بدون تأثیر بر سایر اجزا فراهم است، که به انعطاف‌پذیری و مقیاس‌پذیری سیستم کمک می‌کند.

ساخت پروژه با معماری Clean Architecture و پیاده سازیDDD(Domain-Driven Design)

مراحل راه اندازی ‌Clean Architecture

منظور از راه اندازی Clean Architecture به معنای واقعی کلمه این است که یک Solution خالی در Visual Studio شروع کرده و به سمت ساختار کامل Clean Architecture پیش بروید.

۱ ایجاد پوشه حاوی پروژه‌ها

برای آغاز راه اندازی Clean Architecture ، ابتدا باید یک پوشه Solution خالی ایجاد کنید که در نهایت حاوی همه پروژه‌های آینده خواهد بود.

ساخت پروژه با معماری Clean Architecture و پیاده سازیDDD(Domain-Driven Design)

۲ ایجاد لایه Domain

شما از هسته معماری Clean Domain نام دارد، روند راه اندازی Clean Architecture را شروع می‌کنید. نامی که برای این لایه درنظر می‌گیرید، می‌تواند Domain یا ترکیبی از نام پروژه و عبارت Domain باشد. شما باید به گونه‌ای لایه‌ها را نام‌گذاری کنید که با نگاهی سریع متوجه کارکرد آن لایه بشوید. داخل Solution ایجاد شده یک پروژه Dot net 8 از نوع Class Library ایجاد می‌کنیم. این پروژه، حاوی کلاسی به اسم  دیفالت ایجاد شده Class1  هست که می‌توانیم آن را پاک کنیم.

آنچه معمولاً در پروژه Domain تعریف می‌کنید، قوانین اصلی مربوط به کسب و کار، Enumerations ،Value Object ها، Custom Exception و چنین مواردی است. توجه کنید که در این آموزش، تمام این موارد انجام نمی‌شوند؛ بلکه تنها روی Setup ساختار پروژه براساس Clean Architecture تمرکز خواهد شد.

ساخت پروژه با معماری Clean Architecture و پیاده سازیDDD(Domain-Driven Design)

۳ساخت لایه Application

لایه بعدی که باید تعریف کنیم Application نام دارد. برای این کار، مجدداً یک پروژه Dot net 8 و از نوع Class Library لازم است. ضمن اینکه لازم است کلاس پیش‌فرض حذف شود. برای درک بهتر نتیجه، به تصویر زیر توجه کنید.

ساخت پروژه با معماری Clean Architecture و پیاده سازیDDD(Domain-Driven Design)

اساساً، لایه Domain مجوز ارجاع داشتن به هیچ کدام از لایه‌های بیرونی را ندارد و این موضوع، یک قانون مهم در معماری Clean محسوب می‌شود. در حالی که لایه Application ، امکان برقراری ارتباط با لایه Domain را دارد. در انتهای مقاله، روشی بررسی می‌شود که چنین قیدهایی را برای ما در نظر بگیرد.

پروژه Application یک Orchestrator از سایر لایه‌ها و Use Case ها تلقی می‌شود. این یعنی در این لایه، ماژول‌های مختلف فراخوانی و مورد استفاده قرار می‌گیرند و هیچ منطقی مرتبط با کسب و کار تعریف نخواهد شد. همچنین، در این لایه می‌توانید Service های گوناگون را فراخوانی و به‌کار ببرید.

معمولاً برای ارتباط بین لایه Entry Point و Application از mediator استفاده می‌شود. Mediator یک Design Pattern است که به‌واسطه آن،  Couple-less بودن لایه‌های مختلف پروژه تضمین خواهد شد. اما چرا باید ماژول‌های مختلف به هم وابستگی نداشته باشند؟ 

فرض کنید روزی تصمیم گرفته شود تا یکی از لایه‌های پروژه، به سرویس دیگری از یک میکروسرویس بزرگ‌تر منتقل شود. در این شرایط، اگر وابستگی‌های زیادی بین دو لایه وجود داشته باشند، جداسازی آن‌ها دشوار است و دیگر نمی‌توانید یک لایه خاص را به میکروسرویس بزرگ‌تر منتقل کنید.

در NET. ، یک NuGet Package  اسم MediatR وجود دارد که در ادامه، آن را نصب و استفاده خواهیم کرد.

dotnet add package MediatR –version 12.1.1

پس از نصب  MediatR، می‌توان Use Case ها را ایجاد کرد. لازم است هر Use Case، به‌عنوان یک کلاس مستقلی پیاده‌سازی شود که از MediatR.RequestHandler<TRequest ,TResponse> ارث‌بری می‌کند. پارامتر TRequest نشان‌دهنده شی درخواستی‌ خاصی است که به Use Case ارسال و پارامتر TResponse نمایان‌گر شی پاسخی است که از Use Case برگردانده می‌شود.

به منظور درک کارایی این پکیج، یک Entry Point یا API ایجاد کرده و طبق آن، یک کاربر را ثبت‌نام خواهیم کرد. منظور از Entry Point یا نقطه ورودی پروژه، جایی‌ است که درخواست‌ها در ابتدا به آن ارسال می‌شوند و سپس، از آن جا به سایر لایه‌ها هدایت خواهند شد. این ورودی می‌تواند یک WebApi یا یک Console Application باشد. در این آموزش، گزینه اول، یعنی WebApi را انتخاب می‌کنیم. 

۴ایجاد لایه Presentation 

لازم است لایه جدیدی به نام Presentation از  .Net 8  و از نوع ASP.Net Core Web Application بسازید.

ساخت پروژه با معماری Clean Architecture و پیاده سازیDDD(Domain-Driven Design)

به منظور نوشتن یک API برای ثبت کاربر، کنترلر (Controller) نیاز است. برای انجام این کار، یک پوشه به نام Controllers بسازید و در داخل آن، کلاسی با نام UserController ایجاد کنید. در ادامه، یک Command ایجاد خواهیم کرد که با کمک آن، مشخصات کاربر جدید دریافت بشوند. سپس، یک کلاس Handler می‌سازیم که این درخواست را پردازش کرده و کاربر جدید را ایجاد کند.

به‌صورت کلی، Command  به فرآیندی گفته می‌شود که طی آن، تغییری در وضعیت سیستم به‌وجود می‌آید. در مقابل، اگر بخواهیم از وضعیت یک سرویس یا سیستم مطلع شویم،Query  استفاده می‌شود. لایه اپلیکیشن جایی هست که Command ها و کوئری‌ها پیاده‌سازی خواهند شد.

در لایه Application، یک پوشه به اسم User ایجاد کنید و در داخل پوشه User، پوشه دیگری به نام Commands بسازید. سپس، لازم است یک کلاس به نام CreateUserCommand ایجاد شود. در تصویر زیر، نتیجه قابل مشاهده است.

ساخت پروژه با معماری Clean Architecture و پیاده سازیDDD(Domain-Driven Design)

هر Command ای که مربوط به کاربر باشد، درون پوشه Commands قرار می‌گیرد. به‌عنوان مثال، حذف یا ویرایش مشخصات کاربر درون این پوشه هستند.

می‌توان پوشه‌بندی‌های مختلفی مطرح کرد. به‌عنوان مثال، یک نوع مرسوم پوشه‌بندی در پروژه‌ها، دارا بودن دو پوشه به نام‌های Commands و Queries است؛ به‌طوری که تمامی تغییرات در پوشه Commands و تمامی درخواست‌ها در پوشه Queries نگهداری شوند. برای درک بهتر، به تصویر زیر توجه کنید.

ساخت پروژه با معماری Clean Architecture و پیاده سازیDDD(Domain-Driven Design)

مشکل این روش این است که اگر تعداد Command ها یا کوئری‌ها بیش از اندازه باشند، احتمالاً امکان پیدا کردن هرکدام آن‌ها، از میان انبوه کلاس‌ها دشوار خواهد بود. بنابراین، می‌توان این روش را در پروژه‌های کوچک استفاده کرد. در ادامه، از روش اول پوشه‌بندی استفاده خواهد شد؛ زیرا این رویکرد، برای پروژه‌های بزرگ کارایی مناسبی دارد.

Convention در نام گذاری Command ها و کوئری ها

در صورتی که بخواهیم یک Command برای ایجاد کاربر داشته باشیم، ابتدای نام مربوطه، تسکی که قرار است انجام دهد یعنی  Create)، سپس نام فیچر (یعنی User) و درنهایت، عبارت (Command آورده می‌شود.

به منظور درک نحوه پیاده‌سازی کلاس CreateUserCommnad، به قطعه کد زیر توجه کنید.

این کلاس از <IRequest<T ارث‌بری می‌کند که یکی از اینترفیس‌های پکیج MediatR است. پارامتر T در آن نمایانگر نوع پاسخ، بعد از ایجاد کاربر است. این شی در اینجا، از نوع Boolean خواهد بود؛ یعنی، زمانی که مقدار آن True باشد، کاربر با موفقیت ثبت شده است. البته می‌توان برای پروژه‌های مختلف مدل‌های گوناگونی ایجاد کرد. در این مثال، برای سادگی در بیان، آن را ‌بولین در نظر گرفته‌ایم.

در مرحله بعدی، یک هندلر تحت عنوان CreateUserCommandHandler ، برای این Command ایجاد می‌کنیم. محل نگهداری این کلاس، داخل پوشه Commands (زیرمجموعه پوشه User) خواهد بود. به Convention ای که برای نام‌گذاری کلاس‌های هندلر استفاده می‌کنیم، دقت کنید. در این Convention، نام Command به‌همراه عبارت Handler در انتها قرار داده شده است. این نوع نام‌گذاری‌ها باعث می‌شوند تا سایر برنامه‌نویسان بدون صرف زمان زیادی، بتوانند کلاس‌های مدنظرشان را پیدا کنند.

ساخت پروژه با معماری Clean Architecture و پیاده سازیDDD(Domain-Driven Design)

در ادامه، قطعه پیاده‌سازی هندلر مربوط به ایجاد کاربر قرار داده شده است.

کلاس CreateUserCommandHandler از <IRequestHandler<TRequest, TResponse ارث‌ بری می‌کند.

توجه کنید که TRequest نمایانگر نوع درخواست، TResponse نمایانگر نوع پاسخ و IRequestHandler یکی از اینترفیس‌های پکیج MediatR محسوب می‌شوند.

در متد Handle، می‌توان کاربر جدید را ایجاد و در دیتابیس مربوط به آن ذخیره کرد. اما در این مرحله، هنوز لایه مربوط به دیتابیس را ایجاد نکرده‌ایم و فقط به بازگرداندن مقدار True اکتفا می‌کنیم. این امکان وجود دارد که به جای مقدار Boolean، یک GUID برگردانیم. GUID، نشان‌دهنده شناسه کاربر در دیتابیس است. 

اکنون در این مرحله، می‌توانیم به منظور ایجاد کاربر، این Handler را در یک کنترلر استفاده کنیم. 

مشابه قطعه‌کد زیر، در لایه Presentation و کنترلر User قرار گرفته و اقدامات لازم برای ایجاد یک کاربر با استفاده از MediatR را لحاظ کنید:

اینترفیس ISender برای پکیج MediatR است و به منظور ارسال درخواست توسط این پکیج به‌کار می‌رود. ضمن اینکه درخواست‌های ارسال‌شده توسط هندلرهای مرتبط با آن، دریافت و پردازش می‌شوند.

در این متد، ما یک درخواست CreateUserCommand را از HTTP دریافت می‌کنیم و آن را به MediatR می‌فرستیم. سپس، MediatR به جستجو برای Handler مناسب می‌پردازد و پس از یافتن آن، متد Handle را فراخوانی می‌کند. پس از ایجاد شدن کاربر جدید توسط هندلر، مقدار True در پاسخ HTTP برگردانده می‌شود.

این فقط یک مثال ابتدایی از نحوه پیاده‌سازی Use Case ها در Clean Architecture است. شما می‌توانید سایر موارد را با الگوبرداری از این روش پیاده‌سازی کنید.

نصب و استفاده از پکیج Fluent Validation

فرض کنید باید خالی بودن مقادیر ورودی بررسی شود. محل مناسب برای پیاده‌سازی این منطق کجاست؟ بررسی خالی بودن مقدار یک فیلد، از موضوعات مرتبط با Business نیست. موارد مرتبط با کسب و کار، مانند تکراری بودن نام یا ایمیل، در لایه Domain پیاده‌سازی می‌شوند.

به منظور اعتبارسنجی مقدار یک فیلد، یک پکیج شناخته‌شده به نام Fluent Validation وجود دارد.

برای نصب Fluent Validation در لایه Application، قطعه کد زیر را تایپ کنید:

dotnet add package FluentValidation –version 11.8.0

حال برای بررسی مقادیر ورودی‌ها، در داخل پوشه Commands، یک کلاس به اسم CreateUserValidator ایجاد می‌کنیم که ازAbstractValidator<T>  ارث‌بری می‌کند. T نمایانگر نوع شی است که اعتبارسنجی خواهد شد و AbstractValidator یکی از کلاس‌های پکیج Fluent Validation برای پیاده‌سازی Rule‌ های مختلف به‌کار می‌بریم.

به مثال زیر توجه کنید:

در قطعه کد بالا، این قاعده را تعیین کرده‌ایم که مقدار Name نمی‌تواند Null و Empty باشد. همین قاعده درخصوص سایر پارامترها نیز بررسی شده‌اند. 

به ازای همه پکیج‌ها و کلاس‌های استفاده‌شده در این پروژه، باید Instance های مختلفی از آن‌ها تعریف شود و در بخش‌های گوناگون پروژه به‌کار برده شوند. Net Core. از یک IoC درونی پشتیبانی می‌کند و استفاده از آن به برنامه‌نویس کمک‌کننده است.

استفاده از Dependency Injection

در ادامه این مقاله راه اندازی Clean Architecture ، موضوع Dependency Injection در پروژه‌های Clean بررسی می‌شوند. به‌طور کلی، لازم است یک کلاس به نام DependencyInjection در تمام لایه‌ها ایجاد شود. هرکدام از کلاس‌ها یک متد دارند و نام متد، ترکیبی از عبارت Add و نام لایه است.

 به‌عنوان مثال، کلاس DependencyInjection لایه Application، به‌صورت زیر تعریف می‌شود:

کلاس مذکور یک کلاس Static است و فقط یک متد به نام AddApplication دارد. این تابع، یک Extension Method برای IServiceCollection محسوب می‌شود. به این ترتیب، می‌توانیم تمامی Dependency Injection های مربوط به لایه Application را در این متد قرار دهیم. همین موضوع می‌تواند برای سایر لایه‌ها صادق باشد. درنهایت، می‌توان در کلاس Program.cs ، تمام Dependency Injection های پروژه را اضافه کرد:

به این ترتیب، هر یک از Configuration های مربوط به هر لایه از هم تفکیک شدند.

برای نمونه، متد مربوط به AddApplication تکمیل شد. این متد باید امکان رجیستر کردن دو پکیج نصب‌شده (MediatR و FluentValidation) را داشته باشد.

پکیج FluentValidation، یک متد Extension برای Injection دارد که با کمک این اکستنشن،register  متد تسهیل می‌یابد.

دستور زیر را برای نصب اکستنشن Dependency Injection به‌کار ببرید:

پیاده‌سازی متد AddApplication به‌صورت زیر است:

ورژن‌های جدید پکیج‌های MediatR و FluentValidation، به Assembly پروژه برای رجیستر کردن interface ها و پیاده‌سازی آن‌ها نیاز دارند. بنابراین، ابتدا یک متغیر به نام assembly تعریف کرده و آن را مقداردهی می‌کنیم. حال باید این متغیر در اختیار متدهای RegisterServicesFromAssemblies و AddValidatorsFromAssembly قرار گیرد. این متدها، اینترفیس‌های مشخص و از پیش تعریف شده خود را در داخل assembly داده شده جستجو می‌کنند. اگر کلاسی وجود داشته باشد که از این اینترفیس‌ها ارث‌بری کرده باشد، آن کلاس به‌عنوان پیاده‌سازی اینترفیس مذکور Register می‌شود. 

مقدار بازگشتی متدهایی که برای Register کردن Dependency ها تعریف کردیم، از نوع IServiceCollection بودند.

به این ترتیب، می‌توان فراخوانی آن‌ها در کلاس Program.cs را به‌صورت زیر تغییر داد:

در این بخش از راه اندازی Clean Architecture ، Dependency Injection بررسی شد. در ادامه، لایه آخر یعنی Infrastructure و اهمیت آن در راه اندازی Clean Architecture شرح داده می‌شود.

۵ساخت لایه Infrastructure

در لایه آخر، تمرکز روی پیاده‌سازی‌های مربوط به دیتابیس و ارتباط با سرویس‌های خارجی است. البته می‌توان پیاده‌سازی‌های مرتبط با اتصال به دیتابیس را در لایه درونی‌تر، یعنی Persistence، قرار داد.

مجدداً یک Class Library با Net 8. ایجاد کرده و کلاس پیش‌فرض آن را حذف کنید. توجه کنید که یک کلاس به نام DependecyInjection نیز باید به آن اضافه شود. نتیجه در شکل زیر قابل مشاهده است:

درنهایت، کلاس Program.cs به‌صورت زیر، به‌روزرسانی می‌شود:

این یک نمونه از راه اندازی Clean Architecture در .Net 8است. در این مطلب، لایه‌های مختلف معماری Clean ، ازجمله لایه‌های Presentation ،Infrastructure ،Domain و Application قرار دارند که همگی در زمان اجرا به یکدیگر متصل و اجرا می‌شوند.

Clean Architecture

راه اندازی Clean Architecture مشابه مثال فوق، شروع مناسب و ساختارمندی برای معماری محسوب می‌شود و شما می‌توانید آن را با گذر زمان و تغییر نیازمندی‌های معماری تکمیل کنید. البته راه اندازی Clean Architecture الزاماً پاسخگوی تمام مشکلات سیستم شما نیست و در کنار آن، لازم است سایر فاکتورهای مؤثر نیز بررسی شوند. در سال‌های اخیر، روش‌هایی مانند Layered Architecture وSlice Architecture  نیز محبوبیت یافته‌اند.

مدل تکمیلی به شکل ذیل می باشد:

Clean Architecture

وظایف و نقش Persistence در معماری Clean

  1. ذخیره‌سازی داده‌ها:
    • مدیریت عملیات‌های ذخیره‌سازی داده‌ها در پایگاه‌داده یا سایر منابع داده. این شامل عملیات‌های Create، Read، Update و Delete (CRUD) می‌شود.
  2. بازیابی داده‌ها:
    • بازیابی داده‌ها از پایگاه‌داده یا منابع دیگر و تبدیل آن‌ها به اشیای دامنه‌ای (Entities) که در لایه‌های داخلی استفاده می‌شوند.
  3. استفاده از الگوهای Repository و DAO:
    • استفاده از الگوهای طراحی مثل Repository و Data Access Object (DAO) برای جداسازی منطق دسترسی به داده‌ها از منطق کسب‌وکار و کاربرد.
  4. استفاده از ORM:
    • استفاده از ابزارهای ORM (Object-Relational Mapping) مثل Entity Framework در دات‌نت، Hibernate در جاوا یا سایر ابزارهای مشابه برای مدیریت مپینگ بین اشیای دامنه و جداول پایگاه‌داده.

نحوه پیاده‌سازی Persistence در معماری Clean

  1. ایجاد Interface‌های Repository در لایه Use Cases یا Domain:
    • تعریف Interface‌هایی که عملیات‌های ذخیره‌سازی و بازیابی داده‌ها را تعریف می‌کنند. این Interface‌ها باید مستقل از جزئیات پیاده‌سازی خاص پایگاه‌داده باشند.
  1. پیاده‌سازی Interface‌های Repository در لایه Persistence:
    • پیاده‌سازی این Interface‌ها در لایه Persistence که شامل جزئیات پیاده‌سازی خاص پایگاه‌داده است. این پیاده‌سازی‌ها می‌توانند از ORM یا تکنیک‌های دسترسی مستقیم به پایگاه‌داده استفاده کنند.

  1. تزریق وابستگی‌ها (Dependency Injection):
    • استفاده از تزریق وابستگی‌ها برای ارسال پیاده‌سازی‌های Repository به Use Cases. این کار باعث می‌شود که لایه‌های داخلی به پیاده‌سازی‌های خاص پایگاه‌داده وابسته نباشند.

مزایای جداسازی Persistence در معماری Clean

  1. جداسازی نگرانی‌ها:
    • با جداسازی منطق دسترسی به داده‌ها از منطق کسب‌وکار، هر لایه می‌تواند به طور مستقل تغییر کند و توسعه یابد.
  2. قابلیت تست‌پذیری:
    • با تعریف Interface‌های Repository و استفاده از Mockها یا Fakeها، می‌توان به راحتی لایه‌های داخلی را بدون نیاز به وابستگی به پایگاه‌داده واقعی تست کرد.
  3. انعطاف‌پذیری:
    • امکان تغییر یا جایگزینی تکنولوژی ذخیره‌سازی (مثل مهاجرت از یک پایگاه‌داده به دیگری) بدون تأثیر بر لایه‌های داخلی فراهم است.

نتیجه‌گیری

لایه Persistence در معماری Clean نقش مهمی در جداسازی منطق دسترسی به داده‌ها از منطق کسب‌وکار و کاربرد دارد. با استفاده از اصول معماری Clean و الگوهای طراحی مناسب، می‌توان به سیستم‌هایی قابل نگه‌داری، تست‌پذیر و انعطاف‌پذیر دست یافت که به راحتی قابل توسعه و تغییر باشند.

 Unit Testing در  ASP.NET Core MVC

چرا به تستهای واحد نیاز داریم؟

برنامه های ما امکان دارد به طور غیرمنتظره ای در پاسخ به تغییرات با مشکل روبه رو شوند. از این رو، تست خودکار بعد از تغییرات در تمام برنامه ها مورد نیاز است.

تست دستی، کندترین، کم اعتبارترین و گرانترین راه برای آزمایش یک برنامه است. اما اگر برنامه ها به گونه ای طراحی نشده اند که قابل تست باشند، تست دستی ممکن است تنها راه در دسترس ما باشد.

بنابراین اولین قدم این است که مطمئن شوید برنامه به گونه ای طراحی شده است که قابل آزمایش باشد. برنامه هایی که از اصول معماری خوب پیروی می کنند مانند تفکیک نگرانی ها  (Seperation of Concerns)، وارونگی وابستگی، مسئولیت منفرد (Single Responsibility)، Don’t repeat yourself (DRY) و غیره به راحتی قابل آزمایش هستند. ASP.NET Core از واحد خودکار، یکپارچه سازی و تست عملکرد پشتیبانی می کند.

یک تست واحد به معنی تست یک قسمت واحد از منطق برنامه ما است. کد ما امکان دارد وابستگیهایی بر روی لایه های پایین ترو کامپوننتهای خارجی داشته باشد. اما آنها با تستهای واحد اعتبارسنجی نمیشوند. تست واحد به طور کامل در حافظه و در فرآیند اجرا می شود. با سیستم فایل، شبکه یا پایگاه داده ارتباط برقرار نمی کند.

تست های واحد فقط باید کد ما را تست کنند.

با توجه به این دلایل، تست های واحد باید بسیار سریع اجرا شوند و ما باید بتوانیم آنها را به طور مکرر اجرا کنیم. در حالت ایده‌آل، ما باید تست‌های واحد را قبل از ارسال هر تغییر به source control repository و همچنین با هر build خودکار روی build server اجرا کنیم.

راه اندازی Framework تست واحد

framework  های تست زیادی در market امروزی وجود دارد. با این حال، برای این مقاله، قصد دادریم از xUnit استفاده کنیم که یک framework تست خیلی معروفی است. حتی تستهای ASP.NET Core و EF Core توسط آن نوشته شده اند.

ما میتوانیم با استفاده از xUnit Test Project template یک پروژه تستxUnit  در ویژوال استودیو اضافه کنیم که در ویژوال استودیو در دسترس میباشد:

 Unit Testing در  ASP.NET Core MVC

ما همیشه باید تستهای خود را به سبکی ثابت نام‌گذاری کنیم، با نام‌هایی که مشخص کند که هر تست چه کاری انجام می‌دهد. یک رویکرد خوب این است که کلاس ها و متدهای آزمایشی را با توجه به کلاس و متدی که در حال آزمایش هستند نامگذاری کنید. این کاملاً مشخص می کند که هر آزمایش چه مسئولیتی دارد.

ما می توانیم رفتاری را که در حال آزمایش است را به نام هر test method اضافه کنیم. این باید شامل رفتار مورد انتظار و هر ورودی یا فرضیه هایی باشد که باید این رفتار را نشان دهد.

بنابراین، هنگامی که یک یا چند تست با شکست مواجه می شوند، از نام آنها مشخص است که چه مواردی شکست خورده اند. ما زمانیکه تستهای واحد را در قسمت بعدی ایجاد میکنیم از این قواعد نام گذاری پیروی خواهیم کرد.

بنابراین یک NuGet package reference برای Moq اضافه کنیم که یک فریم ورک آبجکت ساختگی است. این امر، آبجکتهای آزمایشی که آبجکتهای ساختگی یا مجموعه ای از ویژگی ها و رفتارهای متد از پیش تعیین شده برای آزمایش هستند را در اختیار ما قرار می دهد.

تستهای واحد در متدهای کنترلر

بگوییم که یکEmployeeController  با یک متد ()Index  و ()Add تعریف کرده ایم:

حالا نحوه نوشتن تستهای واحد برای این اکشن متدها را بررسی کنیم. کنترلر ما از تزریق وابستگی برای گرفتن مقدار برای dataRepository_  استفاده میکند. این باعث میشود که این امکان را برای unit testing framework فراهم کند تا یک آبجکت ساختگی را ارائه داده و متد ها را تست کند.

الگوی (Arrange, Act, Assert) AAA یک شیوه ی رایج برای نوشتن تستهای واحد است و ما همین الگو را اینجا دنبال خواهیم کرد.

قسمت Arrange یک متد تست واحد، آبجکتها را مقداردهی اولیه میکند و مقادیر را برای ورودیهایی که به متد مورد آزمایش پاس داده میشوند set میکند.

قسمت Act، متد مورد آزمایش را به همراه پارامترهای Arrange فراخوانی میکند.

قسمت Assert تأیید می کند که اکشن متد مورد آزمایش، طبق انتظار عمل می کند.

آزمایش متد ()Index

حالا تستها را برای متد ()Index بنویسیم:

ما اول با استفاده از متد  ()GetTestEmployees ، سرویس  IDataRepository<Employee> را mock کردیم. ()GetTestEmployees  یک لیست از دو آبجکت ساختگی را ایجاد کرده و برمیگرداند.

سپس متد Index() اجرا شده و موارد زیر را روی نتیجه assert میکند:

یک ViewResult برمیگرداند

نوع مدل برگشتی List<Employee> میباشد

دو آبجکت Employee در مدل برگشتی وجود دارد

هر test method با یک ویژگی [Fact] مزین شده است که نشان می دهد این یک متد واقعی است که باید توسط test runner  اجرا شود.

آزمایش متد  ()Add

حالا تستها را برای متد ()Add بنویسیم:

اولین تست تأیید می کند که زمانیکه ModelState.IsValid برابر با false است، اکشن متد یک ViewResult 400 Bad Request را با داده های مناسب برمی گرداند. می‌توانیم با اضافه کردن خطاها با استفاده از متد ()AddModelError وضعیت مدل نامعتبر را آزمایش کنیم.

تست دوم تأیید می‌کند که وقتی ModelState.IsValid برابر با true است، متد ()Add در repository  فراخوانی می‌شود و RedirectToActionResult با آرگومان‌های صحیح بازگردانده می‌شود.

متدهای Mock که ما آنها را فراخوانی نمی کنیم معمولا نادیده گرفته می شوند، اما با فراخوانی ()Verifiable همراه با تنظیمات، می توانیم تایید کنیم که متدهای Mock فراخوانی شده اند. ما می‌توانیم این را با استفاده از mockRepo.Verify تأیید کنیم، که اگر متد مورد انتظار فراخوانی نشده باشد، آزمایش مورد نظر شکست می‌خورد.

اجرای تستها

ما میتوانیم تستها را با استفاده از Test Explorer  در Visual Studio اجرا کنیم:

 Unit Testing در  ASP.NET Core MVC

در Test Explorer می‌توانیم تمام تست‌های موجود را به‌صورت گروه‌بندی شده بر اساس Solution، Project، Class و غیره مشاهده کنیم. ما می توانیم تست ها را با اجرا یا debug کردن آن ها انتخاب و اجرا کنیم. هنگامی که تست ها را اجرا می کنیم، می توانیم یک علامت تیک سبز یا یک علامت متقاطع قرمز را در سمت چپ نام متد تست ببینیم که نشان دهنده موفقیت یا شکست در آخرین اجرای متد است. در سمت راست، می‌توانیم زمان صرف شده برای اجرای هر تست را ببینیم.

آموزش پروژه محور SignalR در ASP.NET Core

SignarR

SignalR یک کتابخانه در ASP.NET Core است که امکان برقراری ارتباط بلادرنگ بین سرور و کلاینت‌ها را فراهم می‌کند. این کتابخانه به طور خاص برای برنامه‌هایی طراحی شده است که نیاز به تبادل اطلاعات سریع و به‌روز بین سرور و کلاینت دارند، مانند چت آنلاین، برنامه‌های بازی، اعلان‌های بلادرنگ، و غیره.

ویژگی‌ها و عملکرد SignalR

ارتباط بلادرنگ: SignalR از پروتکل‌های مختلفی مانند WebSockets، Server-Sent Events، و Long Polling برای برقراری ارتباط بلادرنگ استفاده می‌کند. انتخاب پروتکل به مرورگر و سرور بستگی دارد و به صورت خودکار توسط SignalR مدیریت می‌شود.

پشتیبانی از هاب‌ها: SignalR از مفهومی به نام “هاب” استفاده می‌کند که به شما امکان می‌دهد تا متدهای سرور را از کلاینت صدا بزنید و بالعکس. هاب‌ها به عنوان واسطه‌ای بین سرور و کلاینت عمل می‌کنند و ارتباطات بلادرنگ را ساده‌تر می‌کنند.

مدیریت اتصالات: SignalR به طور خودکار اتصالات را مدیریت می‌کند و امکان پیگیری کلاینت‌های متصل، ارسال پیام به تمام کلاینت‌ها یا گروه‌های خاصی از کلاینت‌ها را فراهم می‌کند.

مقیاس‌پذیری: SignalR از مقیاس‌پذیری در سطح سرور و کلاینت پشتیبانی می‌کند و می‌تواند با استفاده از تکنولوژی‌هایی مانند Redis ، Azure SignalR Service، و غیره، ترافیک را مدیریت کند.

در این آموزش، مقدمات ساخت یک برنامه Real-Time با استفاده از SignalR قرار داده شده است.

در این آموزش خواهید آموخت که چگونه :

یک پروژه وب ایجاد کنید.

کتابخانه سمت کلاینت SignalR را اضافه کنید.

یک SignalR Hub ایجاد کنید.

پروژه را برای استفاده از SignalR کانفیگ کنید.

کد ارسال پیام از یک کلاینت به تمامی کلاینت های متصل را اضافه کنید.

در آخر، شما یک برنامه چت خواهید داشت :

ساخت برنامه چت با SignalR در ASP.NET Core

پیش نیاز ها

ویژوال استودیو 2019 با ابزار مختص به توسعه وب ( ASP.NET and web development workload )

نسخه 3 NET Core SDK. یا بالاتر

ساخت یک پروژه وب

از منو، File و سپس New Project را انتخاب کنید.

در پنجره Create a new project، نوع ASP.NET Core Web Application را انتخاب کرده و سپس برروی Next کلیک کنید.

در پنجره Configure your new project، نام پروژه را SignalRChat قرار داده و برروی Create کلیک کنید.

در پنجره Create a new ASP.NET Core Web Application، ورژن را برروی ASP.NET Core 3 و نوع را برروی NET Core. قرار دهید.

ساخت پروژه Web Application در Visual Studio

اضافه کردن کتابخانه سمت کلاینت SignalR

کتابخانه سمت سرور SignalR به صورت پیشفرض در فریمورک ASP.NET Core قرار دارد.

امَا کتابخانه سمت کلاینت مختص جاوا اسکریپت به صورت پیشفرض در پروژه قرار داده نمیشود.

در این آموزش، از Library Manager یا همان LibMan جهت دریافت کتابخانه سمت کلاینت از unpkg استفاده میشود.

این unpkg که یک Content Delivery Network یا همان CDN است برای ما این امکان را فراهم میکند که از هرچیزی که داخل npm یا همان Node.js Package Manager وجود دارد استفاده کنیم.

در Solution، برروی پروژه خود راست کلیک کرده و از بخش Add گزینه ی Client-Side Library را انتخاب کنید.

در پنجره Add Client-Side Library، ارائه دهنده یا همان Provider را برروی unpkg قرار دهید.

در بخش Library نیز متن زیر را قرار دهید :

@microsoft/signalr@latest

رادیو باتن را برروی Choose specific files قرار داده و در پوشه dist/browser فایل های signalr.js و signalr.min.js را علامت بزنید.

همچنین، Target Location را نیز برروی wwwroot/js/signalr قرار دهید.

افزودن کتابخانه سمت کلاینت SignalR به پروژه ASP.NET Core

‌لیب من ( LibMan ) به طور خودکار پوشه ی wwwroot/js/signalr را ایجاد کرده و فایل های انتخاب شده را داخل آن قرار میدهد.

ایجاد کردن یک SignalR Hub

هاب ( Hub ) کلاسی است که به عنوان یک Pipeline سطح بالا، ارتباط های سرور و کلاینت را هندل میکند.

در پوشه ی پروژه خود ( SignalRChat )، یک پوشه به نام Hubs ایجاد کنید.

در پوشه ی Hubs، یک فایل ChatHub.cs ایجاد کرده و کد زیر را داخل آن قرار دهید.

کلاس ChatHub از کلاس Hub ارث بری کرده است. کلاس Hub کانکشن ها، گروه ها و پیغام هارا مدیریت میکند.

متد SendMessage میتواند با یک کلاینت متصل شده ارتباط برقرار کند تا یک پیام را به تمامی کلاینت ها ارسال کند.

در ادامه آموزش، خواهد دید که چگونه با کد جاوا اسکریپت از سمت کلاینت با این متد ارتباط برقرار میکنیم.

کد SignalR به صورت Asynchronous است تا بتواند حداکثر مقیاس پذیری را ارائه دهد.

پیکربندی SignalR

سرور SignalR باید کانفیگ شده باشد تا بتواند ریکوئست های SignalR را به خود SignalR پاس دهد.

کدهای زیر را به فایل Startup.cs خود اضافه کنید :

این تغییرات، SignalR را به سیستم های مسیریابی ( Routing ) و تزریق وابستگی ( Dependency Injection ) هسته ASP.NET Core اضافه میکند.

اضافه کردن کد سمت کلاینت SignalR

محتوای Pages/Index.cshtml را با کد زیر جایگزین کنید :

این کد :

تکست باکس هایی را برای نام و متن پیام + یک دکمه ارسال را ایجاد میکند.

یک لیست با آیدی messageList برای نمایش پیام هایی که از SignalR Hub دریافت میشوند را ایجاد میکند.

شامل رفرنس کدهای جاوا اسکریپت SignalR و chat.js هست که در قدم های بعدی آن را اضافه خواهیم کرد.

در پوشه wwwroot/js، یک فایل chat.js ایجاد کرده و کد زیر را داخل آن قرار دهید :

این کد :

یک کانکشن را ایجاد و استارت میکند.

به دکمه ی submit یک هندلر اضافه میکند که پیام را به هاب ( Hub ) ارسال کند.

به آبجکت connection یک هندلر اضافه میکند که پیام ها را از هاب ( Hub ) دریافت و آنهارا به لیست اضافه کند.

اجرای برنامه

با Ctrl + F5 برنامه بدون Debugging اجرا میشود.

لینک را از آدرس بار مرورگر خود کپی کرده و در یک مرورگر یا تب باز شده دیگر پیست کنید.

یکی از مرورگرها را انتخاب، نام و پیام خود را وارد، سپس برروی دکمه Send Message کلیک کنید.

نام و پیام در صفحه ی دیگر به سرعت نمایش داده میشود :

برنامه چت با SignalR و  ASP.NET Core

اگر برنامه کار نکرد، Developer Tools مرورگر خود را باز کرده ( با F12 ) و به قسمت Console بروید. باید ارورهایی را در رابطه با کد HTML و جاوا اسکریپت خود مشاهده کنید. برای مثال، ممکن است فایل signalr.js را در یک پوشه دیگر قرار داده باشید. در این حالت به آن فایل رفرنسی داده نخواهد شد و شما ارور 404 را در Console مرورگر خود مشاهده خواهید کرد.

Developer Tools

خطای 404 در Console مرورگر

اگر شما در مرورگر کروم خود ارور ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY را مشاهده کردید، این دستورات را در Command Prompt خود اجرا کنید تا Development Certificate شما بروز شود.

dotnet dev-certs https –clean

dotnet dev-certs https –trust

آموزش استفاده AutoMapper در ASP.Net Core

Auto Mapper

 AutoMapper یک کتابخانه در دات‌نت است که برای نگاشت (Map) خودکار اشیاء استفاده می‌شود. این کتابخانه به شما اجازه می‌دهد تا به‌طور خودکار داده‌ها را بین دو نوع مختلف از اشیاء انتقال دهید. این کار می‌تواند بسیار مفید باشد زمانی که می‌خواهید داده‌ها را از مدل‌های دامنه (Domain Models) به مدل‌های نمایش (View Models) یا DTO ها (Data Transfer Objects) منتقل کنید.

ابتدا باید از طریق nuget آن را به پروژه خود اضافه کنید

پکیج :

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

اگر از معماری clean architecture استفاده میکنید باید آن را به پروژه Domain خود اضافه کنید. این مقاله اگر Automapper نصب ندارین ،زمانی که پکیج بالا نصب میکنید همراهش Automapper نصب میکنه.

مرحله دوم این هست که باید بریم در فایل startup.cs و در بخش ConfigureServices اتومپر (Automapper) رو صدا بزینم.

مرحله سوم اضافه کردن profile ها ست . یک profile در واقع نقشه (map) هست که میگه چه کلاسی باید به چه کلاسی تبدیل کنی ! حالا ما یک کلاس به نام DomainProfile داریم که در سازندش یک mapping تنظیم شده:

وقتی application اجرا بشه Automapper از طریق کد شما تمام کلاس هایی که از کلاس Profile ارث بری شده پیدا می کند و configuration آنها را load میکند. به همین سادگی به همین خوشمزگی!

مرحله چهار استفاده از IMapper . وقتی پیکربندی (configuration) پروفایل های شما بارگذاری (load) شد. باید interface (واسط) IMapper مانند DI Framework های
دیگر (Dependency Injection) تزریق (Inject) کنید. که این کار رو از طریق سازنده (constructor) انجام میدیم و به همه اشیا نقشه ها دسترسی خواهیم داشت:

دوباره بنظر میرسد کار خارق العاده ای اتفاق افتاده است. ما هیچ وقت IMapper را در ServiceCollection ثبت (register) نکردیم .  اما پکیجی با نام AddAutoMapper که در بخش ConfigureServices ثبت کردیم به صورت اتوماتیک هندل میشود.

دامنه (Scopes)

آخرین چیزی که در نهایت میماند دامنه های داخل Automapper چگونه کار میکنند. پیکربندی های شما (مانند Profile های Automapper ) سینگلتون singleton هستند. به این دلیل که در اجرای برنامه فقط یکبار load میشوند.

واسط IMapper خودش Scoped هست. از نظر ASP.net ، به این معنی است که برای هر درخواست منحصر بفرد(individual) ، یک IMapper جدید ایجاد می شود اما در سرتاسر برنامه برای آن درخواست به اشتراک گذاشته می شود (همون Scope در aspnetcore DI هست) (بر عکس transient که یک درخواست منحصربفرد در سرتاسر برنامه هرزمان آن را تقاضا کند برای آن درخواست نمونه جدید میسازد).بنابراین اگر از IMapper در داخل یک controller و در داخل یک service برای یک درخواست واحد (single request) استفاده کنید ، آنها از همان یک نمونه IMapper استفاده می کنند.

اما چیزی که واقعا مهم است اینکه همه چیز از IValueResolver ، ITypeConverter یا IMemberValueResolver مشتق(derives) شده است، transient scope هستند.آنها همچنین با استفاده از .NET Core Service Collection DI ایجاد می شوند.

کد زیر را ببینید،برای resolve کردن یک mapping خاص استفاده می شود که به وسیله آن می خواهیم یک username براساس id مدل، map سراسری کنیم.برای این کار

از آنجا که این به عنوان نمونه transient با استفاده از .NET Core’s Service Collection ،مخزن ما (repository) نیز به درستی resolve شد و ما قادر خواهیم بود map کردن هایی را انجام دهم که بیش از map کردن سراسری مقادیر ساده باشند.

حال در گیت هاب automapper یک پکیجی را قرار داده که Automapper روی efcore سوار می کنه

آدرس پکیج

این پکیج با پکیجی که قبل تر معرفی کردیم سازگار است و همچنین با DI خود netcore.

به عنوان مثال:

توجه: expressionهای تعریف شده توسط کاربر ، expression های اصلی کلید (primary key) را بازنویسی می کند.

در مورد مقایسه با یک Entity موجود برای بروزرسانی چه می توان گفت؟

پکیج Automapper.Collection.EntityFrameworkCore این کار را از طریق extension method از DbSet انجام می دهد.

ترجمه برابری بین Data Transfer Object (مخفف شدش Dto) و شی EF (همون Entity Framework) به یک expression فقط EF با استفاده از مقادیر dto به عنوان ثابت ها است.

توجه: این کار با تبدیل OrderDTO به Expression <Func <Order، bool ”و استفاده از آن برای پیدا کردن نوع تطبیق در پایگاه داده انجام می شود. همچنین می توانید شیء ها را به expression ها نیز map کنید.

(ارسال تغییرات) submit changes بطور خودکار صدا زده نمیشود.

فرم ساز(Form Builder) چیست؟

فرم ساز سیستم یکپارچه مدیریت فرآیند های کسب و کار

فرم ساز طراحان وب را قادر می سازد تا فرم های سفارشی برای سایت های خود ایجاد کنند. پلتفرم های ایجاد وب فرم سازهایی را ارائه می دهند که استفاده از آنها به طور فزاینده ای آسان، ساده و سریع است. 

چرا از فرم ساز استفاده کنیم؟

فرم ها یک عنصر حیاتی برای اکثر وب سایت ها، به ویژه سایت های تجارت الکترونیک هستند. آنها ممکن است نقطه نهایی باشند که در آن اطلاعات تماس سرنخ های بالقوه را جمع آوری می کنید. متأسفانه، اگر یک توسعه‌دهنده وب را برای ایجاد یک سایت HTML ایستا و کدگذاری شده استخدام کرده‌اید، قبل از شروع ساختن فرم‌های شما، باید شماره‌ای بگیرید. با این حال، اگر یک CMS منبع باز مانند وردپرس را انتخاب کرده اید، ابزار Form Builder به شما این امکان را می دهد که بدون نوشتن یک خط کد، به سرعت و به راحتی یک فرم وب با ظاهر عالی ایجاد کنید!

فرم ساز چگونه کار می کند؟

Form Builders به ​​شما امکان می دهد سوالات را بکشید و رها کنید و فیلدهایی را در جایی که به آنها نیاز دارید با پلتفرم های ایجاد وب تشکیل دهید. همچنین می توان با رنگ و ساختار یک فرم و موارد دیگر بازی کرد! 

موارد استفاده Form Builder:

فرم های وب را به سرعت ایجاد کنید و داده ها را به صورت حرفه ای جمع آوری کنید

فرم های وب را بدون هیچ سطح بالاتری از دانش رایانه جاسازی یا به اشتراک بگذارید

هر زمان که شخصی فرم را پر کرد، به سرعت اعلان ها را دریافت کنید

پاسخ ها را در یک مکان مرور کنید و آنها را به وضوح ببینید

امکان دانلود پاسخ ها با فرمت های اکسل،CSV  یا PDF 

توانایی تجزیه و تحلیل و به اشتراک گذاری گزارش های فرم با همکاران برای برنامه ریزی تکنیک های بهینه سازی برای به حداکثر رساندن تبدیل ها

دریافت هشدارهای فوری و مرور پاسخ ها در دستگاه های تلفن همراه

BPMN (Business Process Model & Notation)

BPMN

مخفف عبارت Business Process Model & Notation است و به معنی مجموعه‌ ای از علائم و اشکال گرافیکی برای مدل‌سازی فرآیندهای کسب‌وکار است. با استفاده از این زبان نمادین می‌توان فرآیندهای کسب و کار را مدل‌سازی کرد

BPMN چیست ؟

یک مدل استاندارد فرآیند کسب‌وکار و نمادگذاری (BPMN) به کسب‌وکارها توانایی درک رویه‌های تجاری داخلی خود را در یک نماد گرافیکی می‌دهد و به سازمان‌ها این توانایی را می‌دهد که این رویه‌ها را به شیوه‌ای استاندارد ارتباط برقرار کنند. علاوه بر این، نماد گرافیکی درک همکاری های عملکردی و معاملات تجاری بین سازمان ها را تسهیل می کند. این تضمین می‌کند که کسب‌وکارها خودشان و شرکت‌کنندگان در کسب‌وکارشان را درک می‌کنند و سازمان‌ها را قادر می‌سازد تا به سرعت با شرایط جدید تجاری داخلی و B2B سازگار شوند.

عناصر BPMN

یکی از محرک های توسعه BPMN ایجاد یک مدل ساده و قابل درک است

مکانیزم ایجاد مدل‌های فرآیند کسب‌وکار، در حالی که در عین حال قادر به مدیریت پیچیدگی ذاتی است

به فرآیندهای کسب و کار رویکرد اتخاذ شده برای رسیدگی به این دو الزام متضاد، سازماندهی بود

جنبه های گرافیکی نماد به دسته های خاص. این مجموعه کوچکی از دسته‌بندی‌های نماد را فراهم می‌کند تا خواننده

یک نمودار BPMN می تواند به راحتی انواع اصلی عناصر را تشخیص دهد و نمودار را درک کند. در چارچوب

دسته بندی عناصر، تغییرات اضافی و اطلاعات را می توان برای پشتیبانی از الزامات پیچیدگی اضافه کرد

بدون تغییر چشمگیر ظاهر و احساس اصلی نمودار.

پنج دسته اصلی عناصر عبارتند از:

1-  جریان اشیاء (Flow Objects)

2- داده ها (Data)

3- اتصال اشیاء (Connecting Objects)

4- شناورها (Swimlanes)

5- مصنوعات (Artifacts)

Flow Object ها عناصر گرافیکی اصلی برای تعریف رفتار یک فرآیند تجاری هستند.

 سه جریان وجود دارد

اشیاء:

1- رویدادها (Events)

2- فعالیت ها (Activities)

3- دروازه ها (Gateways)

28 مدل نماد فرآیند کسب و کار، نسخه 2.0

داده ها با چهار عنصر نشان داده می شوند:

1- اشیاء داده (Data Objects)

2- ورودی داده ها (Data Inputs)

3- خروجی داده ها (Data Outputs)

4- فروشگاه های داده (Data Stores)

چهار راه برای اتصال  Flow Objectها به یکدیگر یا اطلاعات دیگر وجود دارد. چهار اتصال وجود دارد

اشیاء:

1- دنباله جریان (Sequence Flows)

2- جریان پیام (Message Flows)

3- انجمن ها (Associations)

4-  انجمن های داده (Data Associations)

دو روش برای گروه بندی عناصر اولیه مدل سازی از طریق “Swimlanes” وجود دارد:

1- استخرها (Pools)

2- خطوط (Lanes)

مصنوعات برای ارائه اطلاعات اضافی در مورد فرآیند استفاده می شوند. دو مصنوع استاندارد شده وجود دارد، اما

مدل‌سازها یا ابزارهای مدل‌سازی می‌توانند هر تعداد مصنوع را که لازم است اضافه کنند. ممکن است تلاش های BPMN بیشتری وجود داشته باشد

برای استاندارد کردن مجموعه بزرگتری از مصنوعات برای استفاده عمومی یا برای بازارهای عمودی. مجموعه فعلی مصنوعات

شامل می شود:

گروه (Group)

حاشیه نویسی متن (Text Annotation)

عناصر مدل سازی اولیه BPMN

لیستی از عناصر اصلی مدل سازی را که با نماد نشان داده شده اند را نمایش می دهد.

NotationDescriptionElement
BPMN (Business Process Model & Notation)رویداد یک رویداد چیزی است که در طول یک فرآیند (به صفحه 238) یا یک طراحی رقص (به صفحه 339 مراجعه کنید) “اتفاق می افتد”. این رویدادها بر جریان مدل تأثیر می‌گذارند و معمولاً یک علت (محرک) یا تأثیر (نتیجه) دارند. رویدادها دایره‌هایی با مراکز باز هستند تا به نشانگرهای داخلی اجازه دهند محرک‌ها یا نتایج مختلف را متمایز کنند. سه نوع رویداد وجود دارد، بر اساس اینکه چه زمانی بر جریان تأثیر می‌گذارند: شروع، متوسط و پایان.Event
رویداد
BPMN (Business Process Model & Notation)فعالیت یک اصطلاح عمومی برای کاری است که شرکت انجام می دهد (به صفحه 151 مراجعه کنید) در یک فرآیند. یک Activity می تواند اتمی یا غیر اتمی (ترکیبی) باشد. انواع فعالیت هایی که بخشی از یک مدل فرآیند هستند عبارتند از: Sub-Process و Task که مستطیل های گرد هستند. فعالیت‌ها هم در فرآیندهای استاندارد و هم در رقص استفاده می‌شوند.Activity
فعالیت
BPMN (Business Process Model & Notation)یک دروازه برای کنترل واگرایی و همگرایی جریان های دنباله ای در یک فرآیند (به صفحه 145) و در یک رقص (به صفحه 344 مراجعه کنید) استفاده می شود. بنابراین، انشعاب، دوشاخه، ادغام و پیوستن مسیرها را تعیین می کند. نشانگرهای داخلی نوع کنترل رفتار را نشان خواهند داد.Gateway
دروازه
BPMN (Business Process Model & Notation)یک جریان توالی برای نشان دادن ترتیب انجام فعالیت ها در یک فرآیند (به صفحه 97) و در یک رقص (به صفحه 320 مراجعه کنید) استفاده می شود.Sequence Flow
جریان دنباله ای
BPMN (Business Process Model & Notation)یک جریان پیام برای نشان دادن جریان پیام ها بین دو شرکت کننده که آماده ارسال و دریافت آنها هستند استفاده می شود (صفحه 120 را ببینید). در BPMN، دو Pool مجزا در یک نمودار همکاری نشان دهنده دو شرکت کننده خواهند بود (به عنوان مثال، PartnerEntities و/یا PartnerRoles).Message Flow
جریان پیام
BPMN (Business Process Model & Notation)یک انجمن برای پیوند دادن اطلاعات و مصنوعات با عناصر گرافیکی BPMN استفاده می شود (به صفحه 67 مراجعه کنید). حاشیه نویسی های متنی (به صفحه 71 مراجعه کنید) و سایر مصنوعات (به صفحه 66 مراجعه کنید) را می توان با عناصر گرافیکی مرتبط کرد. یک نوک پیکان روی انجمن در صورت لزوم، جهت جریان (به عنوان مثال، داده) را نشان می دهد.Association
اتحادیه
BPMN (Business Process Model & Notation)یک Pool نمایش گرافیکی یک شرکت کننده در یک همکاری است (به صفحه 112 مراجعه کنید). همچنین به عنوان یک “swimlane” و یک محفظه گرافیکی برای پارتیشن بندی مجموعه ای از فعالیت ها از سایر Pool ها، معمولاً در زمینه موقعیت های B2B عمل می کند. یک Pool ممکن است دارای جزئیات داخلی باشد، به شکل فرآیندی که اجرا خواهد شد. یا یک Pool ممکن است جزئیات داخلی نداشته باشد، یعنی می تواند یک “جعبه سیاه” باشد.Pool
استخر
BPMN (Business Process Model & Notation)Lane یک پارتیشن فرعی در یک Process است، گاهی اوقات در یک Pool، و تمام طول فرآیند را، به صورت عمودی یا افقی (به صفحه 305 مراجعه کنید) گسترش می‌دهد. خطوط برای سازماندهی و دسته بندی فعالیت ها استفاده می شود.Lane
مسیر
BPMN (Business Process Model & Notation)اشیاء داده اطلاعاتی در مورد آنچه که فعالیت ها برای انجام نیاز دارند و/یا آنچه را که تولید می کنند ارائه می دهند (به صفحه 205 مراجعه کنید)، اشیاء داده می توانند یک شی منفرد یا مجموعه ای از اشیاء را نشان دهند. داده‌های ورودی و خروجی داده‌ها اطلاعات یکسانی را برای فرآیندها فراهم می‌کنند.Data Object
شی داده
BPMN (Business Process Model & Notation)از یک پیام برای نشان دادن محتوای ارتباط بین دو شرکت کننده استفاده می شود (همانطور که توسط یک PartnerRole تجاری یا یک شریک تجاری تعریف شده است – به صفحه 93 مراجعه کنید).Message
پیام
BPMN (Business Process Model & Notation)گروه گروهی از عناصر گرافیکی است که در یک دسته قرار دارند (به صفحه 70 مراجعه کنید). این نوع گروه بندی بر جریان های دنباله ای در گروه تأثیر نمی گذارد. نام دسته بر روی نمودار به عنوان برچسب گروه ظاهر می شود. دسته ها را می توان برای اهداف مستندسازی یا تجزیه و تحلیل استفاده کرد. گروه ها یکی از راه هایی هستند که در آن دسته بندی اشیا را می توان به صورت بصری در نمودار نمایش داد.Group (a box around a group of objects within the same category)
گروه (یک جعبه در اطراف گروهی از اشیاء در همان دسته)
BPMN (Business Process Model & Notation)حاشیه نویسی متن مکانیزمی برای یک مدل ساز است تا اطلاعات متنی اضافی را برای خواننده نمودار BPMN فراهم کند (به صفحه 71 مراجعه کنید).Text Annotation (attached with an Association)
حاشیه نویسی متن (پیوست به انجمن)

عناصر مدل سازی پیشرفته BPMN

فهرست گسترده تری از مفاهیم فرآیند کسب و کار را نشان می دهد که می تواند از طریق نماد مدل سازی فرآیند کسب و کار به تصویر کشیده شود.

NotationDescriptionElement
BPMN (Business Process Model & Notation)Event یک رویداد چیزی است که در طول یک فرآیند (به صفحه 238) یا یک طراحی رقص (به صفحه 339 مراجعه کنید) “اتفاق می افتد”. این رویدادها بر جریان مدل تأثیر می‌گذارند و معمولاً یک علت (تریگر) یا تأثیر (نتیجه) دارند. رویدادها دایره‌هایی با مراکز باز هستند که به نشانگرهای داخلی اجازه می‌دهند تا محرک‌ها یا نتایج مختلف را متمایز کنند. سه نوع رویداد وجود دارد، بر اساس اینکه چه زمانی بر جریان تأثیر می‌گذارند: شروع، متوسط و پایان.Event
رویداد
BPMN (Business Process Model & Notation)همانطور که از نام آن پیداست، رویداد Start نشان می دهد که یک فرآیند خاص (به صفحه 238 مراجعه کنید) یا رقص (به صفحه 339 مراجعه کنید) از کجا شروع می شود.Start
شروع
BPMN (Business Process Model & Notation)رویدادهای میانی بین یک رویداد شروع و یک رویداد پایانی رخ می دهند. آنها بر جریان فرآیند (به صفحه 249 مراجعه کنید) یا رقص (به صفحه 341 مراجعه کنید) تأثیر می‌گذارند، اما روند را شروع یا (مستقیما) خاتمه نمی‌دهند.Intermediate
حد واسط
BPMN (Business Process Model & Notation)همانطور که از نام آن پیداست، رویداد پایان نشان می دهد که یک فرآیند (به صفحه 246 مراجعه کنید) یا رقص (به صفحه 343 مراجعه کنید) به کجا ختم می شود.End
جریان دنباله ای
BPMN (Business Process Model & Notation)شروع و برخی از رویدادهای میانی دارای «محرک‌هایی» هستند که علت رویداد را مشخص می‌کنند (به بخش با عنوان «رویداد شروع» در صفحه 238 و بخش «رویداد میانی» در صفحه 249 مراجعه کنید). راه های متعددی وجود دارد که می توان این رویدادها را تحریک کرد. رویدادهای پایانی ممکن است یک «نتیجه» را تعریف کنند که نتیجه پایان یافتن مسیر جریان توالی است. رویدادهای شروع فقط می‌توانند به (“گرفتن”) یک ماشه واکنش نشان دهند. رویدادهای پایانی فقط می توانند یک نتیجه ایجاد کنند («پرتاب»). رویدادهای میانی می توانند ماشه ها را بگیرند یا پرتاب کنند. برای رویدادها، ماشه‌هایی که می‌گیرند، نشانگرها پر نشده‌اند، و برای ماشه‌ها و نتایجی که پرتاب می‌شوند، نشانگرها پر می‌شوند.        
علاوه بر این، برخی از رویدادها، که برای قطع کردن فعالیت‌ها در BPMN 1.1 استفاده می‌شدند، اکنون می‌توانند در حالتی استفاده شوند که قطع نمی‌شود. مرز این رویدادها شکسته است (شکل سمت راست را ببینید).
Type Dimension (e.g., None, Message, Timer, Error, Cancel, Compensation, Conditional, Link, Signal, Multiple, Terminate.)
نوع ابعاد (به عنوان مثال، هیچ، پیام، تایمر، خطا، لغو، جبران، شرطی، پیوند، سیگنال، چندگانه، خاتمه.)
BPMN (Business Process Model & Notation)فعالیت یک اصطلاح عمومی برای کاری است که شرکت انجام می دهد (به صفحه 151 مراجعه کنید) در یک فرآیند. یک Activity می تواند اتمی یا غیر اتمی (ترکیبی) باشد. انواع فعالیت هایی که بخشی از یک مدل فرآیند هستند عبارتند از: زیر فرآیند و وظیفه که مستطیل های گرد هستند. فعالیت‌ها هم در فرآیندهای استاندارد و هم در رقص استفاده می‌شوند.Activity
فعالیت
BPMN (Business Process Model & Notation)Task یک فعالیت اتمی است که در یک فرآیند گنجانده شده است (به صفحه 156 مراجعه کنید). یک Task زمانی استفاده می شود که کار در Process به سطح دقیق تری از جزئیات فرآیند تجزیه نشده باشد.Task (Atomic)
وظیفه (اتمی)
BPMN (Business Process Model & Notation)یک کار رقص یک فعالیت اتمی در یک رقص است (صفحه 323 را ببینید). این مجموعه ای از یک (1) یا چند تبادل پیام را نشان می دهد. هر کار رقص شامل دو (2) شرکت کننده است. نام کار رقص و هر یک از شرکت‌کنندگان در نوارهای مختلفی که نماد گرافیکی شکل را تشکیل می‌دهند، نمایش داده می‌شوند. دو (2) یا بیشتر باند شرکت کننده و یک گروه نام وظیفه وجود دارد.Choreography Task
وظیفه رقص
چهار شکل بعدی را ببینیدیک فرآیند فرعی یک فعالیت ترکیبی است که در یک فرآیند (به صفحه 173) یا رقص (به صفحه 328 مراجعه کنید) گنجانده شده است. از این جهت مرکب است که می‌توان آن را از طریق مجموعه‌ای از فعالیت‌های فرعی به سطح جزئی‌تری (یک فرآیند یا رقص) تقسیم کرد.Process/Sub-Process (non-atomic)
فرآیند/فرایند فرعی (غیر اتمی)
BPMN (Business Process Model & Notation)جزئیات فرآیند فرعی در نمودار قابل مشاهده نیست (به صفحه 173 مراجعه کنید). علامت “بعلاوه” در مرکز پایین شکل نشان می دهد که Activity یک فرآیند فرعی است و دارای سطح پایین تری از جزئیات است.Collapsed Sub-Process
فرآیند فرعی فروپاشیده
BPMN (Business Process Model & Notation)مرز فرآیند فرعی گسترش یافته و جزئیات (یک فرآیند) در محدوده آن قابل مشاهده است (صفحه 173 را ببینید). توجه داشته باشید که Sequence Flow نمی تواند از مرز یک Sub-Process عبور کند.Expanded Sub-Process
فرآیند فرعی گسترش یافته
BPMN (Business Process Model & Notation)جزئیات رقص فرعی در نمودار قابل مشاهده نیست (به صفحه 328 مراجعه کنید). علامت “بعلاوه” در مرکز پایین نوار نام وظیفه شکل نشان می دهد که فعالیت یک فرآیند فرعی است و دارای سطح پایین تری از جزئیات است.Collapsed Sub- Choreography
رقص فرعی فروپاشیده
BPMN (Business Process Model & Notation)مرز رقص فرعی گسترش یافته و جزئیات (یک رقص) در محدوده آن قابل مشاهده است (صفحه 328 را ببینید).
توجه داشته باشید که سکانس‌ها نمی‌توانند از مرز یک رقص فرعی عبور کنند.
Expanded Sub- Choreography
رقص فرعی گسترده
BPMN (Business Process Model & Notation)یک دروازه برای کنترل واگرایی و همگرایی جریان های دنباله ای در یک فرآیند (به صفحه 287) و در یک رقص (به صفحه 344 مراجعه کنید) استفاده می شود. بنابراین، انشعاب، دوشاخه، ادغام و پیوستن مسیرها را تعیین می کند. نشانگرهای داخلی نوع کنترل رفتار را نشان خواهند داد (به زیر مراجعه کنید).Gateway
دروازه
BPMN (Business Process Model & Notation)نمادهای درون شکل الماسی Gateway نوع رفتار کنترل جریان را نشان می دهد. انواع کنترل عبارتند از:
• تصمیم انحصاری و ادغام. هم Exclusive (به صفحه 290 مراجعه کنید) و هم مبتنی بر رویداد (به صفحه 297 مراجعه کنید) تصمیمات انحصاری را انجام می دهند و ادغام Exclusive را می توان با یا بدون نشانگر “X” نشان داد.
• دروازه های مبتنی بر رویداد و موازی مبتنی بر رویداد می توانند نمونه جدیدی از فرآیند را شروع کنند.
• تصمیم گیری و ادغام دروازه فراگیر (به صفحه 292 مراجعه کنید).
• دروازه مجتمع — شرایط و موقعیت های پیچیده (به عنوان مثال، 3 از 5، صفحه 295).
• انشعاب و اتصال دروازه موازی (به صفحه 293 مراجعه کنید).
هر نوع کنترل بر جریان ورودی و خروجی تأثیر می گذارد.
Gateway Control Types
انواع کنترل دروازه
هفت شکل بعدی را ببینیدیک جریان توالی برای نشان دادن ترتیب انجام فعالیت ها در یک فرآیند (به صفحه 97) و در یک رقص (به صفحه 320 مراجعه کنید) استفاده می شود.Sequence Flow
جریان دنباله ای
BPMN (Business Process Model & Notation)جریان عادی به مسیرهای جریان دنباله ای اشاره دارد که از یک رویداد میانی متصل به مرز یک فعالیت شروع نمی شوند.Normal Flow
جریان عادی
BPMN (Business Process Model & Notation)جریان کنترل نشده به جریانی اطلاق می شود که تحت تاثیر هیچ شرایطی قرار نگیرد یا از یک دروازه عبور نکند. ساده ترین مثال از این یک جریان توالی منفرد است که دو فعالیت را به هم متصل می کند. این همچنین می‌تواند برای جریان‌های دنباله‌ای متعددی که به یک فعالیت همگرا یا واگرا می‌شوند نیز اعمال شود. برای هر Sequence Flow کنترل نشده، یک نشانه از شی منبع از طریق Sequence Flow ها به شی مورد نظر جریان می یابد.Uncontrolled flow
جریان کنترل نشده
BPMN (Business Process Model & Notation)یک Sequence Flow می‌تواند یک عبارت شرطی داشته باشد که در زمان اجرا ارزیابی می‌شود تا مشخص شود آیا Sequence Flow استفاده می‌شود یا خیر (به عنوان مثال، آیا یک نشانه در جریان Sequence Flow حرکت می‌کند – صفحه 97 را ببینید). اگر جریان مشروط از یک Activity خارج شود، آنگاه جریان توالی یک الماس کوچک در ابتدای کانکتور خواهد داشت (شکل سمت راست را ببینید). اگر جریان مشروط از یک Gateway خارج شود، آنگاه خط یک مینی الماس نخواهد داشت (شکل در ردیف بالا را ببینید).Conditional flow
جریان مشروط
BPMN (Business Process Model & Notation)برای دروازه های انحصاری مبتنی بر داده یا دروازه های فراگیر، یک نوع جریان، جریان شرط پیش فرض است (به صفحه 97 مراجعه کنید). این جریان تنها در صورتی استفاده می شود که تمام جریان های مشروط خروجی دیگر در زمان اجرا درست نباشد. این Sequence Flow ها دارای یک اسلش مورب خواهند بود که به ابتدای کانکتور اضافه می شود (شکل سمت راست را ببینید).Default flow
جریان پیش فرض
BPMN (Business Process Model & Notation)جریان استثنا خارج از جریان عادی فرآیند رخ می دهد و بر اساس یک رویداد میانی متصل به مرز یک فعالیت است که در طول اجرای فرآیند رخ می دهد (به صفحه 287 مراجعه کنید).Exception Flow
جریان استثنایی
BPMN (Business Process Model & Notation)یک جریان پیام برای نشان دادن جریان پیام ها بین دو شرکت کننده که آماده ارسال و دریافت آنها هستند استفاده می شود (صفحه 120 را ببینید). در BPMN، دو Pool مجزا در یک نمودار همکاری نشان دهنده دو شرکت کننده خواهند بود (به عنوان مثال، PartnerEntities و/یا PartnerRoles).Message Flow
جریان پیام
BPMN (Business Process Model & Notation)انجمن جبران خسارت خارج از جریان عادی فرآیند رخ می دهد و بر اساس یک رویداد میانی جبران خسارت است که از طریق شکست یک تراکنش یا یک رویداد جبران خسارت ایجاد می شود (به صفحه 302 مراجعه کنید). هدف انجمن باید به عنوان یک فعالیت جبرانی مشخص شود.Compensation  Association
انجمن جبران خسارت
BPMN (Business Process Model & Notation)اشیاء داده اطلاعاتی در مورد آنچه که فعالیت ها برای انجام نیاز دارند و/یا آنچه را که تولید می کنند ارائه می دهند (به صفحه 205 مراجعه کنید)، اشیاء داده می توانند یک شی منفرد یا مجموعه ای از اشیاء را نشان دهند. داده‌های ورودی و خروجی داده‌ها اطلاعات یکسانی را برای فرآیندها فراهم می‌کنند.Data Object
شی داده
BPMN (Business Process Model & Notation)از یک پیام برای نشان دادن محتوای ارتباط بین دو شرکت کننده استفاده می شود (همانطور که توسط یک PartnerRole تجاری یا یک شریک تجاری تعریف شده است – به صفحه 93 مراجعه کنید).Message
پیام
BPMN (Business Process Model & Notation)BPMN از اصطلاح “fork” برای اشاره به تقسیم یک مسیر به دو یا چند مسیر موازی (همچنین به عنوان AND-Split شناخته می شود) استفاده می کند. این مکانی در فرآیند است که در آن فعالیت ها می توانند به طور همزمان انجام شوند، نه متوالی.
دو گزینه وجود دارد:
• جریان های توالی خروجی چندگانه را می توان استفاده کرد (شکل بالا سمت راست را ببینید). این نشان می دهد که جریان “کنترل نشده” روش ترجیحی برای اکثر موقعیت ها است.
• می توان از دروازه موازی استفاده کرد (شکل پایین سمت راست را ببینید). این به ندرت استفاده می شود، معمولاً در ترکیب با سایر دروازه ها.
Fork
چنگال
BPMN (Business Process Model & Notation)BPMN از اصطلاح “پیوستن” برای اشاره به ترکیب دو یا چند مسیر موازی در یک مسیر (همچنین به عنوان AND-Join یا همگام سازی شناخته می شود) استفاده می کند.
یک دروازه موازی برای نشان دادن پیوستن چندین جریان توالی استفاده می شود.
Join
پیوستن
پنج ردیف بعدی را ببینید.تصمیم‌ها دروازه‌هایی در یک فرآیند (به صفحه 287 مراجعه کنید) یا یک رقص (نگاه کنید به صفحه 344) هستند که در آن جریان کنترل می‌تواند یک یا چند مسیر جایگزین را طی کند.Decision, Branching Point
تصمیم، نقطه انشعاب
BPMN (Business Process Model & Notation)این تصمیم یک نقطه انشعاب را نشان می دهد که در آن گزینه های جایگزین بر اساس عبارات شرطی موجود در جریان های دنباله خروجی هستند (به صفحه 290 یا صفحه 345 مراجعه کنید). فقط یکی از گزینه های جایگزین انتخاب خواهد شد.Exclusiv
انحصاری
BPMN (Business Process Model & Notation)این تصمیم یک نقطه انشعاب را نشان می دهد که در آن گزینه های جایگزین بر اساس رویدادی است که در آن نقطه از فرآیند رخ می دهد (به صفحه 297 مراجعه کنید) یا رقص (به صفحه 350 مراجعه کنید). رویداد خاص، معمولاً دریافت یک پیام، تعیین می‌کند که کدام یک از مسیرها طی خواهد شد. می توان از انواع دیگر رویدادها مانند تایمر استفاده کرد. فقط یکی از گزینه های جایگزین انتخاب خواهد شد.
دو گزینه برای دریافت پیام وجود دارد:
• می توان از Tasks of Type Receive استفاده کرد (شکل بالا سمت راست را ببینید).
• می توان از رویدادهای میانی نوع پیام استفاده کرد (شکل پایین سمت راست را ببینید).
Event-Based
مبتنی بر رویداد
BPMN (Business Process Model & Notation)این تصمیم یک نقطه انشعاب را نشان می‌دهد که در آن گزینه‌های جایگزین بر اساس عبارات شرطی موجود در جریان‌های دنباله خروجی هستند (به صفحه 292 مراجعه کنید). به نوعی این یک گروه‌بندی از تصمیم‌های باینری مستقل (بله/خیر) مرتبط است. از آنجایی که هر مسیر مستقل است، تمام ترکیب مسیرها ممکن است از صفر تا همه گرفته شود. اما باید طوری طراحی شود که حداقل یک مسیر طی شود. برای اطمینان از اینکه حداقل یک مسیر طی شده است، می توان از یک شرط پیش فرض استفاده کرد.
دو نسخه از این نوع تصمیم وجود دارد:
• اولین مورد از مجموعه ای از جریان های توالی شرطی استفاده می کند که با الماس های کوچک مشخص شده اند (شکل بالا سمت راست را ببینید).
• دومی از یک دروازه فراگیر استفاده می کند (تصویر پایین سمت راست را ببینید).
Inclusive
شامل
BPMN (Business Process Model & Notation)BPMN از اصطلاح “ادغام” برای اشاره به ترکیب انحصاری دو یا چند مسیر در یک مسیر (همچنین به عنوان OR-Join شناخته می شود) استفاده می کند. یک دروازه انحصاری ادغام برای نشان دادن ادغام چندین جریان توالی استفاده می شود (شکل بالا را ببینید تا سمت راست).اگر تمام جریان ورودی جایگزین باشد، در این صورت به Gateway نیازی نیست. یعنی جریان کنترل نشده همان رفتار را ارائه می دهد (شکل پایین را در سمت راست ببینید).Merging
ادغام
دو شکل بعدی را ببینیدBPMN دو مکانیسم برای حلقه زدن در یک فرآیند فراهم می کند.Looping
حلقه زدن
BPMN (Business Process Model & Notation)ویژگی های Tasks و Sub-Processes تعیین می کنند که آیا آنها یک بار تکرار شده یا انجام می شوند (به صفحه 190 مراجعه کنید). دو نوع حلقه وجود دارد: استاندارد و چند نمونه. یک نشانگر حلقه کوچک در مرکز پایین فعالیت نمایش داده می شود.Activity Looping
حلقه فعالیت
BPMN (Business Process Model & Notation)حلقه‌ها را می‌توان با اتصال یک Sequence Flow به یک شی «بالادست» ایجاد کرد. اگر آن شیء دارای یک جریان توالی خروجی باشد که به یک سری از جریان های توالی دیگر منتهی می شود، یک شیء بالادست در نظر گرفته می شود، که آخرین آنها یک جریان توالی ورودی برای شی اصلی است.Sequence Flow Looping
دنباله جریان حلقه

گزارش ساز یا Report Builder

گزارش ساز

گزارش ساز یا Report Builder ابزاری است که برای ایجاد، طراحی و مدیریت گزارش‌ها از داده‌های مختلف به کار می‌رود. این ابزارها به کاربران اجازه می‌دهند تا به راحتی گزارش‌های متنوع و با کیفیت را تولید کنند و از آن‌ها برای تحلیل و تصمیم‌گیری استفاده کنند. قابلیت‌های گزارش ساز معمولاً شامل موارد زیر است:

اتصال به منابع داده مختلف: امکان اتصال به بانک‌های اطلاعاتی مختلف، فایل‌های اکسل، سرویس‌های وب و دیگر منابع داده.

طراحی گزارش‌های تعاملی: ایجاد گزارش‌هایی با قابلیت فیلتر کردن، مرتب‌سازی، و پیمایش داده‌ها.

خروجی‌گیری متنوع: امکان خروجی‌گیری گزارش‌ها به فرمت‌های مختلف مانند PDF، Excel، Word و HTML.

ایجاد نمودارها و گراف‌ها: توانایی ایجاد انواع نمودارهای میله‌ای، خطی، دایره‌ای و غیره برای نمایش بصری داده‌ها.

سفارشی‌سازی: امکان تنظیم ظاهر و ساختار گزارش‌ها مطابق با نیازها و سلیقه‌های مختلف.

گزارش ساز Highcharts یک ابزار نمودار سازی جاوا اسکریپتی است که امکانات و قابلیت‌های زیادی را برای ایجاد نمودارهای تعاملی و زیبا فراهم می‌کند. برخی از امکانات و قابلیت‌های Highcharts عبارتند از:

پشتیبانی از انواع نمودارها: Highcharts از انواع نمودارهای میله‌ای، خطی، دایره‌ای، مساحتی، پراکندگی و … پشتیبانی می‌کند.

تعامل‌پذیری بالا: نمودارهای ایجاد شده با Highcharts قابلیت تعامل با کاربر از طریق قابلیت‌هایی مانند زوم کردن، بزرگنمایی، نشانگرهای تعاملی و … را دارند.

سفارشی‌سازی گسترده: امکان تنظیم و تغییر ظاهر نمودارها، رنگ‌ها، فونت‌ها، محور‌ها و دیگر اجزای نمودار.

پشتیبانی از داده‌های زنده: قابلیت نمایش داده‌های زنده و به‌روز‌رسانی نمودارها در زمان واقعی.

قابلیت افزوده شدن به صفحات وب: Highcharts به راحتی می‌تواند در صفحات وب ادغام شود و با کتابخانه‌های مختلف جاوا اسکریپت و فریمورک‌ها سازگار است.

مستندات و پشتیبانی قوی: مستندات کامل و مثالی‌های فراوان برای کمک به توسعه‌دهندگان در استفاده از این ابزار.

Highcharts به دلیل قابلیت‌های متنوع و کاربرپسند بودن، یکی از ابزارهای محبوب برای ایجاد گزارش‌ها و نمودارهای تعاملی است.