PHP 设计模式简介

已发表: 2020-04-14

PHP 设计模式已被证明对开发人员非常有用,并且是一个主要的问题解决者。 为了编写高效的代码,开发人员必须遵循最佳实践。 PHP 设计模式是一种面向对象的编程 (OOP) 概念,现在也用于 Drupal 8 项目。 随着 Drupal 8 采用现代 PHP 和 OOP 概念,可以利用设计模式进行更清晰、更健壮的编程。

PHP 中的设计模式

PHP 中的设计模式是什么?

在软件工程中,设计模式是软件设计中常见问题的通用可重复解决方案。 好的面向对象设计应该是可重用、可维护和可扩展的,而 PHP 中的设计模式在这方面非常有帮助。 它不仅有助于解决问题,还暗示了解决共同挑战的最佳方式。

使用 PHP 设计模式的好处

PHP 设计模式的主要优点是:

  • PHP 设计模式有助于解决开发过程中面临的重复问题
  • 在 PHP 中使用设计模式可以让设计者之间的交流更高效
  • 查看您的代码的其他开发人员不必费力理解,因为代码结构良好,具有设计模式
  • 遵循最佳实践有助于构建更强大的软件
  • 它有助于使开发更快更容易

PHP 中广泛使用的设计模式

设计模式可以在各种情况下使用来解决类似的问题。 大约有 23 种设计模式,可以大致分为三种类型的设计模式——创建模式、结构模式和行为模式。

创建模式:在对象创建机制中使用的设计模式,用于创建可以与实现它们的系统分离的对象。

结构模式:通过识别实现实体之间关系的简单方法来简化设计

行为模式:它们用于管理对象之间的关系、职责和算法

工厂模式

工厂模式用于构建对象。 没错——构建一个对象而不是创建一个对象。 当我们构建对象时,我们首先创建它,然后初始化它。 通常,它需要应用一定的逻辑并执行多个步骤。 有了这个,将所有这些放在一个地方并在需要以相同方式构建新对象时重新使用它是有意义的。 从根本上说,这就是工厂模式的使用。
为我们的工厂提供一个接口并让我们的代码依赖它而不是一个具体的工厂是一个好主意

 界面 家庭工厂接口{
    上市 功能 创建():家庭
}

接下来,使用以下类实现工厂接口:

班级 家庭工厂 工具 家庭工厂接口{

上市 功能 创建():家庭{

$family = new Family();

// 初始化你的家庭

返回 $family;

}

}

适配器模式

在适配器设计模式中,一个类将一个类的接口转换为另一个类。在这个例子中,我们有一个TextBook类,它有一个 getTitle() 和 getAuthor() 方法。 客户端需要一个 getTitleAndAuthor() 方法。 为了“适应” SimpleBookdemoAdapter我们有一个适配器类,BookAdapter,这需要在教科书的一个实例,并使用教科书的getTitle()和getAuthor()方法在自己的getTitleAndAuthor方法。

<?php

班级 教科书{

私人$title;
私人$author;
功能 __construct ($title_in, $author_in) {
$this ->title = $title_in;

$this ->author = $author_in;
}

功能 获取标题(){
返回 $this -> 标题;
}
功能 获取作者(){
返回 $this ->作者;
}
}

班级 书本适配器{
私人$book;
功能 __construct(教科书$ book_in){
$this ->book = $book_in;
}
功能 getTitleAndAuthors () {
返回 $this ->book->getTitle()。 '由' $this ->book->getAuthor();
}
}

// 客户

writeln( '开始测试适配器模式' );
writeln( '' );

$book = new TextBook( "Gamma, Helm, Johnson, and Vlissides" , "设计模式" );
$bookAdapter = new BookAdapter($book);
writeln( '作者和标题:' .$bookAdapter->getTitleAndAuthor());
writeln( '' );

writeln( '结束测试适配器模式' );

功能 writeln ($line_in) {
回声$line_in。 "<br/>" ;
}

?>

PHP 单例模式

为了将类的实例化限制为单个对象,PHP 中使用了单例模式。 当整个系统只需要一个对象时,这会很有用。 在设计 Web 应用程序时只允许访问某个类的一个实例是有意义的。 为了防止从单例模式类显式创建对象,使用了私有构造函数。

<?php
班级 单身人士
{
上市 静止的 功能 获取实例()
{
静态$instance = null ;
if ( null === $instance) {
$实例 = 静态();
}
返回$instance;
}
受保护 功能 __构造()
{
}
私人的 功能 __克隆()
{
}
私人的 功能 __唤醒()
{
}
}
班级 单身儿童 延伸 单身人士
{
}
$obj = Singleton::getInstance();
var_dump($obj === Singleton::getInstance());
$obj2 = SingletonChild::getInstance();
var_dump($obj2 === Singleton::getInstance());
var_dump($obj2 === SingletonChild::getInstance());
?>

PHP中的观察者模式

PHP Observer 模式用于向系统的其余部分发出有关特定位置的特定事件的警报。
例如,如果我们需要创建一个剧院来向评论家展示电影。 我们用当前方法定义了Theatre类。 在放映电影之前,我们想向影评人的手机发送消息。 然后,在电影中途我们要暂停电影5分钟,让影评人有一个间隔。 最后,在电影结束后,我们想请影评人留下他们的回应。 因此,在 PHP 的观察者模式中,观察者对象仅在状态更改时收到通知。

这就是代码的样子 -

班级 剧院{

上市 功能 当前(电影 $movie):无效{

$critics = $movie->getCritics();
$this ->message->send($critics, '...' );

$电影->播放();

$电影->暂停( 5 );
$this ->progress->interval($critics)
$电影->结束();

$this ->response->request($critics);
}
}

PHP 装饰器模式

当您想在运行时更改对象的特征时,可以使用装饰器模式,从而减少不必要的继承和类的数量。 嗯,可以举例说明。 假设我们有类 Sofa 和 Bed,它们都实现了 SleeperInterface。

界面 睡眠者接口{
上市 功能 睡眠():无效;
}
班级 沙发 工具 卧铺接口{
上市 功能 睡眠():无效{
// 睡沙发
}
}
班级 工具 卧铺接口{
上市 功能 睡眠():无效{
// 睡在床上
}
}

沙发和床都有相同的睡眠行为。 现在,我们需要其他具有附加功能的沙发和床,当用户睡在沙发或床上时,它们会告诉用户睡眠跟踪。 通过继承,我们可以像这样解决这个问题:

班级 智能沙发 延伸 沙发{
公共函数睡眠():无效{
父母::睡眠();
$ this ->sleepHours();
}
}
班级 智能床 延伸 窗口{
公共函数睡眠():无效{
父母::睡眠();
$ this ->sleepHours();
}
}

现在我们总共有4个班级。 然而,我们可以只用装饰器模式用 3 个类来解决这个问题。 就是这样:

班级 智能睡眠 工具 卧铺接口{

私人$sleeper;
上市 功能 __construct (SleeperInterface $sleeper) {
$this ->sleeper = $sleeper;
}

上市 功能 睡眠():无效{
$this ->sleeper->sleep();
$this ->sleepHours();
}
}
$sofa = new Sofa();
$bed = new Bed();
$smartSofa = new SmartSleeper($sofa);
$smartBed = new SmartSleeper($bed);

在这里,我们引入了一种新型的 sleeper,它的作用类似于代理,但在其之上具有额外的功能。

在 Drupal 8 中利用设计模式

虽然在 Drupal 8 之前 Drupal 中已经建立了许多设计模式,但现在 Drupal 8 包含了许多以前不可用的模式。 其中一些新模式完全取代了一些旧模式,而另一些则为 Drupal 8 引入了一些新功能。

Drupal 8 中使用的设计模式包括:

  • 面向对象的编程模式 (OOP)
  • 依赖注入
  • 工厂模式
  • 单例模式

OOP 并不是真正的单一模式,而是一种超越设计模式的概念化和结构化代码的完全激进的方式。 它是当今使用的许多流行软件设计模式的基础,包括在 Drupal 8 中使用的那些。它在 Drupal 7 中被引入,但没有被广泛使用,也不是必需的。 Drupal 8 中的情况现在不同了,它被广泛使用,它是必需的。

依赖注入

依赖注入是一种软件设计模式,它允许您删除硬编码的依赖项,并且还可以在运行时或编译时更改它们。 添加依赖注入很容易,并且不会干扰您现有的代码。 Drupal 8 引入了服务的概念,以分离可重用的功能。 core.services.yml 是 Drupal 8 中依赖注入的一个例子。我们已经在上面讨论了 PHP 中的工厂模式和单例模式