首页 后端开发 php教程 一文读懂php设计模式之模板方法模式

一文读懂php设计模式之模板方法模式

Aug 06, 2020 pm 05:02 PM
php设计模式 模板方法

模板方法模式也是一种常用的设计模式,它属于行为性设计模式。它的定义是:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

场景

一般周末早上起来比较晚,就不会出去买早点吃,可能就会泡一桶方便面或酸辣粉或淮南牛肉汤。泡方便面或酸辣粉的步骤是一样的,首先需要准备开水,然后用开水泡方便面或酸辣粉,接下来加入自己的调料包,最后泡上2~3分钟就行了。这中间有两个步骤完全一致(准备开水、泡2~3分钟)、有两个步骤类似(泡食材、加入各自调料包)。

对于上面的场景,我们可以定义一个泡方便面或酸辣粉的算法。这个算法非常简单,4个步骤

  • 准备开水

  • 泡食材(方便面或酸辣粉)

  • 加调料(方便面、酸辣粉有自己的调料包)

  • 在开水中浸泡2~3分钟

现在,我们用模板方法模式来完成上述需求。

首先,定义一个抽象类,抽象类里定义具体的算法,以及各个步骤。

abstract class Breakfast
{
    final public function prepare () {
        $this->boilWater();
        $this->brew();
        $this->addSeasoning();  
        $this->wait();
    }
    
    public function boilWater ()
    {
        echo '准备开水' . PHP_EOL;
    }
    
    // 泡食材
    abstract public function brew ();
    
    // 加调料
    abstract public function addSeasoning ();
    
    public function wait ()
    {
        echo '等待2~3分钟' . PHP_EOL;
    }
}
登录后复制

prepare方法里就是具体的算法,给这个方法加上final是防止该方法被重写。另外,你可以看到这里面有两个抽象方法,需要后代去自行完成。

接下来,我们来完成方便面及酸辣粉的类。这两个类需继承Breakfast,然后完成抽象方法。

class Noodle extends Breakfast
{
    public function brew ()
    {
        echo '加入方便面' . PHP_EOL;
    }
    public function addSeasoning ()
    {
        echo '加入方便面的调料包' . PHP_EOL;
    }
}

class Powder extends Breakfast
{
    public function brew ()
    {
        echo '加入酸辣粉' . PHP_EOL;
    }
    public function addSeasoning ()
    {
        echo '加入酸辣粉的调料包' . PHP_EOL;
    }
}
登录后复制

上述的例子就是一个典型的模板方法模式,父类里定义算法骨架,子类完成算法中的一些步骤。

钩子

上述的例子,体现了模板方法模式中一个常用场景:复用。除了复用外,模板方法模式还是一个重要的应用——扩展。

模板方法模式是通过钩子来实现扩展的。钩子是一种声明在抽象类中的方法,但只有空的或默认的实现。钩子的存在,让子类有能力对算法不同点进行挂钩。要不要挂钩,由子类自己决定。

下面我们继续通过例子来讲解钩子的使用,一般我吃泡面的时候,会加火腿或鸡蛋。加火腿和鸡蛋这个是不确定的,所以我们可以钩子,让子类自己决定要不要加火腿或鸡蛋。

修改Breakfast.php

abstract class Breakfast
{
    final public function prepare () {
        $this->boilWater();
        $this->brew();
        $this->addSeasoning();
        $this->hook();
        $this->wait();
    }
    
    
    // 省略部分方法
    
    
    // 默认不做任何事情
    public function hook () :void
    {}
}
登录后复制

修改Noodle.php,重写hook方法

public function hook(): void
{
    echo '加入火腿和鸡蛋' . PHP_EOL;
}
登录后复制

模板方法模式与回调函数

php中有许多的函数用了类似模板方法模式或策略模式的思想,比如sort()函数,它封装了排序的算法,但是具体的排序规则,由回调函数去完成。通过回调函数就不用去创建抽象类以及子类了,大大的减少了代码量。

模板方法模式与工厂方法模式、策略模式的关系

工厂方法模式时模板方法模式一个特殊的形式。

模板方法基于继承机制: 它允许你通过扩展子类中的部分内容来改变部分算法。 

策略模式基于组合机制: 你可以通过对相应行为提供不同的策略来改变对象的部分行为。

 模板方法在类层次上运作, 因此它是静态的。 策略在对象层次上运作, 因此允许在运行时切换行为。

以上是一文读懂php设计模式之模板方法模式的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

会话如何劫持工作,如何在PHP中减轻它? 会话如何劫持工作,如何在PHP中减轻它? Apr 06, 2025 am 12:02 AM

会话劫持可以通过以下步骤实现:1.获取会话ID,2.使用会话ID,3.保持会话活跃。在PHP中防范会话劫持的方法包括:1.使用session_regenerate_id()函数重新生成会话ID,2.通过数据库存储会话数据,3.确保所有会话数据通过HTTPS传输。

描述扎实的原则及其如何应用于PHP的开发。 描述扎实的原则及其如何应用于PHP的开发。 Apr 03, 2025 am 12:04 AM

SOLID原则在PHP开发中的应用包括:1.单一职责原则(SRP):每个类只负责一个功能。2.开闭原则(OCP):通过扩展而非修改实现变化。3.里氏替换原则(LSP):子类可替换基类而不影响程序正确性。4.接口隔离原则(ISP):使用细粒度接口避免依赖不使用的方法。5.依赖倒置原则(DIP):高低层次模块都依赖于抽象,通过依赖注入实现。

在PHPStorm中如何进行CLI模式的调试? 在PHPStorm中如何进行CLI模式的调试? Apr 01, 2025 pm 02:57 PM

在PHPStorm中如何进行CLI模式的调试?在使用PHPStorm进行开发时,有时我们需要在命令行界面(CLI)模式下调试PHP�...

如何在系统重启后自动设置unixsocket的权限? 如何在系统重启后自动设置unixsocket的权限? Mar 31, 2025 pm 11:54 PM

如何在系统重启后自动设置unixsocket的权限每次系统重启后,我们都需要执行以下命令来修改unixsocket的权限:sudo...

解释PHP中的晚期静态绑定(静态::)。 解释PHP中的晚期静态绑定(静态::)。 Apr 03, 2025 am 12:04 AM

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

如何用PHP的cURL库发送包含JSON数据的POST请求? 如何用PHP的cURL库发送包含JSON数据的POST请求? Apr 01, 2025 pm 03:12 PM

使用PHP的cURL库发送JSON数据在PHP开发中,经常需要与外部API进行交互,其中一种常见的方式是使用cURL库发送POST�...

See all articles