اصل جایگزینی لیسکوف
اصل جایگزینی لیسکوف - Liskov substitution یا (LSP)
در اینجا ابتدا تعریفی از LSP ارائه می کنیم.
LSP می گوید: "زیرکلاس ها باید با کلاس های پایه قابل جایگزینی و تعویض باشند."
فکر نمی کنید این عبارت عجیب و غریب باشد؟ اگر ما همیشه بتوانیم بنویسیم:
()BaseClass b=new DerivedClass
بنابراین چرا چنین اصلی باید وجود داشته باشد؟
مقایسه با جهان واقعی
پدر یک تاجر املاک و مشاور املاک است در حالی که پسر می خواهد بازیکن کریکت باشد.
پسر نمی تواند جایگزین پدرش شود علی رغم اینکه آنها به یک خانواده تعلق دارند.
شناسایی مسئله
بیایید در رابطه با یک مثال معروف صحبت کنیم.
در حالت نرمال وقتی صحبت از اشکال هندسی می شود، ما مستطیل را یک کلاس پایه برای مربع می نامیم. تکه کد زیر را در نظر بگیرید:
public class Rectangle
{
public int Width { get; set; }
public int Height { get; set; }
}
public class Square:Rectangle
{
//codes specific to
//square will be added
}
ممکن است کسی بگوید:
Rectangle o = new Rectangle(); o.Width = 5; o.Height = 6;
به نظر خوب می رسد. اما بر اساس LSP باید بتوانیم مستطیل را با مربع عوض کنیم، بنابراین داریم:
Rectangle o = new Square(); o.Width = 5; o.Height = 6;
مشکل کجاست؟ مربع نمی تواند طول و عرض متفاوتی داشته باشد.
این به چه معناست؟ یعنی اینکه نمی توانیم کلاس پایه را با کلاس فرزند جایگزین کنیم. یعنی LSP نقض گردیده است.
چرا width و height را به صورت virtual در مستطیل تعریف نمی کنیم و آنها را در مربع باز نویسی و override کنیم؟
public class Square : Rectangle
{
public override int Width
{
get{return base.Width;}
set
{
base.Height = value;
base.Width = value;
}
}
public override int Height
{
get{return base.Height;}
set
{
base.Height = value;
base.Width = value;
}
}
رفتار ویژگی های طول و عرض در کلاس فرزند تغییر یافت (در مستطیل طول و عرض نمی توانند برابر باشند، اگر برابر باشند دیگر مستطیل نیست.)
این نمی تواند نوعی جایگزینی باشد.
راه حلی که LSP را نقض نمی کند.
باید یک کلاس انتزاعی (Abstract) با عنوان Shape (اَشکال) وجود داشته باشد، مانند زیر:
public abstract class Shape
{
public virtual int Width { get; set; }
public virtual int Height { get; set; }
}
حال دو کلاس گسسته که به یکدیگر وابسته نیستند می تواند وجود داشته باشد، یکی مستطیل و دیگری مربع، هر دوی آنها از کلاس Shape ارث می برند.
حال برنامه نویس می تواند بگوید:
Shape o = new Rectangle(); o.Width = 5; o.Height = 6; Shape o = new Square(); o.Width = 5;//هم طول و هم عرض برابر 5 می شود o.Height = 6;//هم طول و هم عرض برابر 6 می شود
حتی بعد از اشتقاق و باز نویسی کلاس ها رفتار طول و عرض را تغییر نمی دهیم، زیرا وقتی در رابطه با شکل صحبت می کنیم، قانون مشخص و ثابتی برای طول و عرض وجود ندارد. ممکن است برابر باشند یا برابر نباشند.
- نوشته شده توسط مظاهر نصوحی
- بازدید: 18694