تا میتونید از Interface و Abstraction استفاده کنید. ولی اسراف نکنید.
اول با یک سوال شروع کنیم:
چه طور میشه یک کلاس مشتری داشت، در اون یک تابع محاسبه و ذخیره ی اعتبار مشتری داشته باشیم و در صورت تغییر فرمول اعتبار اون رو تغییر ندیم؟!
چه طور یک کلاس میتونه برای توسعه باز و برای تغییر بسته باشه؟
عزیزی فرمودن:
SOFTWARE ENTITIES (CLASSES, MODULES, FUNCTIONS, ETC.) SHOULD BE OPEN FOR EXTENSION, BUT CLOSED FOR MODIFICATION.
خوب وقتشه صورت مسئله ی قبل سخن دوستمون رو بریزیم دور.
اصولا قاعده ی OCP برای مثال های Abstraction جایگاه داره. پس سوال رو تغییر میدیم به:
یک کلاس مشتری داریم، در اون تابعی برای محاسبه اعتبار مشتری وجود داره. یک نوع مشتری دیگه به سیستم اضافه شده که این مشتری خرید عمده انجام میده و فرمول محاسبش متفاوت هست و تسویه حساب های قبلی اون و وضعیتشون در محاسبه ی فرمول دخیل هست. چه طور میشه کلاس مشتری رو تغییر نداد؟!
کلید، Abstraction است.
یک کلاس پدر برای مشتری باید در نظر گرفت. دو کلاس مشتری خرده فروش و عمده فروش رو باید از اون ارث ببریم و هر کدوم پیاده سازی تابع محاسبه ی اعتبار که در کلاس پدر تعریف شده رو انجام میدن. از این به بعد، هر قابلیتی که مربوط به مشتری عمده فروش باشه، فقط در کلاس خودش پیاده سازی میشه، و نه کلاس پدر، و نه کلاس های دیگه که از اون ارث بری کردن نیاز به تغییر ندارن.
نکته1: هر جای کد دیدید کلاس جدیدی دارید اضافه میکنید که بر اساس یکی از پراپرتی های اون کلاس در توابعتون، از if,switch استفاده میکنین، به پیاده سازیتون شک کنین.
رهنمود1: یکی از اصول Clean Code خوانا بودن کد هست، کد رو به نحوی بنویسید که وقتی دارین مطالعش میکنین حس کنین دارین روزنامه میخونین.