درود دوستان. فرض کنیم توی برنامه میخوایم به کاربرها پیام ارسال کنیم. یک تابع داریم به صورت زیر که کار ارسال پیام رو انجام میده:
function notifyUsers(notifier: Notification) { notifier.send(); }
به این تابع فقط آبجکتهایی رو میشه پاس داد که از نوع Notification باشن.
ارسال پیام در حال حاضر فقط به صورت ایمیلی هست. کلاسی ساختیم به اسم EmailNotification که فرض کنیم از نوع Notification هست و از اون به صورت زیر استفاده میکنیم:
// class EmailNotification implements Notification ... mailer = new EmailNotification(); notifyUsers(mailer);
مدتی بعد میخوایم به برنامه یک روش دیگه برای ارسال پیام اضافه کنیم. مثلاً اطلاعرسانی از طریق یک سرویس بیرونی SMS که برای ارسال پیام، کتابخونه و کدهای مخصوص به خودش رو ارائه میده. مشکل اینجا به وجود میاد. این کتابخونه اینترفیسی (نوع) متفاوت داره و از اون نمیتونیم توی تابع notifyUsers استفاده کنیم:
notifyUsers(new External_SMS_Library()); // Fatal error: // Argument 1 passed to notifyUsers() must // implement interface Notification
مشکل اینجاست: در شرایطی که تابع notifyUsers به آبجکتهایی احتیاج داره که از نوع Notification باشن، کلاس External_SMS_Library نوع کاملاً متفاوتی داره و بنابراین تابع notifyUsers نمیتونه از اون استفاده کنه. به قول معروف کلاس External_SMS_Library یک اینترفیس ناسازگار داره.
یک راه برای حل این مشکل اینه که تابع notifyUsers رو دستکاری کنیم:
function notifyUsers(notifier) { if (notifier instanceof EmailNotification) { notifier.sendEmail(); } else if (notifier instanceof External_SMS_Library) { notifier.login(); notifier.setPort(); notifier.sendSms(); } }
خب ظاهراً مشکل حل شد. اما مشکلات دیگهای سبز شدن:
۱. تابع notifyUsers باید اطلاعات زیادی درباره نحوه پیادهسازی و استفاده کلاس External_SMS_Library داشته باشه (اصل اول SOLID هم نقض میشه)
۲. در آینده با اضافه شدن یک سرویس ارسال پیام دیگه، تابع notifyUsers مدام در معرض تغییر هست (نقض شدن اصل دوم SOLID)
۳. ما نمیخوایم کدهامون وابسته به یک کتابخونه خارجی باشه (نقض شدن )
