Get Mystery Box with random crypto!

اهمیت Side-effect Free و Idemponency در کدنویسی برنامه نویسی | DotNetZoom

اهمیت Side-effect Free و Idemponency در کدنویسی

برنامه نویسی Functional Programming (به اختصار FP) در تعریف، یک Paradigm (پارادایم) برنامه نویسی هست که در اون برنامه ها به کمک ترکیب توابع ساخته میشن. (چه تعریف گنگ و غیر ملموسی!)
از اونجایی که "پارادایم" کلمه غیر ملموسی هست و اگر اولین بارتون باشه که اون رو میشنوین احتمال زیاد مفهومش رو متوجه نمیشین اینطور تعریفش میکنم: پارادایم برنامه نویسی یعنی یک روش یا رویکرد برنامه نویسی.
این رویکرد مفاهیم مختلفی رو داخل خودش داره که اینجا نمیخوام واردشون بشم. چیزی که اینجا میخوام روش تاکید کنیم 3 مفهوم زیر هست:
1- Side-effect Free
2- Idempotent
3- Pure Functions

مفهوم Side-effect Free
این مفهوم به این اشاره میکنه که یه تابع (متد) نباید "تاثیر جانبی" روی بقیه قسمت های برنامه داشته باشه. خب این یعنی چی؟ کی ما تاثیر جانبی رو بقیه میذاریم؟
وقتی متد ما یک shared state تغییر رو بده. shared state به معنی متغیر/مقدار ایی هست که بین چندین تابع یا قسمت مختلف برنامه مشترک هست.
پس در واقع وقتی یک تابع، متغیری یا مقداری را که بین چندین تابع یا قسمت های مختلف برنامه مشترک هست رو "تغییر" بده یعنی side-effect اتفاق افتاده

در کنار این مفهوم، مفهوم دیگری نیز وجود داره به نام Avoiding Shared State که تاکید میکنه از ایجاد و استفاده از shared state ها خودداری کنیم.
وجود shared state خواسته یا ناخواسته باعث بروز side-effect میشه. پس خودداری از اون باعث میشه به side-effect نیز برنخوریم یا کمتر بر بخوریم

مفهوم Idempotent
این مفهوم به این امر اشاره میکنه که زمانی توابع ما Idempotent هستند که اگر اونها رو هرچند بار هم با مقادیر ورودی ثابت و مشابه فراخوانی کنیم همیشه نتیجه یا خروجی یکسان و ثابتی داشته باشه
مثلا تابعی که یک مقدار Random رو برمیگردونه Idempotent نیست چرا که هربار نتیجه اش متفاوته؛ همینطور تابعی که DateTime.Now رو برمیگردونه.

مثال کاربردیش توی دنیای واقعی، متدی میشه که وظیفه حذف یک رکورد رو داره. به این صورت که (مثلا از EF استفاده میکنه و) ابتدا رکورد رو با id مورد نظر واکشی میکنه سپس اون رو به متد Remove میده و SaveChanges فراخوانی میشه
خب بار اولی که این متد رو با id برابر با 100 فراخوانی کنیم اون سطح حذف میشه ولی بار دومی که اون رو "با همین id" فراخوانی میکنیم به exception بر میخوره چرا که دیگه اون رکورد وجود نداره که بخواد حذفش کنه (موقع find، مقدار اون رکورد null هست و متد Remove با ورودی null خطا میده)
ولی همین متد رو اگر به این صورت پیاده سازی کنیم که قبل از حذف کردن، چک کنه که اگر این رکورد وجود نداره کاری انجام نده، متد ما Idempotent میشه چرا که هر چندبار فراخوانی اون، یک نتیجه رو داره و اون هم اطمینان از حذف اون رکورد هست

مفهوم Idempotent بودن توی معماری Event-Driven و الگوی Pub/Sub هم اهمیت بسیار بالایی داره. از اونجایی که یک Event یا Message ممکنه به هر دلیلی "بیش از یکبار" توسط Subscriber ها پردازش بشه. باید اطمینان داشته باشیم که نتیجه یکسانی داره و عملکرد سیستم رو تحت تاثیر نمیگذاره (مثلا فرض کنید برای یک سفارش، دو تا فاکتور برای مشتری ثبت بشه!)

نمیخوام خیلی وارد روش های Idempotency بشم فقط اینکه معمولا 2 روش وجود داره:
1- طوری پیاده سازی کنیم که چند دفعه اجرا شدنش توی عملکردش تاثیری نداشته باشه
2- یک flag ایی رو به ازای هر Message داشته باشیم که وقتی اون Message پردازش میشه اون رو true کنیم و دفعات بعدی با چک کردن این flag و متوجه شدن از اینکه قبلا پردازش شده، دیگه پردازشش نکنیم (در این حالت ممکنه استفاده از تکنیک های synchronization مانند locking لازم باشه)

مفهوم Pure Functions
این مفهوم تعریف خیلی ساده ای داره، تابعی Pure Function (خالص) هست که هم Side-effect Free باشه هم Idempotent. در غیر این صورت میشه Impure Function (تابع ناخالص)

جمع بندی
مفاهیم Functional Programming الزاما نیاز به استفاده از زبان های FP (مثل FSharp یا Scala یا Haskell) ندارن. خیلی از اون مفاهیم به راحتی داخل زبان های دیگه و رویکرد Object Oriented Programming نیز قابل استفاده و بسیار مفید هستند و باعث Maintainability و Reliability میشن (نگهداری بهتر کد ها و قابل اعتماد تر بودنشون)
توصیه میکنم که اون مفاهیم رو یاد بگیرید و بسته به نیازتون توی کدنویسی های OOP تون هم ازش استفاده کنید


دوستان یه مقدارش جا نشد. (مخصوصا قسمت مزایاشون)
متن کامل رو توی مقاله زیر بخونین
https://vrgl.ir/GMNeu
______________
@DotNetZoom