PHP设计模式之模板方法模式

PHP设计模式之模板方法模式

模板方法模式,也是咱们常常会在不经意间有会用到的模式之一。这个模式是对继承的最好诠释。当子类中有重复的动做时,将他们提取出来,放在父类中进行统一的处理,这就是模板方法模式的最简单通俗的解释。就像咱们平时作项目,每次的项目流程实都差很少,都有调研、开发、测试、部署上线等流程。而具体到每一个项目中,这些流程的实现又不会彻底相同。这个流程,就像是模板方法,让咱们每次都按照这个流程进行开发。php

Gof类图及解释

GoF定义:定义一个操做中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类能够不改变一个算法的结构便可重定义该算法的某些特定步骤。git

GoF类图github

模板方法模式

代码实现redis

abstract class AbstractClass {
    public function TemplateMethod() {
        $this->PrimitiveOperation1();
        $this->PrimitiveOperation2();
    }

    abstract public function PrimitiveOperation1();
    abstract public function PrimitiveOperation2();
}
复制代码

定义一个抽象类,有一个模板方法TemplateMethod(),这个方法中咱们对算法操做方法进行调用。而这些算法抽象方法是在子类中去实现的。算法

class ConcreteClassA extends AbstractClass {
    public function PrimitiveOperation1() {
        echo '具体类A实现方法1', PHP_EOL;
    }
    public function PrimitiveOperation2() {
        echo '具体类A实现方法2', PHP_EOL;
    }
}

class ConcreteClassB extends AbstractClass {
    public function PrimitiveOperation1() {
        echo '具体类B实现方法1', PHP_EOL;
    }
    public function PrimitiveOperation2() {
        echo '具体类B实现方法2', PHP_EOL;
    }
}
复制代码

具体的实现类,它们只须要去实现父类所定义的算法就能够了。设计模式

$c = new ConcreteClassA();
$c->TemplateMethod();

$c = new ConcreteClassB();
$c->TemplateMethod();
复制代码

在客户端的调用中,实例化子类,但调用的是子类所继承的父类的模板方法。就能够实现统一的算法调用了。缓存

  • 模板方法模式相信只要是作过一点面向对象开发的朋友都会多多少少使用过。由于真的很是常见
  • 一些框架中常常会有某些功能类有初始化的功能,在初始化的函数中都会调用不少内部的其余函数,这其实也是一种模板方法模式的应用
  • 模板方法模式能够很方便的实现钩子函数。就像不少模板或者开源系统中给你准备好的钩子函数。好比某些博客开源程序会预留一些广告位或者特殊位置的钩子函数让使用者本身按需实现
  • 模板方法模式适用于:一次性实现一个算法中不变的部分,并将可变的部分留给子类来实现;将子类中公共的行为提取出来并集中到父类中;控制子类的扩展;
  • 这个模式体现了一个叫“好莱坞法则”的原则,那就是“别找咱们,咱们来找你”

在公司中,我很是的推崇敏捷式的项目管理,固然,这里也不是说传统的项目管理有多么很差,只是敏捷更适合咱们这种短平快的公司。在敏捷中,咱们采用的是Scurm框架,它其实就是一个模板。它定义了四种会议、三种人员、三个工具。在每一个项目的具体实现中,咱们都会遵照这些规则,但具体的实现又不会同样。好比有时咱们是一周一个迭代,有时是一个月一个迭代。有时咱们不须要回顾会议,而是将回顾和评审会议放在了一块儿进行。无论怎么样,咱们会在Scurm的基础上进行灵活的项目开发。而作为领导的我,只须要在每一个项目中调取Scurm的基本流程就能够了。因此说,公司的强大和你们的学习是分不开的,好用的东西固然要时刻学习分享并应用啦!!框架

完整代码:github.com/zhangyue050…memcached

实例

不发短信了,此次咱们实现的是一个Cache类的初始化部分。就像上文说过的一些框架中的工具类。通常Cache咱们会使用Memcached或者Redis来实现,因此咱们抽取一个公共Cache类,而后让Memcached和Redis的Cache实现类都继承它。在公共类中,经过模板方法来进行实现类的一些初始化工做,这些工做由父类统一调用,实现类只须要实现每个步骤的具体内容就能够了。函数

缓存类图

缓存模板方法模式版

完整源码:github.com/zhangyue050…

<?php

abstract class Cache {
    private $config;
    private $conn;

    public function __construct() {
        $this->init();
    }
    public function init() {
        $this->GetConfig();
        $this->OpenConnection();
        $this->CheckConnection();
    }

    abstract public function GetConfig();
    abstract public function OpenConnection();
    abstract public function CheckConnection();
}

class MemcachedCache extends Cache {
    public function GetConfig() {
        echo '获取Memcached配置文件!', PHP_EOL;
        $this->config = 'memcached';
    }
    public function OpenConnection() {
        echo '连接memcached!', PHP_EOL;
        $this->conn = 1;
    }
    public function CheckConnection() {
        if ($this->conn) {
            echo 'Memcached链接成功!', PHP_EOL;
        } else {
            echo 'Memcached链接失败,请检查配置项!', PHP_EOL;
        }
    }
}

class RedisCache extends Cache {
    public function GetConfig() {
        echo '获取Redis配置文件!', PHP_EOL;
        $this->config = 'redis';
    }
    public function OpenConnection() {
        echo '连接redis!', PHP_EOL;
        $this->conn = 0;
    }
    public function CheckConnection() {
        if ($this->conn) {
            echo 'Redis链接成功!', PHP_EOL;
        } else {
            echo 'Redis链接失败,请检查配置项!', PHP_EOL;
        }
    }
}

$m = new MemcachedCache();

$r = new RedisCache();

复制代码

说明

  • 这样一个简单的缓存类咱们就实现了。是否是和不少框架中的代码很是相似。
  • 子类只须要定义本身的实现就能够了,剩下的重复代码都让父类去完成,若是没有父类,它们都须要本身实现一个init()方法
  • 固然,须要增长其它的实现类时,也只须要继承这个Cache父类后完成本身的实现就能够了,客户端面对这些实现类都能很是轻松,由于它们知道本身只须要先调用一下初始化方法可使用这个类了,不论是哪个实现类都是同样的

下期看点

模板方法模式是否是也很是简单。最主要的是这样的设计模式跟咱们的生活很接近,在咱们的工做学习过程会很是容易见到并使用到。这样的模式简直不能挂在经常使用设计模式的标签下,由于它比经常使用更经常使用。好了,咱们的进度还不错哟,下一个模式正等着咱们呢,它但是大名鼎鼎的单例模式

相关文章
相关标签/搜索