• خانه
  • وبلاگ
  • نمونه کار ها
  • استارتاپ
  • درباره ما
  • تماس با ما
  • پنل کاربری
  • خانه
  • وبلاگ
  • نمونه کار ها
  • استارتاپ
  • درباره ما
  • تماس با ما
  • پنل کاربری
09023755684
ورود به پنل
  • خانه
  • وبلاگ
  • نمونه کار ها
  • استارتاپ
  • درباره ما
  • تماس با ما
  • پنل کاربری
  • خانه
  • وبلاگ
  • نمونه کار ها
  • استارتاپ
  • درباره ما
  • تماس با ما
  • پنل کاربری
می 16, 2021 توسط POWERA

پنج اصل سالید در برنامه نویسی

پنج اصل سالید در برنامه نویسی
می 16, 2021 توسط POWERA

اصول سالید

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

در طراحی شی گرایی پنج اصل اساسی مطرح میشه با برداشتن اولین حرف از این پنج اصل کامه سولید solid تشکیل میشه.آشنایی بر این موضوع از جمله باید های یک مخندس نر م افزار،برنامه نویس و توسعه دهنده می باشد.

از مهم ترین اهداف اصل بهبود فرآیند دیباگ کردن،انعطاف پذیری بیشتر برنامه ها ،افزایش مدت زمان نگهداری و همچنین افزودن قابلیت ها و ویژگی های بیشتر به برنامه ها می باشد.

اصل اول( SRP ) اصل تک مسئولیتی

Single Responsibility Principle

  اصل  اول اصل تک مسئولیتی می باشد.
یعنی هرکلاس باید یک مسئولیت خاص داشته باشه 
به منظوری میشه گفت یک کار انجام بده ولی درست !
به کلاس زیر دقت کنید 
کلاس کاربر ما شامل سه تا متد میشه .
متد information که اطلاعات کاربر برمیگردونه 
متد sendEmail برای ارسال  ایمیل به کاربر  
متد  print message برای چاپ پیغام 
کلاس user نباید مسئولیت بقیه مثلا ارسال ایمیل رو داشته باشه فقط باید یک کار انجام بده حالا کجا به مشکل برمی‌خوره وقتی بخواهیم کلاس گسترش بدیم .پس برای رفع این مشکل میایم سر اصل یک سالید 
 
class User {
    public information() {}
    public sendEmail() {}
    public PrintMessage(){}
}
خب حالا مرتب شد کلاس user ما فقط یه کار انجام میده و دیگه عملکردهای اضافی ازش جدا کردیم .به منظوری هر عملکرد اضافی به یک کلاس اختصاص انتقال  دادیم . 
class User {
    public information() {}
}
 
class Email {
    public send(user: User) {}
}
class PrintMessage{
    public message(string my message ) {}
}

اصل دوم سالید(ocp)اصل باز و بسته

Open/Closed Principle

اصل دوم   اصل باز /بسته 
به طوری این اصل میگه برای توسعه داده شدن موجودیت های یک نرم افزار مثل کلاس ها ،توابع و…باز و برای تغییر دادن موجودیت ها ی یک نرم افزار بسته باشه . به منظوری این اصل میخواد بگه یک کلاس هم باز باشه هم بسته !
 
آنچه که باید بدونیم!
کلاس باز یعنی کلاسی که بشه اون رو توسعه داد ،متد های جدید بهش اضافه کرد ویژگی ها و رفتارهاشو بتونیم تغییر بدیم .
کلاس بسته یعنی یه کلاس پایدار و بدون تغییر .کلاسی که تست شده و می‌تونه توسط بقیه کلاس ها استفاده بشه .
حالا با توجه به آشنایی  با مفهوم بازرو بسته بودن کلاس،میگیم در این اصل، کلاس همزمان که توسعه داده بشه تغییر نکنه .
 
دقت کنید این کلاس با درنظر گرفتن زبان ورودی از ما خداحافظی می‌کنه .الان ما  در این برنامه سه تا زبان توسط متد say پشتیبانی میشه .
class Goodbye {
    public say(lang) {
        if (lang == ‘pr’) {
            return ‘خدانگهدار’;
        } else if (lang == ‘en’) {
            return ‘Goodbye’;
        } else if (lang == ‘fr’) {
            return ‘au revoir’;
        } 
    }
}
 
let obj = new Goodbye;
console.log(obj.say(‘de’));
اگر من بخوام زبان های دیگه اضافه کنم یعنی دارم ویژگی های جدیدی اضافه میکنم که این یعنی کلاس داره با توجه به نیازها تغییر می‌کنه .این امر از نظر اصول سالید رد شدس پس اصل دوم  سالید وارد کار میشه .
class Goodbye {
    public say(lang) {
        if (lang == ‘pr’) {
            return ‘خدانگهدار’;
        } else if (lang == ‘en’) {
            return ‘Goodbye’;
        } else if (lang == ‘fr’) {
            return ‘au revoir’;
        } else if (lang == ‘de’) {
            return ‘Chao’;
        }
    }
}
 
let obj = new Goodbye;
console.log(obj.say(‘de’));
راه حل اینه که بیایم 
 کنیم Abstract (عمومی تر کردن )
 
حالا چجوری! ؟
من میام متد sayرو کلی و عمومی  می‌نویسم  که دیگه اصل باز و بسته بودن رعایت بشه .وقتی متد کلی و عمومی درنظر گرفته بشه دیگه در برابر  تغییرات مستقل و دست نخورده باقی میمونه .پس ما میایم هرزبان به یه کلاس جدید منتقل می‌کنیم حالا هر موقع بخوایم زبان جدیدی اضافه کنیم فقط با درست کردن یک کلاس جدید  دیگه کار حله !
 
 
class Persian {
    public sayGoodby() {
        return ‘خدانگهدار’;
    }
}
class English  {
    public sayGoodbye() {
        return ‘Goodbye’;
    }
} 
class French {
    public sayGoodbye() {
        return ‘au revoir’;
    }
}
class spanish {
    public sayGoodbye() {
        return ‘Chao’;
    }
}
 
 
class Goodbye {
    public say(lang) {
        return lang.sayGoodbye();
    }
}
 
 
let obj = new Goodbye;
console.log(obj.say(new Persian));

اصل سوم سالید(LSP)اصل جایگزینی

Liskov Substitution Principle

اصل دوم اصل جایگزینی لیسکوف  .به طوری این اصل بیان می‌کنه که اگر Bیه زیرکلاس Aباشه ،آبجکت های نوع کلاس Aباید بتونه بدون تغییر دادن کدهای برنامه با آبجکت های زیرکلاس Bجایگزین بشه .
جایگزینی انجام بده اما بدون خطا و تغییر کد برنامه !
 
به طور فرض یک کلاس به اسم Cدرنظر گرفتیم .

class C  { … }

می‌خوایم از کلاس Cآبجکت هایی بسازیم و توقسمت های مختلف برنامه مورد استفاده قرار بدیم .
کد زیر نمایانگر  قسمت های مختلف برنامه است  که از کلاس Cاستفاده می‌کنه .
 
let a = new C;
 
// …
 
let b = new C;

حالا می‌خوایم کلاس Cرو توسعه بدیم پس میام یه کلاسی دیگه مثلا کلاس Tمیسازم که از کلاس Cمشتق میشه در نتیجه کلاس Tیه زیر نوع از کلاس Cشد .

class T extends C { … }

در اسلاید قبل دیدید که از کلاس Cآبجکت هایی ساختیم و تو برنامه مورد استفاده قرارگرفت حالا میخوایم بجای کلاس Cاز کلاس T که یک زیر نوع کلاس Cبود استفاده کنیم.هدفذما از این عمل  جایگزینی است که طبق اصل LSPوقتی جایگزینی انجام میشه نباید به خاطر جایگزینی برنامه دچار خطا بشه و کد برنامه تغییر کنه .

let a = new C new T;
 
// …
 
let b= new C new T;
نتیجه‌گیری
هدف این اصل اینه که وقتی میخوای یک کلاس رو با مشتق کردن توسعه بدی هرجا که کلاس والد داشتی باید کلاس والد بتونه بدون مشکل با کلاس های فرزند هم کار کنه .

اصل چهارم سالید(ISP)اصل جداسازی اینترفیس ها

INTERFACE SEGREGATION PRINCIPLE

اصل چهارم ،  اصل جداسازی اینترفیس ها .این اصل میگه نوشتن اینترفیس ها باید طوری باشه که وقتی یک کلاس از اون استفاده می‌کنه محبور به پیاده سازی متدهایی که لازم نداره نباشه .
یعنی ورود متد های بی ربط و وجود آنها کنار هم در یک اینترفیس ممنوع حتی شما دوست عزیز ! 
 حالا من یه اینترفیس با دو متد براتون آوردم که باید توسط کلاس هایی که ازش استفاده میکنن پیاده سازی بشه .کلاس fish (ماهی)در نظر میگیریم که از اینترفیس استفاده می‌کنه .
interface Animal {
 
fly();
 
run();
 
}
متد fly اینجا قانون شکنی می‌کنه چون کلاس ماهی مجبور به پیاده سازی متدی شد که از اون استفاده نمیکنه 
 
class Fish implements Animal {
    public fly() {
        return false;
    }
 
    public run() {
        // Run
    }
 
}

اما راه حل  چیه :با جداسازی اینترفیس ها و اختصاص متد flyبه یک اینترفیس این اصل(ISP )به کمک ما میاد و مشکل حله .

interface Animal {
    run();
}
 
interface FlyableAnimal {
    fly();
}
کلیات ممنوع 
در کدنویسی شی گرایی نکته حائز اهمیت دوری کردن از کلیات  یعنی شما هرچقدر از کلی نویسی دوری کنی کدهای منسجم تر ،خوانا تری  خواهی داشت .که این موضوع برای تست دوباره و ریفکتور کردن هم کار رو آسون می‌کنه .
 
 
اصل پنجم سالید(DIP)اصل وارونگی وابستگی
Dependency Inversion Principle
اصل پنجم و اما اخرین اصل ، اصل وارونگی وابستگی است .
این اصل بیان می‌کنه کلاس های سطح بالا نباید به کلاس های سطح پایین وابسته باشن بلکه هردو باید وابسته به انتزاع( Abstractions)باشند .همچنین جزئیات (جزئیات کلاس مثل  نام متد و.. )، باید وابسته به انتزاع باشن نه بالعکس .
 
دانستنی های مورد نیاز برای درک این اصل 
مفاهیم کلاس های سطح پایین و بالا و انتزاع پس بریم که آشنا بشیم .
کلاس های که مسئولیت عملیات اساسی و پایه برعهده دارن مثل دیتابیس ،کار با جی‌میل و… کلاس سطح پایین میگیم .
کلاس هایی که با استفاده از کلاس های سطح پایین عملیات های پیچیده و خاص مثل کلاس Users(کلاس سطح بالا ) که برای اطلاع رسانی به کلاس ایمیل(کلاس سطح پایین ) نیاز داره .
 
مفاهیم انتزاعی، یک طرح کلی برای چیزهای عینی هستن مثلا وقتی میگیم خودرو چیز خاصی به ذهنمون نمیاد چون تو دنیای واقعی قابلیت پیاده سازی ندارند اما مثلا ویلچر نوعی از خودرو هست پس دراینجا خودرو همون مفهوم انتزاع رو داره ولی دوچرخه چون واقعیه و وجود داره Concrete میگیم .حالا بخوایم   تو برنامه نویسی هم بگیم کلاس های که قابل نمونه سازی باشن(new کردن  کلاس ) Concrete Classes و کلاس های که قابل نمونه سازی نباشه  Abstract Classes
 
ما میایم به طور فرض یه کلاس سطح بالا logو یه کلاس سطح پایین MySQL درنظر میگیریم .اگر من بیام تغییری توی کلاس MySQL بدم ممکنه به طور مستقیم رو کلاس های که ازش استفاده میکنن تاثیر بزاره و   باید این تغییر تو کلاس سطح بالا  log هم بدیم‌.موضوع دیگه کلاس سطح بالا قابل استفاده مجدد نیست و ما باید برای رفع این مشکل یا کلاس رو تغییر بدیم یا یه کلاس جدا براساس هرنوع دیتابیس بسازیم .
اینا همه مشکل وابستگی کلاس سطح بالا به  پایین  هستش .
 
class MySQL {
    public update() {}
    public delete() {}
}
 
class Log {
    private database;
 
    constructor() {
        this.database = new MySQL;
    }
}
راه  حل !
با تشکیل یه لایه انتزاعی کارمون حله چون دیگه کلاس Logوابسته به کلاس خاصی نیست و براش اهمیتی نداره که داره با چه نوع دیتابیسی کار میکنه.
۱)برای وابسته کردن کلاس های سطح بالا و پایین به اینترفیس یک اینترفیس می‌سازیم .
interface Database {
    update();
    delete();
}

۲)پیاده سازی اینترفیس کلاس های سطح پایین برای وابستگی به انتزاع 

class MySQL implements Database {
    public update() {}
    public delete() {}
}
 
class FileSystem implements Database {
   
    public update() {}
    public delete() {}
}

۳)استفاده از یک اینترفیس بجای استفاده مستقیم از کلاس های سطح پایین برای وابستگی کلاس های سطح بالا به انتزاع 

class Log {
    private db: Database;
 
    public setDatabase(db: Database) {
        this.db = db;
    }
 
    public update() {
        this.db.update();
    }
}
 

۴)و درنهایت حذف وابستگی با استفاده ازاصل پنجم 

let logger = new Log 
logger.setDatabase(new FileSystem);
// …
logger.setDatabase(new MySQL);
 
logger.update();
   این اصل هم با هدف قابل توسعه تر شدن و قابل نگهداری کدها طراحی شده اما باید خیلی حواس جمع بود که به جا و به درستی از این اصول استفاده کنیم چون ممکنه به جای انسجام و راحتی کار بالعکس عمل کنه و  موجب  گنگ  شدن و پیچید گی کدها بشه .
 
 
مقاله قبلیدستور break&continueمقاله بعدی تابع

دیدگاهتان را بنویسید لغو پاسخ

برای نوشتن دیدگاه باید وارد بشوید.

درباره ما

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

دسته‌ها

  • اموزشی
  • برنامه نویسی
  • مقدماتی سی پلاس پلاس

درباره ما

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

دوره ها

  • دوره html
  • دوره ++C
  • دوره php

تماس با ما

  • info.powera1.ir@gmail.com
  • 090237555684
  • ساعات پاسخگویی:9 الی17
Instagram