Interface و طراحی قرارداد
Interface و طراحی قرارداد
بخشی از آموزش جامع C# و .NET 10
محتوای درس Interface و طراحی قرارداد
Interface قرارداد رفتاری را بدون الزام به یک سلسلهمراتب کلاس مشخص تعریف میکند. طراحی بر اساس Interface وابستگی اجزا را کاهش و تستپذیری را افزایش میدهد.
۱. تعریف Interface
Interface مجموعهای از اعضای قراردادی را مشخص میکند. Typeهای مختلف میتوانند بدون رابطه ارثبری مشترک آن را پیادهسازی کنند.
مثال
interface ILogger{void Log(string message);}
class ConsoleLogger:ILogger{public void Log(string m)=>Console.WriteLine(m);}در این مثال، مفهوم «تعریف Interface» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نامها عمداً ساده انتخاب شدهاند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب میشود.
۲. Multiple Interface
یک Class میتواند چند Interface را پیادهسازی کند و چند نقش مستقل داشته باشد.
مثال
interface IPrint{void Print();} interface ISave{void Save();}
class Report:IPrint,ISave{public void Print(){} public void Save(){}}در این مثال، مفهوم «Multiple Interface» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نامها عمداً ساده انتخاب شدهاند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب میشود.
۳. Interface Segregation
Interfaceهای کوچک و متمرکز معمولاً از Contractهای بزرگ که مصرفکننده را مجبور به اعضای غیرضروری میکنند بهترند.
مثال
interface IRead<T>{T? Get(int id);} interface IWrite<T>{void Save(T item);}در این مثال، مفهوم «Interface Segregation» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نامها عمداً ساده انتخاب شدهاند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب میشود.
۴. Dependency Inversion
کد سطح بالا بهتر است به Abstraction وابسته باشد نه پیادهسازی مشخص.
مثال
class Service { private readonly ILogger _log; public Service(ILogger log)=>_log=log; }در این مثال، مفهوم «Dependency Inversion» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نامها عمداً ساده انتخاب شدهاند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب میشود.
۵. Interface در برابر Abstract Class
Interface برای قرارداد و چند نقش مستقل مناسب است؛ Abstract Class برای خانوادهای با State و Implementation مشترک کاربرد بیشتری دارد.
مثال
abstract class Document { public abstract string Render(); }در این مثال، مفهوم «Interface در برابر Abstract Class» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نامها عمداً ساده انتخاب شدهاند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب میشود.
۶. مثالهای عملی
public interface INotificationSender
{
Task SendAsync(string recipient, string message);
}
public class EmailSender : INotificationSender
{
public Task SendAsync(string recipient, string message)
{
Console.WriteLine($"Email to {recipient}: {message}");
return Task.CompletedTask;
}
}این نمونه عملی چند مفهوم فصل را در کنار هم قرار میدهد و برای مشاهده رفتار واقعی کد قابل اجرا و تغییر است.
۷. خطاهای رایج
• Interfaceهای بسیار بزرگ
• نامگذاری مبهم Contractها
• وابستگی مستقیم Serviceها به Concrete Class با وجود نیاز به جایگزینی
۸. نکات اجرایی
• نامها، Typeها و Methodها را متناسب با مفهوم دامنه و بدون ابهام انتخاب کنید.
• هشدارهای کامپایلر و Nullable را بدون بررسی خاموش نکنید.
• منطق هر بخش را تا حد امکان کوچک، قابل تست و مستقل از I/O غیرضروری نگه دارید.
۹. تمرین عملی
Interface با نام IStorage تعریف کنید و دو پیادهسازی FileStorage و MemoryStorage برای ذخیره و خواندن متن بسازید.
۱۰. جمعبندی
در این فصل، مبانی «Interface و طراحی قرارداد» با تمرکز بر ساختارهای اصلی زبان، الگوهای صحیح استفاده و خطاهای رایج بررسی شد. تسلط بر این مفاهیم زمینه لازم برای اتصال موضوع به فصلهای بعدی و طراحی کدهای خواناتر، قابل نگهداری و قابل تست را فراهم میکند.