SOLID原理的简单说明



原则SOLID是所有开发人员都必须理解的编程标准,以避免创建不良的体系结构。 该标准在OOP中被广泛使用。 如果正确应用,它将使代码更具可扩展性,逻辑性和可读性。 当开发人员在糟糕的体系结构的指导下创建应用程序时,代码变得不灵活,即使很小的更改也可能导致错误。 因此,您必须遵循SOLID的原则。

掌握它们将花费一些时间,但是如果您按照这些原则编写代码,其质量将会提高,并且您将掌握创建一个好的软件体系结构的过程。

要了解SOLID的原理,您需要清楚地了解如何使用界面。 如果您不了解,请先阅读文档

我将以最简单的方式说明SOLID,因此对于初学者来说更容易理解。 我们将一一考虑原则。

单一责任原则

导致班级变更的原因只有一个。
一堂课只能解决一个问题。 它可能有几种方法,但是它们仅应用于解决一般问题。 所有方法和属性都应达到一个目的。 如果一个类有多个目的,则必须将其划分为单独的类。

考虑一个例子:

<?php
namespace Demo;
use DB;

class OrdersReport
{
    public function getOrdersInfo($startDate, $endDate)
    {
        $orders = $this->queryDBForOrders($startDate, $endDate);
        
        return $this->format($orders);
    }

    protected function queryDBForOrders($startDate, $endDate)
    {   // If we would update our persistence layer in the future,
        // we would have to do changes here too. <=> reason to change!
        return DB::table('orders')->whereBetween('created_at', [$startDate, $endDate])->get();
    }

    protected function format($orders)
    {   // If we changed the way we want to format the output,
        // we would have to make changes here. <=> reason to change!
        return '<h1>Orders: ' . $orders . '</h1>';
    }
}

. ? , (, ). .

, , , XML, JSON, HTML ..

:

<?php
namespace Report;
use Report\Repositories\OrdersRepository;

class OrdersReport
{
        protected $repo;
        protected $formatter;

        public function __construct(OrdersRepository $repo, OrdersOutPutInterface $formatter)
        {
                $this->repo = $repo;
                $this->formatter = $formatter;
        }

        public function getOrdersInfo($startDate, $endDate)
        {
                $orders = $this->repo->getOrdersWithDate($startDate, $endDate);

                return $this->formatter->output($orders);
        }
}

namespace Report;

interface OrdersOutPutInterface
{
        public function output($orders);
}

namespace Report;

class HtmlOutput implements OrdersOutPutInterface
{
        public function output($orders)
        {
                return '<h1>Orders: ' . $orders . '</h1>';
        }

}

namespace Report\Repositories;
use DB;

class OrdersRepository
{
    public function getOrdersWithDate($startDate, $endDate)
    {
        return DB::table('orders')->whereBetween('created_at', [$startDate, $endDate])->get();
    }
}

/ (Open-closed Principle)


, .
(, , ) . , .

:

<?php
class Rectangle
{
    public $width;
    public $height;
    public function __construct($width, $height)
    {
        $this->width = $width;
        $this->height = $height;
    }
}

class Circle
{
    public $radius;
    public function __construct($radius)
    {
        $this->radius = $radius;
    }
}

class AreaCalculator
{
    public function calculate($shape)
    {
        if ($shape instanceof Rectangle) {
            $area = $shape->width * $shape->height;
        } else {
            $area = $shape->radius * $shape->radius * pi();
        }
        
        return $area;
    }
}

$circle = new Circle(5);
$rect = new Rectangle(8,5);
$obj = new AreaCalculator();
echo $obj->calculate($circle);

, AreaCalculator. /, , .

? :

<?php
interface AreaInterface
{
    public  function calculateArea();
}

class Rectangle implements AreaInterface
{
    public $width;
    public $height;

    public function __construct($width, $height)
    {
        $this->width = $width;
        $this->height = $height;
    }
    public  function calculateArea(){
        $area = $this->height *  $this->width;
        return $area;
    }
}
  
class Circle implements  AreaInterface
{
    public  $radius;

    public function __construct($radius)
    {
        $this->radius = $radius;
    }
    
    public  function calculateArea(){
        $area = $this->radius * $this->radius * pi();
        return $area;
    }
}

class AreaCalculator
{
    public function calculate($shape)
    {
        $area = 0;
        $area = $shape->calculateArea();
        return $area;
    }
}

$circle = new Circle(5);
$obj = new AreaCalculator();
echo $obj->calculate($circle);

, AreaCalculator.

(Liskov Substitution Principle)


“Data abstraction” 1987-. 1994- :
φ(x) — x T. φ(y) y S, S — T.
, , :
  1. .
  2. .
  3. .
1996- , :
, , , .
: / / .

, () , . , , , , , , . .

:

<?php
interface LessonRepositoryInterface
{
    /**
     * Fetch all records.
     *
     * @return array
     */
    public function getAll();
}

class FileLessonRepository implements LessonRepositoryInterface
{
    public function getAll()
    {
        // return through file system
        return [];
    }
}

class DbLessonRepository implements LessonRepositoryInterface
{
    public function getAll()
    {
        /*
            Violates LSP because:
              - the return type is different
              - the consumer of this subclass and FileLessonRepository won't work identically
         */
        // return Lesson::all();

        // to fix this
        return Lesson::all()->toArray();
    }
}

(Interface Segregation Principle)

, .
, , .

, .

:

<?php
interface workerInterface
{
    public  function work();
    public  function  sleep();
}

class HumanWorker implements workerInterface
{
    public  function work()
    {
        var_dump('works');
    }

    public  function  sleep()
    {
        var_dump('sleep');
    }
}

class RobotWorker implements workerInterface
{
    public  function work()
    {
        var_dump('works');
    }

    public  function sleep()
    {
        // No need
    }
}

RobotWorker’ , sleep, . . :

<?php
interface WorkAbleInterface
{
    public  function work();
}

interface SleepAbleInterface
{
    public  function  sleep();
}

class HumanWorker implements WorkAbleInterface, SleepAbleInterface
{
    public  function work()
    {
        var_dump('works');
    }
    
    public  function  sleep()
    {
        var_dump('sleep');
    }
}

class RobotWorker implements WorkAbleInterface
{
    public  function work()
    {
        var_dump('works');
    }
}

(Dependency Inversion Principle)

. .
. .
: , - .

, , , .

:

<?php
class MySQLConnection
{
   /**
   * db connection
   */
   public function connect()
   {
      var_dump('MYSQL Connection');
   }
}

class PasswordReminder
{    
    /**
     * @var MySQLConnection
     */
     private $dbConnection;
     

    public function __construct(MySQLConnection $dbConnection) 
    {
      $this->dbConnection = $dbConnection;
    }
}

, « » « ». .

, , MySQLConnection PasswordReminder, MySQLConnection. PasswordReminder MySQLConnection.

MySQLConnection MongoDBConnection, PasswordReminder.

PasswordReminder , - . ? :

<?php
interface ConnectionInterface
{
    public function connect();
}

class DbConnection implements ConnectionInterface
{

    /**
     * db connection
     */
    public function connect()
    {
        var_dump('MYSQL Connection');
    }
}

class PasswordReminder
{
    /**
     * @var ConnectionInterface
     */

    private $dbConnection;

    public  function __construct(ConnectionInterface $dbConnection)
    {
        $this->dbConnection =  $dbConnection;
    }
}

MySQLConnection MongoDBConnection. PasswordReminder, PasswordReminder .

Source: https://habr.com/ru/post/zh-CN412699/


All Articles