پیشگفتار:
مدتی است که با خود میاندیشم تجربیاتم را در حوزهی نرمافزار در اینجا بنویسم، هم ماندگار خواهد شد و هم شاید به دوستی کمک کند. نمیدانم “الگوی ایجاد نرمافزار” عبارت مناسبی هست یا نه، ولی تا یافتن عبارت مناسبتر از آن استفاده خواهم کرد.
قرارداد:
قرارداد یا عقد یا پیمان یا کنترات یک توافق الزامآور میان اشخاص است که حقوق و تکالیف طرفین آن را تعیین میکند. در تعبیر حقوقی به توافق دو یا چند اراده در جهت ایجاد یک اثر حقوقی گویند. [ویکی پدیا]
همان طور که از متن تعریف بر میآید قرارداد، “حقوق” و “تکالیف” طرفین را تعیین میکند. برای نمونه در قرارداد پروژه بین پیمانکار و کارفرما تعیین میشود که پیمانکار چه “تکالیف” و چه “حقوقی” دارد و همین طور کارفرما چه “تکالیف” و “حقوقی” دارد. برای مثال در یک پروژهی نرمافزاری، پیمانکار مکلف است تا پایان ماه اول، پروتوتایپ سیستم را به کارفرما تحویل دهد و تحویل پروتوتایپ در پایان ماه اول، حق کارفرماست. برای انجام پروتوتایپ، کارفرما مکلف است تا مستندات تعیینشده را در اختیار پیمانکار قراردهد (تکلیف کارفرما).
به زبان سادهتر:
– کار: تهیه پروتوتایپ
– تکالیف کارفرما: تحویل مستندات تعیینشده به پیمانکار
– تکالیف پیمانکار: تحویل پروتوتایپ در مدت یک ماه
قراردادها در برنامهنویسی:
تا جایی که میدانم هر سیستم نرمافزاری از مجموعهای از عناصر یا المانها تشکیل شده است. این عناصر میتوانند اجزایی مانند تابع (function)، کلاس (class) یا رویهها (procedure) باشند. این عناصر با مکانیزمهایی میتوانند با همدیگر تعامل کنند. یک تابع میتواند تابع دیگری را صدا کند و آن تابع نیز به نوبهی خود میتواند تابع بعدی را صدا کند. این زنجیرهی تعامل یعنی کنش و واکنش بین اجزای سیستم، رفتار آن را شکل میدهد.
اجازه بدهید در سادهترین حالت ممکن بحث را ادامه بدهیم. فرض بفرمایید دو تابع f و g وجود دارند. تابع f برای انجام کاری تابع g را صدا میکند. کار مورد درخواست را هم محاسبه ریشهی دوم یک عدد طبیعی (۱,۲,۳,…) تعریف مینماییم.
در این حالت میتوانیم فرض کنیم که تابع f مانند کارفرما و تابع g مانند پیمانکار عمل خواهند کرد. نتیجه:
– کارفرما: تابع f
– پیمانکار: تابع g
– موضوع قرارداد: محاسبه ریشهی دوم یک عدد طبیعی
حالا بیایید کمک کنیم تا بین تابع f و g قراردادی منعقد شود:
– کارفرما مکلف است که فقط اعداد طبیعی را ارسال کنید
– کارفرما محق است که ریشهی دوم عدد ارسال شده را به صورت یک عدد با دو رقم اعشار دریافت کند
– پیمانکار مکلف است که ریشهی دوم عدد را به دو رقم اعشار گرد کند (round)
– پیمکانکار محق است که عدد طبیعی دریافت کند در غیر این صورت مکلف است خطا یا استثناء (Exception) را گزارش نماید.
حالا که قرارداد بین کارفرما و پیمانکار منعقد شد، میتوانیم پیادهسازی تابع g را شروع کنیم. پیادهسازی را میتوان به سه بخش تفکیک کرد:
– بخش اول: تابع g ابتدا باید کنترل کند که عددی که دریافت کرده، یک عدد طبیعی (صحیح و بزرگتر از صفر) است. طبق قرارداد، اگر عدد دریافتی، یک عدد طبیعی نباشد، تابع g باید خطا یا استثناء را گزارش کند (بازگرداندن کد خطا یا پرتاب استثناء (Throw Exception)).
– بخش دوم: تابع g باید روشی برای محاسبه ریشهی دوم یک عدد طبیعی پیادهسازی کند. برای انجام این کار، میتوان از “تقریب” در ریاضیات استفاده کرد.
– بخش سوم: مطابق قرارداد، نتیجهی به دست آمده در مرحلهی قبل باید به دو رقم اعشار گرد شود و به کارفرما یعنی تابع f بازگردانده شود.
تمام!
پسگفتار:
این شیوهی نگاه به اجزای نرمافزاری در قالب یک کارفرما، یک پیمانکار و یک قرارداد، روشی ساده، مفید و کاربردی برای طراحی و پیادهسازی در نرمافزار است. ایدهی اصلی این الگو از روش “طراحی با قرارداد” (Design By Contract) است. این روش که توسط برتراند مایر ابداع شده است در دنیای شیءگرایی بسیار معروف و جاافتاده است.
نکتهای که در این الگو به آن افزوده شده این است که با در نظر نگرفتن شیگرایی و انتقال این ایده به عناصری مانند تابع (function)، این الگو برای زبانهایی که ماهیت شیءگرایی هم ندارند قابل استفاده است از جمله پایتون و جاوا اسکریپت.
امیدوارم که قراردادهای بسیار باارزشی منعقید کنید!
گزیده:
اگر میخواهید سریعتر پیش بروید، اگر میخواهید سریعتر کارها را تمام کنید، اگر میخواهید نوشتن کد برایتان آسان و راحت باشد، کاری کنید که خواندن کدتان آسان و راحت باشد.
رابرت سی. مارتین
دیدگاهتان را بنویسید