PHP 中的 SOLID 原则

2025-06-04

PHP 中的 SOLID 原则

什么是 SOLID?

你可能几乎在所有职位描述中都听说过这个术语**SOLID**,并且想知道它为什么如此重要。SOLID 原则是一套五条设计指南,旨在使软件设计更易于理解、更灵活、更易于维护。这些原则广泛应用于面向对象编程,尽管它们也可以应用于其他范式。

SOLID 原则的支柱

SOLID 的首字母缩略词代表:

  • 单一职责原则(SRP)
  • 开放封闭原则(OCP)
  • 里氏替换原则(LSP)
  • 接口隔离原则(ISP)
  • 依赖倒置原则(DIP)

1)单一职责原则

一个类应该只有一个目的或理由。这意味着这个类应该只有一个职责。我将用 PHP 示例逐一演示。

// Single Responsibility Principle

// Shouldn't do
class Report {
    public function generate() {
        // generating report
    }

    public function saveToFile($filename) {
        // save report to file
    }
}

// Should do
class Report {
    public function generate() {
        // generating report
    }
}

class ReportSaver {
    public function saveToFile(Report $report, $filename) {
        // save report to file
    }
}
Enter fullscreen mode Exit fullscreen mode

2)开闭原则

实例应该对扩展开放,但对修改关闭。这意味着实例(类、函数、模块等)可以被另一个实例扩展,但不应允许直接修改它们。

// Open Close Principle

// Shouldn't do
class Rectangle {
    public $width;
    public $height;
}

function area($rectangle) {
    return $rectangle->width * $rectangle->height;
}

// Should do
interface Shape {
    public function area();
}

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

    public function area() {
        // w * h
    }
}

class Circle implements Shape {
    public $radius;

    public function area() {
        // πr2
    }
}
Enter fullscreen mode Exit fullscreen mode

3)里氏替换原则

这意味着,超类的对象应该可以被子类的对象替换,而不会影响程序的正确性。这是什么意思呢?让我们看一下示例代码来解释一下。

// Liskov Substitution Principle

// Shouldn't do
class Animal {
    public function jump() {
        // code for jumping
    }
}

class Snail extends Animal {
    public function jump() {
        // Sanil can't jump
    }
}

// Good example
abstract class Animal {
    abstract public function eat();
}

class Snail extends Bird {
    public function eat() {
        // every animal can eat
    }
}

class Tiger extends Bird {
    public function eat() {
        // every animal can eat
    }
}
Enter fullscreen mode Exit fullscreen mode

4)接口隔离原则

我们不应该强迫实例实现它们不使用的接口。我们应该让接口在大多数情况下都具有灵活性。

// Interface Segregation Principle

// Shouldn't do
interface Human {
    public function walk();
    public function swim(); // not everyone can swim
}

// Should do
interface Walkable {
    public function walk();
}

interface Swimmable {
    public function swim();
}

class People implements Walkable, Swimmable {
    public function walk() {
        // walking
    }

    public function swim() {
        // swimming
    }
}
Enter fullscreen mode Exit fullscreen mode

5)依赖倒置原则

该原则旨在通过在高级模块(提供复杂功能)和低级模块(提供基本功能)之间引入抽象层来解耦它们。这使得高级模块和低级模块都依赖于抽象而不是固定的实现,从而使系统更加灵活、可扩展和可维护。

// Dependency Inversion Principle

// Shouldn't do
class Book {
    public function getContent() {
        // return contents
    }
}

class Printer {
    public function printBook(Book $book) {
        $content = $book->getContent();
        // print the content
    }
}
Enter fullscreen mode Exit fullscreen mode

如上例所示,Printer类依赖于Book对象,并且只能为Book 对象打印。如果还有一个名为Article的类也需要打印怎么办?我们不应该修改Printer类来接受更多对象。相反,我们应该提供它们之间的抽象。

// Dependency Inversion Principle

// Should do
interface Printable {
    public function getContent();
}

class Book implements Printable {
    public function getContent() {
        return "This is the book content";
    }
}

class Article implements Printable {
    public function getContent() {
        return "This is the article content";
    }
}

class Printer {
    public function printContent(Printable $printable) {
        $content = $printable->getContent();
        echo "Printing content: " . $content;
    }
}
Enter fullscreen mode Exit fullscreen mode

在 PHP 中,这些原则有助于创建简洁的代码库,使其更易于调试、理解和扩展。鉴于 PHP 应用程序通常会随着时间的推移而演进,应用 SOLID 原则可以显著减轻代码增长和维护的负担。

文章来源:https://dev.to/devlinaung/solid-principles-in-php-363j
PREV
10 个超棒的 Python 单行代码详解
NEXT
JavaScript 设计模式 - 第 1 章 🤓 简介 ▶ 开始吧 🙄 什么是模式? 🏷 设计模式的分类 构造函数模式 📝 摘要 🙏 感谢您的阅读!