اصول SOLID

پرسیده شده
فعالیت 1387 روز پیش
دیده شده 671 بار
3

با سلام خدمت دوستان 

 

من یک مشکلی داشتم تو درک مفهوم اصل Liskov Substitution اگر کسی از اساتید یا دوستان مطلبی برای درک بهتر این اصل داره ممنون میشم راهنماییم کنه.

 

- اگر کلاس A زیر مجموعه کلاس B است ، پس باید بدون ایجاد اختلال در رفتار برنامه خود ، B را با A جایگزین کنیم.

 

تو درک مفهوم این اصل و این که اصلا هدف از رعایت این اصل چیه مشکل دارم

فایل پیوست

علی.
علی.

19 تیر 99

3

مورد تایید استاد

حذف شده

سلام 

این اصل میگه که شما زمانی که یک کلاسی رو از کلاس دیگه ای اکستند میکنید باید رفتار پدر رو بتونید داخل کلاس فرزند پیاده سازی کنید برای مثال : 

شما کلاسی a رو در نظر بگیرید : 

<?php 
class a{
     
    private $number1;
    private $number2;

    public function getNum1(){
         return $this->number1;
    }
    public function setNum1($num){
     $this->number1 = $num;
    }
    public function getNum2(){
        return $this->number2;
   }
   public function setNum2($num){
    $this->number2 = $num;
   }

    public function total()
    {
       $total = $this->number1 + $this->number2;
       return $total;
    }

}

اینجا چند تا متود وجود داره که پراپرتی های number1 , number2 رو مقدار دهی میکنه و اونا رو میخونه (getter and setter)

و همچنین یک متود برای جمع این دو پراپرتی 

حالا فرض کنید که میخواهید این کلاس رو در کلاسی تحت عنوان b اکستند کنید

شما برای اینکه از این متد ها استفاده کنید در کلاس b کلاس a رو اکستند کردید ( درواقع الان کلاس b فرزند کلاس a است)

تا اینجای کار شما این اصل رو نقض نکردید اما زمانی رو در نظر بگیرید که میخواید بجای متود total به جای جمع این دو پراپرتی رو از هم کم کنه 

شما متود total رو بازنویسی میکنید داخل کلاس b : 

<?php 
class b extends a{

    public function total(){

        $total = $this->number1 - $this->number2;
        return $total;

    }

}

این بازنویسی اصل لیسکوف رو نقض میکنه به دلیل اینکه دیگه متود total رفتاری که توی کلاس پدر هست رو انجام نمیده و رفتار دیگه رو داره!

امید وارم تونسته باشم کمک کنم سعی کردم ساده توضیح بدم اما این اصل یخورده درک و توضیحش سخته!

فایل پیوست

میثم نصرتی

توسط

میثم نصرتی

19 تیر 99

حذف شده
سلام چیزی که اخرش توی ذهنم اومد اینه ک این اصل سالید ، اصل polymorphism رو رد میکنه درسته ؟
هادی قاسمی

2 آبان 99

2

مورد تایید استاد

حذف شده

سلام ممنون از توضیحی که دادید .

 

تو این جوابی که دادید فرض کنیم کلاس a یک اینترفیس بود اون موقع چی ؟

 

از چیزایی که فهمیدم یه مثال میزنم :

 

ما یه کلاس پرندگان داریم که کلاس های عقاب ها و شترمرغ ها از اون کلاس مشتق شدن

کلاس پرندگان دارای دوتا متد پرواز کردن و غذا خوردن هست کلاس عقاب میاد این متدها رو پیاده سازی میکنه و تا اینجا برنامه مشکلی نداریم

ولی به هنگام پیاده سازی کلاس شتر مرغ ها از اون جایی که کلاس شتر مرغ ها نیازی به متد پرواز کردن نداره این متد رو تعریف نمیکنیم  اینجاست که این اصل نقض میشه چون کلاس فرزند مثل باباش رفتار نمیکنه

 

 

مفهوم اصل رو درست فهمیدم ؟

 

سوال بعدی که دارم اینه که اینکار به چه دردی میخوره ؟ یعنی یه دلیلی داره که ما باید این اصل رو رعایت کنیم اون دلیله چیه؟

فایل پیوست

علی.

توسط

علی.

19 تیر 99

2

مورد تایید استاد

حذف شده

خواهش میکنم 

تا جایی که از این اصل میدونم فرقی بین کلاس های عادی یا اینترفیس ها نیست برای این اصل 

خوب شما تنها از متود پرواز استفاده نمیکنید چیزی رو نقض نکردید شما زمانی نقض میکنید که به فرض متد پرواز کردن رو توی کلاس فرزند (شتر مرغ ها ) دست کاری کنید و تغیراتی داخل اون بدید شما الان وقتی میگید شتر مرغ نیازی به متد پرواز نداره تغیری توی متد پرواز ندادید تنها اون رو استفاده نکردید و هر زمان که نیاز باشه میتونید اون رو استفاده کنید یا استفاده نکنید.

به این دلیل استفاده می شه که مطمئن باشیم وراثت همیشه بدرستی به کار رفته

فایل پیوست

میثم نصرتی

توسط

میثم نصرتی

19 تیر 99

2

مورد تایید استاد

حذف شده

حرف شما متین ولی اگه کلاس پرندگان رو یک اینترفیس درنظر بگیریم متد های من بدنه ای نداره که بیام مثل مثالی که خودتون زدید بدنشو تغییر بدم (متد total) . با این مثالی که شما زدی نباید هیچ کلاس فرزندی بیاد متد های والدشو override بکنه چون این اصل نقض میشه . بعدشم اگه من متد پرواز کردن رو تو یک اینترفیس تعریف کنم باید تو کلاس شتر مرغ هم پیاده سازی کنم در غیر اینصورت خطا میده

 

از طرفی این اصل میگه باید بشه کلاس فرزند رو جای کلاس پدر قرار داد بدون اینکه مشکلی در برنامه پیش بیاد حالا من اگه متد پرواز کردن رو تو کلاس شتر مرغ ها تعریف نکنم که نمیتونم این زیر کلاس رو جایگیزن والدش کنم چون یه چیزی کم داره و کارایی والدش رو نمی تونه داشته باشه به خاطر همین این شرط رو نقض میکنه و به یه شکلی میشه این موضوع رو حل کرد

 

 

فایل پیوست

علی.

توسط

علی.

19 تیر 99

2

مورد تایید استاد

حذف شده

حرف شما درسته در مورد اینترفیس حق با شماست و من اشتباه کردم ! عذر میخوام 

اما خوب در حالت کلی بعضی اوقات واقعا نمیشه این اصل رو رعایت کرد من از برنامه نویس های با سابقه هم پرسیدم برای نقض چنین چیزی اما اون ها هم این جواب رو به بنده دادن که همیشه هم نمیشه اصل رو بصورت کامل اجرا کرد ی جاهایی مجبور به این میشیم که اصل رو نقض کنیم.

در مورد اینتر فیس زمانی که شما از اینترفیسی استفده میکنید بدنه اون متودی که داخل اینتر فیس هست رو داخل کلاسی که این اینترفیس رو ایمپلیمنت کرده تعریف میکنید 

خوب اینجا اصلا شما نقضی صورت ندادید و مجبورید از همون امضایی که داخل اینتر فیس گذاشتید در داخل کلاس استفاده کنید!

به فرض اینترفیس داریم با نام a و یک سری امضا داخل اون داریم و اومدیم کلاسی به اسم b رو ساختیم که اینترفیس a رو ایمپلیمنت میکنه 

حالا اگر اشتباه نکنم زمانی که شما یک کلاس دیگه با نام c داشته باشید و بخواید کلاس c فرزند کلاس b باشه باز هم میتونید متود ها رو اورراید کنید و اینجا میتونه این نقض به وجود بیاد نه در اینترفیس 

چون تمامی امضا هایی که داخل اینترفیس شما میسازید باید بدنه همه اونها رو جایی که از این اینترفیس استفاده میکنید بسازید

 

فایل پیوست

میثم نصرتی

توسط

میثم نصرتی

19 تیر 99