نگاه ساده به برنامه نویسی شی گرا یا OOP در زبان MQL


خیلی از ما شده که خواستیم برنامه نویسی شی گرا رو یاد بگیرم اما با اسم و کلماتی برخوردیم که کلا قید یاد گیری این سبک کد زنی رو زدیم! تو این نوشته می خوام خیلی ساده شده اما کاربردی و با مثال جوری که خودم این سبک رو داخل ذهنم مدل کردم براتون توضیح بدم، راستی این اولین نوشته منه و خیلی خوشحال میشم که با نظراتتون به من کمک کنید که نوشته های بعدی بهتر بشه...

به صورت کلی بخوام بگم با شی گرایی ما میایم کدمون رو مرتب میکنیم و نظم میدیم،فرض کنید شما یه اتاق دارید که وسایل تون توش کاملا به هم ریخته و رندوم داخلش چیده شده، وقتی شما میاید وسایل تون رو مرتب میکنید مثلا نوشت افزارها یک طرف، کامپیوتر و موارد مرتبط با اون یک طرف یا حتی وسایل آرایشی و بهداشتی تون در یک طرف باشه در اصل دارید مواردی که داخل اتاق هست رو به گونه ای طبقه بندی می کنید! به این طبقه بندی یا categorize تو شی گرایی میگیم Class بندی کردن.

دقیقا همون واژه کلاس که تو مدرسه به کار میره و دانش آموز مقاطع تحصیلی مختلف رو دسته بندی می کنه. به زبون برنامه نویسی بخوام بگم فرض کنید شما یه فایلی دارید که توابعی که تو اکثر پروژه هاتون باهاش کار میکنید اونجاست و شما این فایل رو میاید داخل فایل های دیگه ایمپرت میکنید (یا include میکنید)، حالت اول اینکه بیاید خیلی به هم ریخته تابع با وظایف مختلف رو کنار هم دیگه بزارید و هر دفه کلی دنبال یه تابع بگردید اما حالت دوم این میشه که مثلا توابعی که برای ارسال یا ویرایش سفارش هستند (برای بچه های mql کار مثلا) یه جا بنویسید و یا توابعی که مربوط به مدیریت حجم معامله هستند رو هم کنار هم و یه جا، وقتی ما این کار رو بکنیم در اصل یه Class برای Trade و یه Class برای Money Management ساختیم.

خلاصه وار بگم تا اینجا class بندی به معنی دسته بندی هستش.

اما Encapsulation چیه؟

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

به عبارتی کلی فرایند هست که از دید شما مخفیه، به این کار میگن Encapsulate کردن.

فرض کنید شما می خواین پیدا کنید که کمترین قیمت close توی 100 تا کندل گذشته چیه، توی mql5 مثلا شما باید بیاید پیدا کنید که اولا اندیس اون کندلی که کمترین قیمت رو داره چیه و در مرحله بعد اون اندیس رو استفاده کنید تا مقدار کمترین قیمت close رو بدست بیارید، اما اگه بخواید از oop استفاده کنید شما صرفا دستور میدید که مقدار کمترین close رو برای شما برگردونه و این خود class هست که باید اول بره اندیس رو پیدا کنه و بعد از اون اندیس برای گرفتن مقدار استفاده کنه و شمای کاربر دیگه درگیر این مسیئله نمیشید ( درست مثل اینکه رفتید رستوران و غذا رو سفارش دادید و از اینجا به بعد درگیر اینکه چطور این غذا اماده میشه نمیشید)

خلاصه این بند هم میشه اینکه اون عملیات های میانی که از دیدکاربر حذف میشن رو میگیم Encapsulation


اما این Encapsulation لول بندی های مختلفی داره که این سه تا واژه رو ما زیاد می بینیم، Public ، Private و Protected

public :

بخش public یعنی اون تابعی که اینجا می نویسیم وقتی کاربر بیاد از دات استفاده کنه براش نمایش داده میشه، در واقع همون متد هایی که بعد از دات برای ما نمایش داده میشن در بخش public کلاس خودشون نوشته شدن، یه جورایی مثل منوی رستوران که به مشتری نشون داده میشه

Private :

این بخش توابع یا حتی متغیرهای میانی که در حین خروجی نهایی استفاده میشن میان (مثل همون تابعی که کارش پیدا کردن اندیس کندل بود) ، مواردی که اینجا نوشته میشه به کاربر نمایش داده نمیشن و صرفا در داخل خود class کاربرد دارن. درست مثل دستور پخت یه غذای خاص که صرفا مختص همون رستورانه و حتی داخل شعبه های دیگه رستوران هم نیست ( این که داخل شعبه های دیگه هم نیست رو بعدا میگم چرا اشاره کردم) و قاعدتا شمای مشتری هم ازش خبردار نیسی.

Protected :

این بخش رو می خواستم وقتی ارث بری رو توضیح دادم مطرحش کنم، اما به خاطر اینکه سلسله مطلب خراب نشه میگم ، اول باید ارث بری یا Inheritance رو بگم، خیلی ها اینجوری توضیحش میدن که مثلا حیوانات یا انسان ها ممکنه یه سری خصلت ها به بچه هاشون ارث بدن ( مثلا کچلی یا دماغ بزرگ ) اما من بخوام طبق مثال خودمون بگم فرض کنید که یه رستوران زنجیره ای میاد شعبه های دیگه رو افتتاح میکنه و لیست و منوی غذاش رو از اون شعبه مادر میگیره ( به ارث می بره)

حالا اون شعبه اصلی ممکنه 100 تا دستور پخت داشته باشه که 90 تا رو در اختیار شعبه های دیگه قرار داده اما 10 رو برای خودش نگه داشته، اون 90 تا دستور که فقط در اختیار رستوران و شعبه هاشه (نه مشتری) تو برنامه نویسی میان در قسمت protected نوشته میشن ( یعنی از دید کاربر محافظت شدن یا مخفی شدن) و اون 10 موردی که صرفا برای شعبه اصلی و مادر بود و به زیر مجموعه ها نشون داده نشد رو در قسمت private می نویسن.

پس در کل تفاوت private و protected در اینکه با کلاس های فرزند (child) به اشتراک گذاشته بشن یا خیر.

تو mql اگه شما بخواین قسمت private یه class رو فراخونی کنید با این ارور مواجه میشید

"Can not call private member function"

اما over load کردن چیه؟
توی mql ما حتما باید جنس ورودی هامون به توابع رو بدونیم و همون تایپ رو پاس بدیم، فرض کنید من یه تابع دارم به اسم sum_of_two() که میاد دوتا ورودی میگیره و باهم جمع میکنه، حالت اول اینکه من این تابع رو اینجوری تعریف کنم

sum_of_two(int a , int b) الان حتما باید عدد صحیح بدم و اگه عدد اعشار بدم به صحیح تبدیل میشه، اما می تونیم از همین اسم استفاده کنم و نوع ورودی هام رو تغییر بدم، mql خودش تشخیص میده که از خودم استفاده کنه به عبارتی من این دوتا تابع رو دارم

sum_of_two(int a , int b) و sum_of_two(double a , double b)

و خود mql باتوجه به تایپ ورودی های من تشخیص میده که از کدوم استفاده کنه، به این کار میگن overload کردن.

حالا بریم سراغ Constructor و Destructor

هرکاری از جمله اجرای یه برنامه به صورت کلی سه تا بخش داره ، بخش آغازین ، بخش میانی و بخش پایانی (غیب گفتم)، بخش میانی میشه همون وظیفه ای که برای کد مشخص کردیم اما قبل از اجرای وظایف اصلی شاید بخوایم یه سری چیزا انجام بشه، مثلا یه سری متغیرها مقدار دهی بشن یا یه سری اسم ها تغییر کنن ، یا یه مثال دیگه فرض کنید می خواین یه جشن تولد برگزار کنید، اینکه بیاید صندلی ها رو بچینید یا کیک رو اماده کنید میشه بخش میانی که برای اجرای یه جشن تولد باید حتما انجام بشن

اون وظایفی که به محض اینکه یه class فراخونی شد باید انجام بشه رو تو Constructor می نویسیم. که تابع constructor با خود کلاس هم اسمه.

اون Destructor هم که از اسمش مشخصه، همون توابعی هست که وقتی یک class برای برنامه unload میشه اجرا میشن، مثلا قسمت Comment رو پاک کنه یا فضای اختصاص داده شده رم به ارایه رو حذف کنه و چیزای اینطوری ، یا تو مثال جشن تولد مون میشه شستن ظرف ها، ترکوندن بادکنک های باقی مونده و مرتب کردن خونه

فقط یادتون باشه که Constructor و Destructor به صورت اتومات اجرا میشن و ما به صورت صریح فراخونی شون نمی کنیم.

در انتها ببینیم Virtual چیه؟
گفتیم شعبه رستوران میاد اسامی غذا ها رو از شعبه اصلی میگیره، حالا ممکنه شعبه اصلی بعضی از غذاها رو به زیر مجموعه ها اجازه بده که طبق سلیقه خودشون سرو کنن ، مثلا زرشک پلو با مرغ رو دوس داشته باشن متفاوت از شعبه اصلی سرو کنن، اینکه اجازه داشته باشن کدوم از غذاها رو (با همون اسم که تو لیست هست) متفاوت از شعبه اصلی سرو کنن رو باید شعبه اصلی حتما مجوزش رو ذکر کرده باشه، این مجوز میشه virtual
به عبارتی وقتی ما میایم یک تابع رو به صورت virtual در قسمت public کلاس اصلی ( همون قسمت که کلاس های فرزند ازش ارث بری می کنن) می نویسیم، این اجازه رو به فرزندان میدیم که از اون اسم استفاده کنن و هرجوری که دلشون می خواد اون تابع با همون اسم رو برای خودشون تعریف کنن.


به همین سادگی بود همش :)

ممنون میشم ازت اگه نظرت رو بهم بگی تا تو نوشته های بعدی حتما ازش استفاده کنم

راستی اینم سایت منه که به همین سبک میام زبان MQL4 رو توضیح میدم ، خوشحال میشم بم سر بزنی

https://mqlcoder.ir/ea-tutorial/