اصول Solid در php

اصول Solid در php

اصول Solid در php

 

در این مقاله قصد دارم شما را با اصول Solid آشنا کنم که هر برنامه نویسی برای ساخت برنامه ای بهتر باید آن را بداند و انجام دهد. Solid در واقع یک سریع دستورالعمل هست که اگر شما از آن استفاده کنید ( به صورت اصولی و صحیح) کدهای نوشته شده ساده، توسعه پذیر، منطقی و واضح هستند به عبارتی بهتر باعث میشود از طراحی بد اجتناب کنید. در بعضی توضیحات از کلمه ماژول و در بعضی از موارد کلاس استفاده شده، ما اکثرا از کلمه کلاس در طول مقاله استفاده میکنیم.

Solid شامل موارد زیر میباشد :

  1. Single Responsibility Principle (SRP) : یکی از مهم ترین قواعد Solid که بیان میکند تنها یک مسئولیت (وظیفه) واحد توسط هر کلاس ارائه میشود.
  2. Open-Close Principle :‌ این اصل بیان میکند که کلاس باید گسترش پذیر باشد اما برای اصلاح بسته باشد.
  3. Liskov Substitution : کلاس های مشتق شده میتوانند در مکان هایی که کلاس پایه استفاده شده است جایگزین شوند.
  4. Interface Segregation :‌ ما باید interface های خود را بهinterface های کوچک تری تبدیل کنیم تا در هر بخش تنها همان نیاز کاربر را بر طرف کنیم.
  5. Dependency Inversion : این اصل به عبارتی ساده بیان میکند که کلاس های سطح بالا نباید به کلاس سطح پایین وابستگی داشته باشن بلکه هردوی آنها باید به abstractions وابسته باشند.

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

اصول Solid در php

Single Responsibility

در یک کلاس شما تنها یک هدف دارید و تمامی متدها برای یک وظیفه واحد اجرا میشوند. اگر کلاسی دارید که چندین هدف یا وظیفه دارد باید به چند کلاس تبدیل شود.

برای نمونه ما کد زیر را داریم :

class Setting{
  public function setSettings()
  {
    // set settings
  }
  public function getSettings()
  {
    // get settings
  }
  public function showSettings()
  {
    // show output
  }
}
اصول Solid در php

توجه کنید که هر تابع قراره تنها یک کار انجام بده و قراره هر کلاس یا شی یک هدف واحد داشته باشه، کدها رو به شکل زیر تغییر میدیم:

class Setting{
  public function setSettings()
  {
    // set settings
  }
  public function getSettings()
  {
    // get settings
  }
}
class Output
{
  public function show($data)
  {
    // show output
  }
}

خوب تغییرات بالا باعث شد تا هر کلاس یک هدف خاص رو دنبال کنه و همچنین در آینده اگر نیاز به تغییر یا توسعه باشه با تغییرات اعمال شده اینکار برای ما راحت تر هست.

اصول Solid در php

Open-Close

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

برای مثال ما کد زیر برای ورود اطلاعات به ۲ نوع پایگاه داده رو داریم :

class DB
{
  public function insert($connection, $into, $cell, $data)
  {
    if (is_a($connection, 'mysqli')) {
      // connect and insert into mysql and return id 
    } elseif (is_a($connection, 'mongodb')) {
      // connect and insert into mongodb and return id
    }
      throw new DatabaseInvalidConnection;
  }
}

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

interface Database{
  public function insert($into, $cell, $data);
  public function connect();
}
class Mysql implements Database
{
  public function connect()
  {
    // connect to  mysql database
  }
  public function insert($into, $cell, $data)
  {
    // insert into mysql and return id
  }
}
class NoSql implements Database
{
  public function connect()
  {
    // connect to  mongodb database
  }
  public function insert($into, $cell, $data)
  {
    // insert into mongodb and return id
  }
}
class DB
{
  public function insert($connection, $into, $cell, $data)
  {
    $connection->connect();
    $connection->insert($into, $cell, $data);
  }
}

حالا برای هر پایگاه داده تنهای نیازه کلاس بر اساس اینترفیس دیتابیس پیاده سازی بشه بدون هیچ تغییری کد با پایگاه داده جدید کار خواهد کرد.

اصول Solid در php

Liskov Substitution

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

برای مثال ما کد زیر را داریم :

interface OutputInterface{
  public function show($data);
}
class Output implements OutputInterface{
  public function show($data)
  {
    // show data
  }
}

class Formatter extends Output
{
  public function jsonFormat($data)
  {
    // return json data
  }
  public function show($data)
  {
    $data = $this->jsonFormat($data);
    // show Data
  }
}

در این کد اصول Solid رعایت نشده است یا به عبارت بهتر Liskov substitution به درستی اعمال نشده است. کلاس Formatter فرزند کلاس Outputمیباشد و باید تمامی فعالیت های کلاس والد را بتواند انجام دهد. اگر قسمتی از کد که از کلاس Output استفاده شده است را تغییر دهیم به صورتی که از کلاس Formatter استفاده کند خروجی مد نظر ما داده نمیشود زیرا در این کلاس متد show را ما مجددا بازنویسی کردیم و خروجی به صورت json نمایش داده میشود.

Interface Segregation

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

کد زیر را در نظر بگیرید:

interface ImagesInterface
{
  public function setWatermark($src);
  public function saveFile($file, $path);
}

class Image implements ImagesInterface
{
  public function setWatermark($src)
  {
    // set watermark
  }
  public function saveFile($file, $path)
  {
    // save file
  }
}

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

interface ImagesInterface
{
  public function setWatermark($src);
}
interface FileInterface
{
  public function saveFile($file, $path);
}
class Image implements ImagesInterface,FileInterface
{
  public function setWatermark($src)
  {
    // set watermark
  }
  public function saveFile($file, $path)
  {
    // save file
  }
}

Dependency Inversion

یکی اصل مهم از Solid میباشد که بیان میکند که یک ماژول سطح بالا نباید به یک ماژول سطح پایین وابسته باشد بلکه هر دوی آنها باید به abstractionsوابسته باشند. abstractions نباید به جزئیات وابسته باشد بلکه جزیئات باید به abstractions وابسته باشد.

اصول Solid در php

درک این مفهوم ممکنه برای شما از درک مفاهیم بیان شده سخت تر باشه، با یک مثال این اصل رو واضح تر میکنیم. فرض کنید شما قطعه کد زیر را برای ایندکس کردن داده ها در وب دارید :

class Crawler
{
  public function crawlPage()
  {
    // crawl Page with DOMDocument
  }
}
class Engines
{
  public function indexing(Crawler $crawler)
  {
    $crawler->crawlPage();
  }
}

اگر در قطع کد بالا ما در بدنه کلاس Crawler تغییر ایجاد کنیم ، کلاس Engines هم تحت تاثیر قرار میگرد. برای حل این مسئله کد را به شکل زیر تغییر میدهیم:

interface CrawlerInterface
{
  public function crawlPage();
}

class Crawler implements CrawlerInterface
{
  public function crawlPage()
  {
    // crawl Page with DOMDocument
  }
}
class Engines
{
  public function indexing(CrawlerInterface $crawler)
  {
    $crawler->crawlPage();
  }
}

نتیجه گیری : امیدوارم در این مقاله تونسته باشم به خوبی شما را با این اصول آشنا کنم. رعایت اصول Solid شاید در ابتدا کمی دشوار باشد اما با رعایت تمامی موارد گفته شده در کنار هم مزایای زیادی برای شما به وجود می آورد مانند: توسعه پذیری کدها، انعطاف پذیری بیشتر، یکپارچگی، پایداری و … .

اصول Solid در php

 

0 پاسخ

دیدگاه خود را ثبت کنید

Want to join the discussion?
Feel free to contribute!

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *