فصل 19 از 40 درس 1 از 1

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 و طراحی قرارداد» با تمرکز بر ساختارهای اصلی زبان، الگوهای صحیح استفاده و خطاهای رایج بررسی شد. تسلط بر این مفاهیم زمینه لازم برای اتصال موضوع به فصل‌های بعدی و طراحی کدهای خواناتر، قابل نگهداری و قابل تست را فراهم می‌کند.