تو قسمت قبلی اومدیم interface ها و abstract کلاس ها برسی کردیم و یکسری توضحیات درمورد دلیل استفاده شون اوردیم همراه با یک مثال و تو این قسمت تمرکز اصلی روی پیاده سازی به زبان پایتون هستش و جاهایکه این دوتا مفهوم میتونن مورد استفاده قرار بگیرنو میبینم همراه با چندتا مثال خوب
اگه قسمت ۱ خونده باشید مطمعنن میدونید که ما مفهوم مستقلی به اسم interface ها و یا abstract کلاس ها نداریم تو پایتون . خب راحل چیه؟
چندتا راحل وجود داره اولین و ساده ترین استفاده از ماژول abc هستش یا به اختصار (abstract base class) و تو PEP 3119 معرفی شدش و برای ساخت abstract کلاس ها مورد استفاده قرار میگیره ,
دومین راحل استفاده از ماژول zope هستش که برای ساخت interface ها مورد استفاده قرار میگیره و اخرین راحل و سخترینشون پیاده سازی abstract و interface ها با استفاده از خود پایتون هستش همینطور که تو قسمت ۱ گفتم پایتون خیلی از محدودیت های زبان های دیگه نداره برای همین این مفاهیم بصورت مستقل موجود نیستن توش برای همین میشه این مفاهیم با استفاده از کلاس های خود پایتون پیاده سازی کرد که برای اینکار نیاز به درک درستی از شی گرایی تو پایتون و همینطور metaclass ها هستش.
من تو این مقاله تمرکز روی استفاده از abc گذاشتم که کار باهاش راحته و نیازی به نصبش نیست
ی مثال قراره داشته باشیم ولی قبلش یکسری نکات باید بگم تو پایتون تفاوت abstract کلاس ها با interface ها خیلی کم رنگ هستش و بزرگترین تفاوتشون میتونه این باشه که تو abstract کلاس ها ما میتونیم متد های معمولی داشته باشیم ولی تو interface ها نه !
تو تصویر بالا میبنید که کلاس myabstract نه تنها متد های abstract داره بلکه متد های معمولی هم میتونه تو خودش داشته باشه. ولی توی اینترفیس به این شکل نیست و اگه یک متد معمولی توش تعریف بشه با خطا مواجه میشیم. اگه تیکه کد بالا متوجه نمیشید نگران باشید پایینتر بطور کامل درموردش صحبت کردم فقط الا این نکته تو ذهنتون داشته باشید . پس میشه اینطور نتیجه گیری کرد که از abstract کلاس هاهم میشه مثل interface ها استفاده کرد و تو پایتون تنها تفاوتشون همین یک نکته هستش
حالا چرا ما باید ازشون استفاده کنیم؟ ما زمانی مجبور میشیم ازشون استفاده کنیم که درحال طراحی و پیاده سازی واحد ها بزرگ و یا کوچیک هستیم و بعضی از این واحد ها ممکنه با واحد دیگه ارتباط برقرار بکنن برای همین ما یک رابط سراسری و عمومی (interface (api)) میسازیم برای هرکدوم از این واحد ها! و از مشکلاتی مثل ناهماهنگی بین این واحد ها جلوگیری میکنیم. شاید الا بخوبی متوجه منظورم نشید ولی به مثال پایین دقت کنید
تمام لپتاپ ها و کامپیوتر های دسکتاپ زیر مجموعه کامپیوتر هستن فقط نوع مختلفی از کامپیوترو نشون میدن و در اصل یکی هستن و حالا هرکدوم از اینا میتونن مشخصات متفاوت و همینطور فیچر های مختص به خودشونو داشته باشن ! ولی این اصلیت اونهارو تحت تاثیر قرار نمیده. اون کامپیوتری که میگفتم همین abstract کلاسی هستش که پایین تو کد میبنید
برای اینکه یک abstract کلاس داشته باشیم نیازه که از ABC ارث پذیری کنیم مثل کلاسی که تو تصویر میبینید از زمانیکه ارث بری کردید از ABC این یک کلاس abstract محسوب میشه. یک کامیپوتر داری بخش های ثابتی هستش مثل بخش صدا , تصویر که اینجا مانیتور استفاده کردیم و بخش کیبورد و موس و همینطور بخش پروسسور که وظیفه انجام عملیات های مختلف تو کامپیوتر داره. حالا تو این مثال خیلی چیزای دیگه ام ممکنه کامپیوتر داشته باشه که اینجا نگفتیم و همین بخش های هم که گفتید شاید نیاز به بازنگری داشته باشن ولی چون میخوام ساده نگه دارم به همینا بسنده میکنیم
خب حالا تو بدنه abstract کلاسمون ما میتونیم از متد های abstract استفاده کنیم تو قسمت اول درموردشون گفتم یک متد abstract متدی هستش که فقط تعریف شده و دارای بدنه ای نیست و تو پایتون بعد تعریف همچین متدی نیازه که از دیکوریتور abstractclassmethod که از ماژول abc اورده شده استفاده کنیم مثل تصویر بالا, تا اون متد تعریف شده واقعا یک متد با خصوصیات abstract واقعی باشه.
حالا متد های تعریف شده باید تو همه زیرکلاس ها پیاده سازی بشن وگرنه با ارورو موجه میشد مزیت اینکار سراسری بودن یکسری از متد ها تو بین تمام زیرکلاس های ما هستش و حتی اگه تیم یا شخص دیگه ام درحال توسعه کد های شما باشه و یا حتی خودتون درچار اشتباهی نمیشد که متدی فراموش کنید پیاده سازی کنید
تصویر بالا دقت کنید اینجا ما یک کلاس desktop داریم که به کامیپوتر ها دسکتاپ اشاره داره و یک فرزند از abstract کلاس کامپیوتر ما هستش.این کلاس desktop بدون تعریف تمام abstract متد هایکه تو کلاس abstract خودمون مشخص کردیم اومدیم و ازش سعی کردیم یک نمونه بسازیم , همینطور که حدس زدید و تو تصویر میبنید اروری با موضوع اینکه یک دونه یا تعدادی از abstract متد های مورد نیازی که تو کلاس والد تعریف شدن پیاده سازی نشده مواجه میشیم و اسم اون متد هم اورده شده
خب فرض میکنیم اونم پیاده سازی کردیم بعدش چی ؟ خب بیاید فرض کنید ما یک سیستم عاملی داریم طراحی میکنیم که این سیستم عامل وابسته به کامپیوتر ما هستش و یکسری از فانکشن های اونو برای کار کردن صحیح نیاز داره کد پایین ببینید.
این کلاس OS ورودیش یک کامپیوتر دریافت میکنه و واسش مهم نیست چه نوعی هستش دسکتاپ هست یا یا نوع همراه در هر صورت اون میدونه که اون کامپیوتر یکسری فانشکن های با اسم های ثابتیی داخلش هستن و با تغییر نوع کامیپوتر اونا تغییر نمیکنن پس بدون دردسر ازشون استفاده میکنه. همینطور که میبیند os ما قابلیت پخش موزیک هم داره و میدونه هم برای اینکه پخش بکنه باید به کدوم قسمت کامپیوتر چه چیزای بفرسته تا اونکار انجام بشه. خب الا مهم نیست شما دارید اینو توسعه میدید یا شخصی دیگه یا تیم تون , هیچ مشکلی پیش نمیاد برای برنامه تون چون یکسری مفاهیم بصورت سراسری اعمال میشن و بعدا هیچ وقت پیش نمیاد یک OS نیاز به استفاده از بخش Audio کامیپوتر داشته باشه و اون بخش Audio پیاده سازی نشده باشه, اینطوری هر نوع OS طراحی بکنید بدرستی کار میکنن مثال پایین ببینید.
اینجا فرض کنید تیم شما یا شخص دیگه ای بدون استفاده از abstract کلاس هامون یا interface مون یک کامیپوتر طراحی کرده و سعی کرده OS ما روش نصب کنه بیشتر بخش OS ما روی این کامپیوتره کار میکنه ولی اون تیم یا شخص فراموش کرده بخش Audio طراحی و پیاده سازی بکنه و زمانیکه os ما سعی در پخش صدای داشته باشه کرش میکنه و کلا قطع میشه و یک ناهماهنگی درست میشه ولی همین موضوع بیایم با استفاده از abstract کلاس هامون یا interface هامون اگه طراحی کرده بود ببینیم
خب میبینید اینجا OS ما بخوبی روی این لپ تاپ کار میکنه. ولی باز یک مشکلی هستش این os ما ممکنه با برنامه های که بعدا براش طراحی میشه سازگاری نداشته باشه برای اینکه بخوبی با نرم افزار هایکه به os وابسته هستن هماهنگ باشه نیازه یک interface هم براش بزنیم و از قوانین اون پیروی کنیم.
این یک مثال کوچیک و ساده از یکی از کاربرد های ایم مبحث هستش و شما بیشتر میتونید از مبحث تو بحث های از قبیل دیزاین پترن ها ببینید.
اگه سوال و نظری داشتید میتونید کامنت کنید.