专栏首页Lemon黄PHP设计模式——模板方法

PHP设计模式——模板方法

在方法中定义算法的框架,将某些步骤推迟到子类。模板方法(Template Method)可让子类在不更改算法结构的情况下重新定义算法的某些步骤。

管理公司员工的日常行程可能是一项耗时的工作。如果可以使用程序将日常任务编程为自动发生,那将容易得多。Mark在Yahaa Inc工作了四年, 他是一名程序员,他的日常工作主要的是从事与编程有关的任务。Elisa是同一家公司的营销经理;像Mark一样,她有自己的日常活动,而她则主要从事营销工作。

作为程序员,Mark在公司的日常工作如下:

class Programmer
{
 
    public function workRoutine()
    {
        $this->markAttendance();
        $this->doProgrammingTask();
        $this->reportDailyCompletion();
    }
 
    public function markAttendance()
    {
        echo '我正在打卡';
    }
 
    public function doProgrammingTask()
    {
        echo '正在做编程的任务';
    }
 
    public function reportDailyCompletion()
    {
        echo '我正在报告我的每日完成进度';
    }
}
  • Mark每天到公司时,他要做的第一件事就是在出勤跟踪系统中打卡。这样可以确保他当天的工资(markAttendance())。
  • 此后,他就会投入到自己的本职工作中(doingProgrammingTask()
  • 最后,他会写一份详细的每天报告,报告他当天完成的工作(reportDailyCompletion()

现在,营销经理Elisa的行事方式与Mark几乎相同,除了第二步。作为营销人员,日常工作的第二部分是执行与营销相关的任务。

我们可以轻松地在上面的两个类中发现代码重复。程序员和营销人员都共享一些通用程序。

我们如何来重构代码呢?

如果可以在超类中定义一些通用的方法,但仍然给子类提供灵活地可以定义子类自身的功能,那么显然可以做得更好。而这就需要应用到模板方法(Template Method)模式了。

现在我们用一些预定义的函数定义一个抽象的超类:

class Employee
{
    public function workRoutine()
    {
        $this->markAttendance();
        $this->doWork();
        $this->reportDailyCompletion();
    }
 
    public function markAttendance()
    {
        echo 'I am marking my attendance';
    }
 
    public function reportDailyCompletion()
    {
        echo 'I am reporting my daily completion';
    }
 
    abstract public function doWork();
}

该类看起来与之前的Programmer类非常相似,不同之处在于,我们删除了两个类之间不同的函数,并用抽象类doWork()代替了它。

现在,让我们重构Programmer和并且可以很方便的创建针对营销人员Marketer类:

class Programmer extends Employee
{
    public function doWork()
    {
        $this->doProgrammingTask();
    }
 
    public function doProgrammingTask()
    {
        echo 'doing programming task';
    }
}
 
class Marketer extends Employee
{
    public function doWork()
    {
        $this->doMarketingTask();
    }
 
    public function doMarketingTask()
    {
        echo 'doing marketing task';
    }
}

如我们所见,ProgrammerMarketer类都变得更加整洁,不再有任何代码重复。

在我们的示例中,我们在方法(Employee类中的workRoutine()方法)中定义算法的框架,将某些步骤(doWork())推迟到子类(ProgrammerMarketer类)中。模板方法(Employee类中的doWork()方法)使子类(ProgramerMarketer类)重新定义算法的某些步骤(doWork()),而无需更改算法的结构。

本文分享自微信公众号 - Lemon黄(lemonhunag),作者:Lemon黄

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • PHP设计模式——迭代模式

    作为商店经理,Eric的工作包括检修各个部门的产品。商店中实际上有两个部门。一个部门称为男士部门,该部门存放男性用品,另一个部门称为女士部门的女性用品。每个部门...

    Lemon黄
  • 通俗易懂PHP基础【9-类和对象(1)】

    曾经见过一个摄影师喂藏羚羊喝水,同行的警察把藏羚羊赶走了,摄影师问为什么,警察说,要不然它会以为人类是善良的。

    Lemon黄
  • PHP设计模式——抽象方法

    Dragon公司的业务受到轰炸,而CEO希望特许所有海外分支机构的专营权。他首先要注意的问题是如何确保产品质量。他们不希望特许经营者削减成本和使用低质量的组件。...

    Lemon黄
  • 深入分析PHP设计模式

    工厂模式,顾名思义,如同工厂一样,你把原材料放入工厂中,出来的是成品,而你并不需要知道工厂里做了什么,工厂模式主要用于解耦。

    砸漏
  • 【php设计模式】门面模式

    门面模式又叫外观模式,用来隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系...

    码缘
  • spring的bean的注解

    bean可以xml配置,也可以采用注解,注解更加简单,注解也需要配置相关的xml文件。因为bean的装配,采用注解和使用配置不同,所以注解的schema和命名空...

    东风冷雪
  • 通过Eloquent实现Repository模式

    Eloquent采用了ActiveRecord的模式,这也让Eloquent招致了好多批评,让我们去看现在Eloquent/Model.php文件, 该文件已经...

    zhuanxu
  • Android使用Spinner实现城市级联下拉框

    最近写一个使用Spinner实现城市级联下拉框的Dome,现在总结一下,第一次写博客,互相学习。

    砸漏
  • PHP设计模式之模板方法模式

    模板方法模式,也是我们经常会在不经意间有会用到的模式之一。这个模式是对继承的最好诠释。当子类中有重复的动作时,将他们提取出来,放在父类中进行统一的处理,这就是模...

    硬核项目经理
  • PHP5.4新特性trait

    php //代码片段1 class Hello { public $id = 2; public function __constru...

    苦咖啡

扫码关注云+社区

领取腾讯云代金券