اصل تفکیک رابط در C#: ایجاد رابط هایی که مردم در واقع می خواهند از آنها استفاده کنند

مرا مجبور نکنید که آن را اجرا کنم
همه ما آن را دیده ایم – کلاس که مجبور به اجرای روش هایی است که فقط به آن اهمیت نمی دهد زیرا “رابط می گوید.”
این همان چیزی است که اصل تفکیک رابط (ISP) اینجا برای رفع است.
مشتریان نباید مجبور شوند به رابط هایی که از آنها استفاده نمی کنند وابسته باشند. – رابرت سی مارتین
بیایید آن را با مثال های C# در دنیای واقعی و برخی از عقل سلیم تجزیه کنیم.
مشکل: یک رابط برای رد همه آنها
تصور کنید که ما در حال ساختن سیستمی برای رسیدگی به انواع مختلف اسناد هستیم. در اینجا یک رابط مشترک وجود دارد که ممکن است با آن شروع کنید:
public interface IDocumentProcessor
{
void Print();
void Fax();
void Scan();
}
خوب به نظر می رسد ، تا زمانی که ما یک کلاس برای a ایجاد کنیم مستندات دیجیتالی:
public class DigitalDocument : IDocumentProcessor
{
public void Print()
{
throw new NotSupportedException("Cannot print digital-only documents.");
}
public void Fax()
{
throw new NotSupportedException("Fax not supported.");
}
public void Scan()
{
// Scan logic (maybe)
}
}
ما در حال حاضر در حال نقض اصل تفکیک رابط هستیم.
بو: چه موقع throw
نشان دادن
هنگامی که اجرای شما شروع به پرتاب می کند NotSupportedException
، این یک علامت واضح است که رابط کاربری است انجام بیش از حدبشر
کلاس مجبور می شود بستگی به رفتارهایی که به آن احتیاج ندارد، فقط برای برآورده کردن کامپایلر. و اکنون ، سایر قسمت های سیستم باید دفاعی باشند و بررسی کنند که واقعاً پشتیبانی می شود.
✅ FIX: رابط را تقسیم کنید
بیایید همه چیز را به درون تقسیم کنیم رابط های متمرکز ، خاص نقش:
public interface IPrintable
{
void Print();
}
public interface IFaxable
{
void Fax();
}
public interface IScannable
{
void Scan();
}
اکنون هر کلاس فقط آنچه را که در واقع پشتیبانی می کند پیاده سازی می کند:
public class DigitalDocument : IScannable
{
public void Scan()
{
Console.WriteLine("Scanning digital document...");
}
}
public class PhysicalDocument : IPrintable, IFaxable, IScannable
{
public void Print() => Console.WriteLine("Printing...");
public void Fax() => Console.WriteLine("Faxing...");
public void Scan() => Console.WriteLine("Scanning...");
}
پاک کننده ، واضح تر و بدون روش هدر رفته.
📦 یک مورد استفاده واقع بینانه تر: صورتحساب
بیایید آن را به فاکتورها برگردانیم. ممکن است با:
public interface IInvoiceHandler
{
void Save();
void Email();
void Print();
}
اما اگر برخی از فاکتورها فقط پیش نویس یا داخلی باشند و نیازی به ایمیل یا چاپ نباشند ، چه می شود؟
رابط را تقسیم کنید:
public interface IInvoiceSaver
{
void Save();
}
public interface IInvoiceMailer
{
void Email();
}
public interface IInvoicePrinter
{
void Print();
}
اکنون کلاسهای شما با روشهای بلااستفاده یا جعلی به هم ریخته نیستند throw
منطق هرکدام دقیقاً همان کاری را انجام می دهند که لازم است – و چیز دیگری.
🧪 چک سریع
از خود بپرسید:
- آیا این روشهای اجرای کلاس در واقع استفاده نمی کند؟
- آیا شما می بینید که “پشتیبانی نشده” یا اجرای خالی؟
- آیا می توان این رابط را به قطعات کوچکتر و متمرکز تر تقسیم کرد؟
اگر بله ، احتمالاً به دنبال نقض ISP هستید.
thoughts افکار نهایی
اصل تفکیک رابط همه چیز در مورد احترام است. احترام به کلاس های خود ، هم تیمی های آینده و سلامت خود را.
هنگامی که رابط ها تمیز و متمرکز هستند ، درک ، آزمایش و گسترش آن آسان تر می شود. روش های نگهدارنده دیگری وجود ندارد. پشتیبانی جعلی دیگری برای ویژگی ها وجود ندارد. فقط طراحی تمیز و عمدی.
بنابراین دفعه بعد که وسوسه می شوید “فقط یک روش دیگر” را به آن رابط اضافه کنید ، مکث کنید – و شاید به جای آن یک روش جدید ایجاد کنید.
یک رابط خوب مانند یک مکالمه خوب است – short ، مرتبط و عاری از سکوت ناخوشایند.