Liskov Substitution Principle

If it looks like a duck, quacks like a duck, but needs batteries – you probably have the wrong abstraction

این اصل ابتدا توسط Barbara Liskov در سال ۱۹۸۸ نامگذاری شد. براساس این اصل یک تایپ باید قابلیت تعویض را توسط ساب تایپ‌هایش (بدون تغییر در صحت اپلیکیشن) داشته باشد. فرض کنید یک کلاس با نام Class1 و دو کلاس دیگر با نام‌های Class2 and Class3 داریم. اشیاء کلاس Class2 and Class3 قابلیت انتساب به اشیاء Class1 را دارند:

1
2
3
Class1 obj =  null;
obj = new Class2(); //ok
obj = new Class3(); //ok

کد فوق مشکلی ندارد زیرا Class2 از Class1 ارث‌بری می‌کند؛ اگر این ارتباط را حذف کنیم؛ ویژوال‌استدیو فوراً یک خطا را گزارش خواهد داد. مثال فوق از inheritance استفاده می‌کند، همین رفتار را می‌توانیم از طریق interfaces نیز داشته باشیم:

1
2
3
IInterface obj = null;
obj = new Class2(); //ok
obj = new Class3(); //ok

 

در واقع هدف از این اصل استفاده بهتر از ارث‌بری است؛ فرض کنید کلاسی با نام B دارید، این کلاس نیز از کلاس A ارث‌بری خواهد کرد؛ براساس این اصل، در هر جایی کلاس A نیاز باشد باید بتوانیم از کلاس B به جای آن استفاده کنیم؛ همچنین نباید تغییری در عملکرد برنامه ایجاد شود.

در ادامه یک نمونه از نقض این الگو را مشاهده می‌کنید:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Program
{
    static void Main(string[] args)
    {
        Apple apple = new Orange();
        Console.WriteLine(apple.GetColor());
    }
}
public class Apple
{
    public virtual string GetColor()
    {
        return "Red";
    }
}
public class Orange : Apple
{
    public override string GetColor()
    {
        return "Orange";
    }
}

در کد فوق خروجی مورد انتظار باید Red باشد در حالیکه خروجی Orange است. برای رفع این مشکل می‌توانیم یک کلاس پایه با نام Fruit ایجاد کنیم سپس کلاس‌های Apple, Orange  را از آن مشتق کنیم:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public abstract class Fruit
{
    public abstract string GetColor();
}
public class Apple : Fruit
{
    public override string GetColor()
    {
        return "Red";
    }
}
public class Orange : Fruit
{
    public override string GetColor()
    {
        return "Orange";
    }
}

در نهایت برای استفاده از آن خواهیم داشت:

1
2
3
4
Fruit fruit = new Orange();
Console.WriteLine(fruit.GetColor());
fruit = new Apple();
Console.WriteLine(fruit.GetColor());

در اینحالت خروجی موردانتظار را دریافت خواهیم کرد.

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top