محمد میرزائیان
محمد میرزائیان
خواندن ۱۶ دقیقه·۵ سال پیش

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

یکی از موضوعاتی که همیشه وقتی توی پروژه های مختلف از موتورهای فرآیندی استفاده می کردیم ذهن منو درگیر می کرد این بود که چطور روال تاییدات بین مدیران یا کارشناسان را پیاده سازی کنیم . و خوب البته ایده ها و چالش های مختلفی در کنار این موضوع مطرح بودند . که این چالش ها را از اونجایی که ممکنه برای شما هم جالب باشه و یا اینکه روش های حل مختلفی رو براش داشته باشید اینجا لیست می کنم :

۱- چالش اول ، امکان داینامیک بودن روال تاییدات بود ، یعنی کاربر از طریق سامانه این قابلیت را در اختیار داشته باشد که خودش روال تاییدات رو تنظیم کند .

۲- چیدمان بر اساس چارت سازمانی ، هر سازمانی بر اساس چارت خود و با توجه به ادبیات سازمانی خود روال تاییدات را تعیین می کند

۳- امکان ویرایش اطلاعات رکورد مربوط به کسب وکار در حین روال تاییدات ، در برخی موارد حتی تاریخچه ویرایش رکورد ها توسط کاربران نیز مهم است .

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

نکته ای که قبل از خوندن ادامه این مقاله باید در نظر بگیرید این هست که باید با مفاهیم و المنت های موجود در BPMN 2.0 آشنا باشید ، همچنین مطالب ذکر شده بر روی موتور فرآیندی Camunda پیاده سازی و تست شده است اما ممکن است مطالب عنوان شده در این مقاله بر روی سایر موتور های فرآیندی نیز قابل پیاده سازی و انجام باشد مانند Activiti و Flowable.

همین طور برای تعامل با Camunda نیز از Integration آن با Spring استفاده شده است .

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

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

مدل داده ای برای تعیین سلسله مراتب تاییدات
مدل داده ای برای تعیین سلسله مراتب تاییدات

قطعا در هر سامانه در یک جدول اطلاعات کاربران نگهداری می شود که به کمک جدول USER نمایش داده شده و به ازای هر فرآیند در سطح سامانه می توان اولویت ۱و۲و۳و.. تاییدات را به کمک جدول CONFIRMATION_PRIOIRTY به کاربران مختلف نسبت داد .

در ادامه با روش های پیاده سازی این موضوع در BPMN آشنا خواهیم شد .

روش اول ( پیاده سازی ضمنی حلقه )

امکان ایجاد حلقه ضمنی در فرآیند های BPMN در حالات مختلفی ممکن است پیش بیاید و کارشناسان فرآیندی و یا برنامه نویسان در حالات مختلفی ممکن است اقدام به ایجاد یک حلقه ضمنی کنند . برای آشنایی بیشتر با این روش قبل از هر نکته ای BPMN آن را در تصویر زیر مشاهده می کنیم :

ایجاد حلقه ضمنی در BPMN
ایجاد حلقه ضمنی در BPMN

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

اگر بخواهیم به شکل بهتری که این حلقه ضمنی دقیقا کدام بخش از فرآیند است ، در تصویر المنت هایی که حلقه ضمنی را ایجاد کرده اند با رنگ سبز مشاهده می کنید :

ایجاد حلقه ضمنی در BPMN
ایجاد حلقه ضمنی در BPMN


روش دوم - استفاده از Multiple Instance

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

شکل BPMN گفته شده در روش قبلی به شکل زیر تغییر خواهد کرد :

در روش قبلی ما با ایجاد Loop در BPMN چندین UserTask را ایجاد می کردیم اما در روش فعلی ما یک UserTask با قابلیت Multiple Instance داریم و خود این فعالیت به تعداد مورد نیاز UserTask های لازم را در موتور فرآیندی ایجاد خواهد کرد .

دقت کنید در ادامه هر جا در مورد فعالیت والد صحبت شد منظور UserTask اصلی است و هر جا از فعالیت فرزند صحبت شد منظور UserTask هایی است که به وسیله فعالیت Multiple Instance ایجاد شده است .

در موتورهای فرآیندی Task ها دارای انواع مختلفی هستند ، همچنین Task ها رو می توان با برخی علامت گذاری ها به برخی قابلیت ها مجهز کرد ، این علامت گذاری ها شامل Loops ، Multiple Instance و یا Compensations هستند . همین طور می توان بر روی یک تسک از چندین علامت گذاری استفاده کرده و آن ها با هم ترکیب کرد و به رفتار مورد نیاز رسید . در این بخش ما Multiple Instance را برای حل مساله مورد نظر استفاده خواهیم کرد .

در یک فرآیند می توان از فعالیت های Multiple Instance استفاده کرد ، استفاده از این فعالیت ها یکی از روش های مناسب برای تعریف تکرارها در گام های مختلف یک مدل فرآیندی است . در مفاهیم برنامه نویسی یک حلقه for-each معادل یک فعالیت Multiple Instance در یک فرآیند است .

فعالیت Multiple Instance به ما اجازه می دهد یک فعالیت را چندین بار برای یک گام خاص از فرآیند تکرار کنیم و یا یک Sub-process را به ازای یک مجموعه ( Collection ) به صورت Sequential و یا Parallel اجرا کنیم .

فعالیت های زیر قابلیت اجرا به صورت multi-instance را دارند :

  • Service Task
  • Send Task
  • User Task
  • Business Rule Task
  • Script Task
  • Receive Task
  • Manual Task
  • Embedded Sub Process
  • Call Activity
  • Transaction Sub Process

همچنین باید به این نکته دقت کرد که Gateway ها و Event ها نمی توانند به صورت Multiple Instance اجرا شوند .

اگر یک فعالیت به صورت Multiple Instance تعریف شود به کمک یک خط کوچک در زیر آن فعالیت مشخص می شود ، سه خط عمودی مشخص خواهد کرد که این فعالیت به صورت Parallel اجرا خواهد شد و همچنین سه خط افقی مشخص می کند که این فعالیت به صورت Sequential اجرا می شود .

نمونه ای از فعالیت Parallel  و Sequential
نمونه ای از فعالیت Parallel و Sequential

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

هر فعالیت Multiple Instance ( منظور فعالیت والداست ) دارای متغیر های زیر خواهد بود :

  • تعداد کل فعالیت ها ( nrOfInstances )
  • تعداد فعالیت های فعال جاری (nrOfActiveInstaces ): منظور Instance هایی است که هنوز پایان نیافته اند . برای فعالیت های Sequential این متغیر همیشه یک خواهد بود .
  • تعداد فعالیت های اتمام یافته (nrOfCompltedInstances) : تعداد فعالیت هایی که در حال حاضر تکمیل شده اند .

این مقادیر می توانند به کمک متد execution.getVariable(x) برگردانده شده و مورد استفاده قرار بگیرند .

به علاوه ، هر فعالیت ایجاد شده برخی متغیر های محلی مربوط به خود را دارد که این متغیر ها توسط سایر فعالیت ها قابل مشاهده نیستند و در سطح ProcessInstance ذخیره نمی شوند .

همچنین به کمک متغیر LoopCounter می توان index مربوط به for-each مورد نظر را پیدا کرد .

برای تبدیل فعالیت ها ، به یک فعالیت multi-instance بایستی xml مربوط به آن فعالیت دارای المنت multiInstanceLoopCharacteristics باشد :

مشخصه isSequential مشخص خواهد کرد که این فعالیت به صورت Sequential یا Parallel اجرا شود .

یکی از نکات بسیار مهمی که در مورد فعالیت Multiple Instance اهمیت دارد این است که ، تعداد نمونه های فعالیت ها یک بار محاسبه خواهد شد و این محاسبه زمان ورود به فعالیت انجام خواهد شد. راه های متفاوتی برای تنظیم این موضوع وجود دارد . که در ادامه به تشریح این روش ها می پردازیم .

Loop Cardinality

یکی از روش هایی که می توان به کمک آن تعداد تکرار یا تعداد فعالیت های Multiple Instance را مشخص کرد ، تعیین مستقیم متغیر Loop Cardinality است .

باید دقت شود که تعداد تکرارها قابلیت تعیین به صورت ثابت و داینامیک را دارد ، اگر بخواهیم برای مثال گفته شده در مقاله یعنی تایید مرخصی کارمندان این متغیر را تعیین کنیم ، از آنجایی که تعیین روال تاییدات در اختیار کارشناسان سامانه است و ممکن است تغییر کند حتما باید به صورت داینامیک تنظیم شود و بایستی تعداد کارشناسان تایید کننده در این متغیر قرار بگیرد . ما در نظر گرفتیم که رییس شخص درخواست دهنده و کارشناس کارگزینی بایستی درخواست مرخصی کارمندان را تایید کنند در نتیجه در این حالت مقدار متغیر Loop Cardinality برابر ۲ خواهد بود .

این مشخصه از دو روش قابل تنظیم است ، روش اول از طریق Properties های مربوط به فعالیت مورد نظر در نرم افزار Camunda Modeler و روش دوم به کمک xml که تصویر هر دوی این روش ها در زیر قابل مشاهده است .

تنظیم متغیر Loop Cardinality  در نرم افزار Camunda Modeler
تنظیم متغیر Loop Cardinality در نرم افزار Camunda Modeler

در xml مربوط به فایل bpmn نیز به صورت زیر می توان این مشخصه را مقدار دهی کرد :

تنظیم متغیر Loop Cardinality  از طریق xml
تنظیم متغیر Loop Cardinality از طریق xml

همچنین می توان این متغیر را از طریق expression نیز مقدار دهی کرد که در واقع مقدار دهی داینامیک به این مشخصه به این روش صورت می گیرد :

همچنین این قابلیت وجود دارد از طریق فراخوانی یک وب سرویس به مقدار این متغیر دست پیدا کرد و مقدار مورد نظر را در این متغیر قرار داد .

Collection

یک روش دیگر برای مشخص کردن تعداد فعالیت ها مشخص کردن نام یکی از Process Variable ها است که در واقع یک collection است ، استاندارد BPMN روشی را معرفی کرده است که می توان از طریق متغیر LoopDataInputRef این Collection را مشخص کرد اما بایستی دقت شود که این متغیر از طریق xml قابل مقدار دهی است و از طریق نرم افزار Camunda Modeler قابل مقدار دهی نمی باشد .

در این روش به ازای هر عضو موجود در collection مورد نظر یک نمونه یا instance ایجاد خواهد شد .

همچنین پارامتری وجود دارد که شما می توانید به صورت اختیاری تنظیم کنید ، که هر Instance به کدام فیلد از آبجکت collection شما دسترسی داشته باشد و بتواند با آن کار کند :

در نظر بگیرید که متغیر assigneeList شامل مقادیر [ رضا ، علی ، محمد ] است . قطعه xml بالا ، سه Task را به صورت Sequential ایجاد خواهد کرد . هر کدام از excution ها دارای یک متغیر با نام assignee هستند که از مقادیر مجموعه تعریف شده هستند و برای assign کردن Task استفاده خواهند شد .

یکی ایرادات بزرگی که دو متغیر loopDataInputRef و InputDataItem دارند این است که بر اساس قواعد و محدودیت های BPMN 2.0 نمی توانند شامل expression باشند و همین طور باید از طریق xml مقدار دهی شوند . از این رو موتور فرآیندی Camunda این موضوع را به کمک مشخصه های collection و element variable بر روی multi-instance ها حل کرده است که به سادگی این موضوع از طریق نرم افزار Camunda Modeler قابل تنظیم است .

اگر بخواهیم مثال گفته شده ، یعنی تایید مرخصی کارمندان را به کمک این روش حل کنیم ما بایستی یک متد در اختیار داشته باشیم که لیستی از کاربران تایید کننده را از مدل داده ConfirmationPriority برای ما فراخوانی کند که در متغیر Collection قرار می گیرد و شناسه کاربری افراد تاییده کننده ( یعنی رییس شخص درخواست دهنده و کارشناس کارگزینی ) به عنوان Element Variable استفاده خواهد شد .

مدل داده ای جهت درک بهتر مجددا قرار داده شد .

شرط اتمام Multiple Instance

یک فعالیت Multiple Instance زمانی پایان می یابد که تمام فعالیت های زیر مجموعه مربوط به آن پایان یافته باشند . اما این قابلیت وجود دارد که یک expression مشخصی کنیم که هر بار یک Instance از این فعالیت تمام می شود بررسی شود اگر نتیجه این expression برابر با صحیح (True) بود ما بقی Instance های باقی مانده از بین برود و اجرا نشود و اجرای Multiple Instance خاتمه بیابد ، یعنی عملا کار به ادامه ی فرآیند ، یعنی بعد از فعالیت multi-instance می رود .

نمونه ای از این رفتار را در فرآیند زیر می بینیم که از طریق متغیر Complete Condition در نرم افزار Camunda Modeler مشخص شده است :

در مثال گفته شده که به روش Parallel پیاده سازی شده است وقتی 60% تسک ها تکمیل می شوند مابقی آن ها حذف شده و فرآیند ادامه پیدا خواهد کرد .

می توان حالتی را نیز برای روش Sequential در نظر گرفت که وقتی نظر یکی از کارشناسان رد کردن درخواست بود فعالیت ادامه پیدا نکند :


Loops

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

اما این چشم انداز در Camunda دیده شده که قابلیت پشتیبانی از استاندارد Loop مربوط به Bpmn را به موتور فرآیندی خود اضافه کند .

برای رفع این محدودیت روشی که در ابتدای مقاله عنوان شد یعنی ایجاد حلقه به طور ضمنی روش مناسبی خواهد بود .

نتیجه گیری

یکی از بزرگترین ایراداتی که Multiple Instance ها دارند این است که تعداد تکرار آن ها بایستی قبل از ورود به آن ها مشخص شود که این موضوع ممکن است در برخی حالات آن ها را گزینه مناسبی برای ایجاد حلقه های تکرار ندانیم . اما قطعا برای برخی حالات کاملا مناسب خواهند بود .

جهت درک بهتر در مثال تایید مرخصی کارمندان چنانچه در حین فرآیند تایید مرخصی یکی از کارمندان سلسه مراتب تاییدات توسط مدیر ارشد سیستم تغییر کند و یک فرد اضافه یا حذف شود این تغییر بر روی فرآیند های در حال اجرا تاثیر نخواهد گذاشت .

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


bpmncamundajavaworkflowbpms
برنامه نویس جاوا
شاید از این پست‌ها خوشتان بیاید