🏛 کلاس در برابر اینترفیس: کدام را و چه زمانی انتخاب کنیم؟
یکی از اساسیترین سوالات در طراحی شیءگرا اینه: کی باید از یه class و وراثت استفاده کنیم و کی باید بریم سراغ interface؟
این فقط یه انتخاب سینتکسی نیست، یه تصمیم مهم معماریه. بیاید با یه قانون ساده و یه مثال عالی، این موضوع رو برای همیشه روشن کنیم.
1️⃣ قانون طلایی: پیادهسازی مشترک در برابر رفتار مشترک ⚖️
به عنوان یک قانون کلی و کاربردی:
از class و وراثت استفاده کن:
وقتی تایپهای شما به صورت طبیعی، پیادهسازی مشترکی (shared implementation) دارند. یعنی کدهای مشترکی بینشون هست که میخواید از تکرارش جلوگیری کنید.
از interface استفاده کن:
وقتی تایپهای شما رفتار مشترکی (shared behavior) دارند، ولی هر کدوم پیادهسازی مستقل (independent implementation) و متفاوتی از اون رفتار رو ارائه میدن.
2️⃣ مثال عملی: دنیای حیوانات 🦅
فرض کنید میخوایم موجودات مختلف رو مدلسازی کنیم.
مشکل (استفاده فقط از کلاس): 👎
یه "عقاب" هم "پرنده" است، هم "موجود پرنده" و هم "گوشتخوار". چون #C وراثت چندگانه از کلاسها رو پشتیبانی نمیکنه، کد زیر کامپایل نمیشه!
abstract class Animal {}
abstract class Bird : Animal {}
abstract class FlyingCreature : Animal {}
abstract class Carnivore : Animal {}
// ❌ خطای کامپایل! یک کلاس نمیتونه از چند کلاس ارثبری کنه
class Eagle : Bird, FlyingCreature, Carnivore {}راه حل (ترکیب کلاس و اینترفیس): 👍
حالا قانون طلایی رو به کار میبریم. "پرنده" بودن احتمالاً یه سری پیادهسازی و ویژگی مشترک داره، پس
Bird یه class باقی میمونه. اما "پرواز کردن" یا "گوشتخوار بودن"، رفتارهایی هستن که موجودات مختلف (مثل حشره و پرنده) به شکلهای کاملاً متفاوتی انجام میدن. پس اینها بهترین کاندیدا برای اینترفیس هستن!// اینترفیسها فقط "رفتار" رو تعریف میکنن
interface IFlyingCreature { }
interface ICarnivore { }
abstract class Animal {}
// کلاسها "پیادهسازی" مشترک رو ارائه میدن
abstract class Bird : Animal {}
// ✅ حالا درسته!
// عقاب از کلاس Bird ارث میبره و دو اینترفیس رو پیادهسازی میکنه
class Eagle : Bird, IFlyingCreature, ICarnivore {}
🤔 حرف حساب و تجربه شما
این مثال نشون میده که چطور با انتخاب درست بین کلاس و اینترفیس، میتونید ساختارهای پیچیده و در عین حال تمیز و انعطافپذیری طراحی کنید.
🔖 هشتگها:
#CSharp #DotNet #OOP #SoftwareArchitecture #Interface #CleanCode