PHP八大设计模式

如梦初醒
2022-03-06 / 0 评论 / 32 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年03月11日,已超过115天没有更新,若内容或图片失效,请留言反馈。

单例模式

<?php


namespace App\Http\Controllers\Admin;


use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\ValidationData;

class JwtAuth
{
    private $token;
    private $user_id;
    private $secrect="#awadakvcabzijvjvsuvr";
    private $aud="www.test.com";
    private $iss="www.test.com";
    private $decodeToken;
    /**
     * JTW句柄
     * @var
     */
    private static $instance;

    public static function getInstance(){
        if (is_null(self::$instance)){
            self::$instance =new self();
        }
        return self::$instance;
    }

    private function __construct()
    {
    }

    private function __clone(){

    }

    public function getToken(){
        return (string)$this->token;
    }

    public function setToken($token){
        $this->token = $token;

        return $this;
    }

    public function setUid($user_id){
        $this->user_id =$user_id;
        return $this;
    }

    public function encode(){
        $time= time();
       $this->token = (new Builder())
           ->setHeader('alg','HS256')
           ->setIssuer($this->iss)
           ->setAudience($this->aud)
           ->setIssuedAt($time)
           ->setExpiration($time+3600)
           ->set('user_id',$this->user_id)
           ->sign(new Sha256(), $this->secrect)
           ->getToken();
       return $this;
    }

    /**
     * @return \Lcobucci\JWT\Token
     */
    public function decode(){
        if (!$this->decodeToken){
            $this->decodeToken = (new Parser())->parse((string)$this->token);
            $this->user_id = $this->decodeToken->getClaim('user_id');
        }

        return $this->decodeToken;
    }

    /**
     * @return bool
     */
    public function validate(){
        $data = new ValidationData();
        $data->setIssuer($this->iss);
        $data->setAudience($this->aud);

        return $this->decode()->validate($data);
    }

    /**
     * @return bool
     */
    public function verify(){
        $result = $this->decode()->verify(new Sha256() , $this->secrect);
        return $result;
    }

    public function getUid(){
      return (new Parser())->parse((string)$this->token)->getClaim('user_id');
    }



}

$jwtAuth = JwtAuth::getInstance();
$token = $jwtAuth->setUid($id)->encode()->getToken();

工厂模式


// 最基本的工厂模式  

class Myname{  
    public function OutPutMyName(){  
        return 'hello world~';  
    }  
}

class NameFactory{  
    public static function Namefunc(){  
        return new Myname();  
    }  
}

$obj=NameFactory::Namefunc();  
echo $obj->OutPutMyName();  
?>  

<?php  
//定义一个抽象类  
abstract class operation  
{  
    protected $_numA = 0;  
    protected $_numB = 0;  
    protected $_result = 0;  
    public function __construct($a, $b)  
    {  
        $this->_numA = $a;  
        $this->_numB = $b;  
    }  
    //抽象方法所有子类必须实现该方法  
    protected abstract function getResult();  
}  
//加法运算  
class operationAdd extends operation  
{  
    public function getResult()  
    {  
        $this->_result = $this->_numA + $this->_numB;  
        return $this->_result;  
    }  
}  
//减法运算  
class operationSub extends operation  
{  
    public function getResult()  
    {  
        $this->_result = $this->_numA - $this->_numB;  
        return $this->_result;  
    }  
}  
//乘法运算  
class operationMul extends operation  
{  
    public function getResult()  
    {  
        $this->_result = $this->_numA * $this->_numB;  
        return $this->_result;  
    }  
}  
//除法运算  
class operationDiv extends operation  
{  
    public function getResult()  
    {  
        $this->_result = $this->_numA / $this->_numB;  
        return $this->_result;  
    }  
}  
//定义工厂类  
class operationFactory  
{  
    //创建保存示例的静态成员变量  
    private static $obj;  
    //创建实例的静态方法  
    public static function CreateOperation($type, $a, $b)  
    {  
        switch ($type) {  
        case '+':  
            self::$obj = new operationAdd($a, $b);  
            break;  
        case '-':  
            self::$obj = new operationSub($a, $b);  
            break;  
        case '*':  
            self::$obj = new operationMul($a, $b);  
            break;  
        case '/':  
            self::$obj = new operationDiv($a, $b);  
            break;  
        }  
        //最后返回这个实例  
        return self::$obj;  
    }  
}  
//最后我们使用工厂模式  
$obj = operationFactory::CreateOperation('+', 100, 20);  
echo $obj->getResult(); 
如果还是理解不了这两者的区别,可以看看这个帖子: https://www.zhihu.com/question/20367734

注册模式

class  Registry  {

    protected   static  $store  =  array();
    private     static  $instance;

    public static function instance() {
        if(!isset(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function  isValid($key)  {
        return  array_key_exists($key,Registry::$store);
    }

    public function  get($key)  {
        if  (array_key_exists($key,Registry::$store))
            return  Registry::$store[$key];
    }

    public  function  set($key,  $obj)  {
        Registry::$store[$key]  =  $obj;
    }
}

//数据库链接类
class ConnectDB {

    private $host;
    private $username;
    private $password;

    private $conn;

    public function __construct($host, $username, $password){
        $this->host = $host;
        $this->username = $username;
        $this->password = $password;
    }

    public function getConnect() {
        return mysql_connect($this->host,$this->username,$this->password);
    }

}

$reg = Registry::instance();
$reg->set('db1', new ConnectDB('localhost', 'root', '123456'));
$reg->set('db2', new ConnectDB('127.0.0.2', 'test', 'test'));

print_r($reg->get('db1'));
print_r($reg->get('db2'));

class Register
{
     //定义全局属性
     protected static $objects;
 
     //将对象注册到全局的树上
     function set($alias,$object)
     {
         //将对象放到树上
         self::$objects[$alias]=$object;
     }
 
     static function get($name){
         //获取某个注册到树上的对象
         return self::$objects[$name];
     }
 
     function _unset($alias)
     {
         //移除某个注册到树上的对象。
         unset(self::$objects[$alias]);
     }
}

适配器模式(interface)

// 接口 IDatabase
 <?php
 namespace IMooc;
 interface IDatabase
 {
     function connect($host, $user, $passwd, $dbname);
     function query($sql);
     function close();
 }
MySQL
<?php
namespace IMooc\Database;
use IMooc\IDatabase;
class MySQL implements IDatabase
{
    protected $conn;
    function connect($host, $user, $passwd, $dbname)
    {
        $conn = mysql_connect($host, $user, $passwd);
        mysql_select_db($dbname, $conn);
        $this->conn = $conn;
    }

    function query($sql)
    {
        $res = mysql_query($sql, $this->conn);
        return $res;
    }

    function close()
    {
        mysql_close($this->conn);
    }
}
PDO
<?php
namespace IMooc\Database;
use IMooc\IDatabase;
class PDO implements IDatabase
{
    protected $conn;
    function connect($host, $user, $passwd, $dbname)
    {
        $conn = new \PDO("mysql:host=$host;dbname=$dbname", $user, $passwd);
        $this->conn = $conn;
    }
function query($sql)
    {
        return $this->conn->query($sql);
    }

    function close()
    {
        unset($this->conn);
    }
}

/**
 * 目标角色
 */
interface Target {
 
    /**
     * 源类也有的方法1
     */
    public function sampleMethod1();
 
    /**
     * 源类没有的方法2
     */
    public function sampleMethod2();
}
 
/**
 * 源角色
 */
class Adaptee {
 
    /**
     * 源类含有的方法
     */
    public function sampleMethod1() {
        echo 'Adaptee sampleMethod1 <br />';
    }
}
 
/**
 * 类适配器角色
 */
class Adapter extends Adaptee implements Target {
 
    /**
     * 源类中没有sampleMethod2方法,在此补充
     */
    public function sampleMethod2() {
        echo 'Adapter sampleMethod2 <br />';
    }
 
}
 
class Client {
 
    /**
     * Main program.
     */
    public static function main() {
        $adapter = new Adapter();
        $adapter->sampleMethod1();
        $adapter->sampleMethod2();
 
    }
 
}

策略模式

UserStrategy.php
<?php
/*
 * 声明策略文件的接口,约定策略包含的行为。
 */
interface UserStrategy
{
    function showAd();
    function showCategory();
}
FemaleUser.php
<?php
require_once 'Loader.php';
class FemaleUser implements UserStrategy
{
    function showAd(){
        echo "2016冬季女装";
    }
    function showCategory(){
        echo "女装";
    }
}
MaleUser.php
<?php
require_once 'Loader.php';
class MaleUser implements UserStrategy
{
    function showAd(){
        echo "IPhone6s";
    }
    function showCategory(){
        echo "电子产品";
    }
}
Page.php//执行文件
<?php
require_once 'Loader.php';
class Page
{
    protected $strategy;
    function index(){
        echo "AD";
        $this->strategy->showAd();
        echo "<br>";
        echo "Category";
        $this->strategy->showCategory();
        echo "<br>";
    }
    function setStrategy(UserStrategy $strategy){
        $this->strategy=$strategy;
    }
}

$page = new Page();
if(isset($_GET['male'])){
    $strategy = new MaleUser();
}else {
    $strategy = new FemaleUser();
}
$page->setStrategy($strategy);
$page->index();
php策略模式和适配器模式的区别

观察者模式(Observer)

1.抽象主题(Subject)角色:主题角色将所有对观察者对象的引用保存在一个集合中,每个主题可以有任意多个观察者。 抽象主题提供了增加和删除观察者对象的接口。

2.抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在观察的主题发生改变时更新自己。

3.具体主题(ConcreteSubject)角色:存储相关状态到具体观察者对象,当具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。

4.具体观察者(ConcretedObserver)角色:存储一个具体主题对象,存储相关状态,实现抽象观察者角色所要求的更新接口,以使得其自身状态和主题的状态保持一致

主题接口

interface Subject{
    public function register(Observer $observer);
    public function notify();
}

观察者接口

interface Observer{
    public function watch();
}

被观察者

class Action implements Subject{
     public $_observers=array();
     public function register(Observer $observer){
         $this->_observers[]=$observer;
     }
 
     public function notify(){
         foreach ($this->_observers as $observer) {
             $observer->watch();
         }
 
     }
 }

观察者

class Cat implements Observer{
     public function watch(){
         echo "Cat watches TV<hr/>";
     }
 }
 class Dog implements Observer{
     public function watch(){
         echo "Dog watches TV<hr/>";
     }
 }
 class People implements Observer{
     public function watch(){
         echo "People watches TV<hr/>";
     }
 }

调用

$action=new Action();
$action->register(new Cat());
$action->register(new People());
$action->register(new Dog());
$action->notify();

原型模式

场景

大数据量 ( 例如:通过 ORM 模型一次性往数据库插入 1,000,000 条数据 ) 。

<?php
abstract class BookPrototype
{
    /*
    * @var string
    */
    protected $title;
    
    /*
    * @var string
    */
    protected $category;
    
    abstract public function __clone();
    
    public function getTitle(): string
    {
        return $this->title;
    }// getTitle() end
    
    public function setTitle($title)
    {
        $this->title = $title;
    }// setTitle() end
}// BookPrototype{} end

class BarBookPrototype extends BookPrototype
{
    /*
    * @var string
    */
    protected $category = 'Bar';
    
    public function __clone()
    {
    }
}// BarBookPrototype{} end

class FooBookPrototype extends BookPrototype
{
    /*
    * @var string
    */
    protected $category = 'Foo';
    
    public function __clone()
    {
    }
}// FooBookPrototype{} end

$fooPrototype = new FooBookPrototype();
$barPrototype = new BarBookPrototype();

for ($i = 0; $i < 10; $i++) {
    $book = clone $fooPrototype;
    $book->setTitle('Foo Book No ' . $i);
    echo $book->getTitle() . PHP_EOL;
}

for ($i = 0; $i < 5; $i++) {
    $book = clone $barPrototype;
    $book->setTitle('Bar Book No ' . $i);
    echo $book->getTitle() . PHP_EOL;
}
结果
<?php
Foo Book No 0
Foo Book No 1
Foo Book No 2
Foo Book No 3
Foo Book No 4
Foo Book No 5
Foo Book No 6
Foo Book No 7
Foo Book No 8
Foo Book No 9
Bar Book No 0
Bar Book No 1
Bar Book No 2
Bar Book No 3
Bar Book No 4

装饰器模式

短信模板接口


<?php
interface MessageTemplate
{
    public function message();
}

假设有很多模板实现了上面的短信模板接口

// 下面这个是其中一个优惠券发送的模板实现
class CouponMessageTemplate implements MessageTemplate
{
    public function message()
    {
        return '优惠券信息:我们是全国第一的牛X产品哦,送您十张优惠券!';
    }
}

我们来准备好装饰上面那个过时的短信模板

abstract class DecoratorMessageTemplate implements MessageTemplate
{
    public $template;
    public function __construct($template)
    {
        $this->template = $template;
    }
}

过滤新广告法中不允许出现的词汇

class AdFilterDecoratorMessage extends DecoratorMessageTemplate
{
    public function message()
    {
        return str_replace('全国第一', '全国第二', $this->template->message());
    }
}

使用我们的大数据部门同事自动生成的新词库来过滤敏感词汇,这块过滤不是强制要过滤的内容,可选择使用

class SensitiveFilterDecoratorMessage extends DecoratorMessageTemplate
{
    public $bigDataFilterWords = ['牛X'];
    public $bigDataReplaceWords = ['好用'];
    public function message()
    {
        return str_replace($this->bigDataFilterWords, $this->bigDataReplaceWords, $this->template->message());
    }
}

客户端,发送接口,需要使用模板来进行短信发送


class Message
{
    public $msgType = 'old';
    public function send(MessageTemplate $mt)
    {
        // 发送出去咯
        if ($this->msgType == 'old') {
            echo '面向内网用户发送' . $mt->message() . PHP_EOL;
        } else if ($this->msgType == 'new') {
            echo '面向全网用户发送' . $mt->message() . PHP_EOL;
        }

    }
}
$template = new CouponMessageTemplate();
$message = new Message();

// 老系统,用不着过滤,只有内部用户才看得到
$message->send($template);

// 新系统,面向全网发布的,需要过滤一下内容哦
$message->msgType = 'new';
$template = new AdFilterDecoratorMessage($template);
$template = new SensitiveFilterDecoratorMessage($template);

// 过滤完了,发送吧
$message->send($template);

引用:https://zhuanlan.zhihu.com/p/102420902https://www.cnblogs.com/yuanwanli/p/8796402.html

0

评论 (0)

取消