PHP设计模式-原生工厂模式

需要先了解抽象类与接口

简单工厂:
建立一个工厂类,对实现了统一接口的一些类进行实例的创建

工厂方法:
创建一个抽象工厂类和多个具体工厂类,一旦需要增加新的功能,需要修改抽象工厂类和他所有子类

抽象工厂公共类:
创建一个工厂接口和多个工厂实现类,一旦需要增加新的功能,直接增加新的工厂类

<?php
//加入命名空间
namespace think;
/**
 * @var HttpClient
 */
class HttpClient
{
    /**
     * @var 请求的路径
     */
    private $url;

    /**
     * @var 请求方式
     */
    private $method;

    /**
     * @var 请求参数
     */
    private $param;

    /**
     * @var 请求头
     */
    private $header;

    /**
     * @var 响应结果
     */
    private $response;

    /**
     * @var 设置请求路径
     *
     * @param string url
     *
     * @return HttpClient
     */
    private function setUrl(String $url = '')
    {
        $this->url = $url;
        return $this;
    }

    /**
     * @var 设置请求参数
     *
     * @param array param
     *
     * @return HttpClient
     */
    private function setParam(Array $param)
    {
        $this->param = http_build_query($param);
        return $this;
    }

    /**
     * @var 设置请求头部
     *
     * @param array header
     *
     * @return HttpClient
     */
    private function setHeader(Array $header)
    {
        foreach ($header as $key => $value) {
            if (is_string($key)) {
                $key = constant(strtoupper($key));
            }

            $this->header[$key] = $value;
        }

        return $this;
    }

    /**
     * @var 设置请求方式
     *
     * @param string method
     *
     * @return HttpClient
     */
    private function setMethod(String $method = 'GET')
    {
        $this->method = $method;
        return $this;
    }

    /**
     * @var 开始请求
     *
     * @return HttpClient
     */
    private function exec()
    {
        $ch = curl_init();

        if ($this->header) {
            foreach ($this->header as $key => $value) {
                curl_setopt($ch, $key, $value);
            }
        }

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_URL, $this->url);

        if ($this->method == 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $this->param);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/x-www-form-urlencoded; charset=utf-8',
                'Content-Length: ' . strlen($this->param)
            ));
        } elseif ($this->method == 'GET') {
            curl_setopt($ch, CURLOPT_URL, $this->url.'?'.$this->param);
            curl_setopt($ch, CURLOPT_HEADER, false);
        }

        $info = curl_getinfo($ch);
        $data = curl_exec($ch);
        $error = curl_errno($ch);
        curl_close($ch);

        $this->response = [
            'code' => $error ? 1 : 0,
            'message' => $error,
            'info' => $info,
            'data' => $data,
        ];
        return $this;
    }

    /**
     * @var 获取响应数据
     *
     * @throw Exception
     *
     * @return array|string
     */
    public function getBody()
    {
        if (!$this->response) {
            throw new Exception('no httpRequest');
        }

        return $this->response['data'];
    }

    /**
     * @var 获取响应状态码
     *
     * @throw Exception
     *
     * @return int
     */
    public function getCode()
    {
        if (!$this->response) {
            throw new Exception('no httpRequest');
        }

        return $this->response['code'];
    }

    /**
     * @var 获取错误信息
     *
     * @throw Exception
     *
     * @return int|array
     */
    public function getMessage()
    {
        if (!$this->response) {
            throw new Exception('no httpRequest');
        }

        return $this->response['message'];
    }

    /**
     * @var 获取响应信息
     *
     * @return array
     */
    public function getInfo()
    {
        if (!$this->response) {
            throw new Exception('no httpRequest');
        }

        return $this->response['info'];
    }

    /**
     * @var GET请求
     *
     * @param string url
     * @param array param
     * @param array header
     *
     * @return HttpClient
     */
    public function get(String $url, Array $param = [], Array $header = [])
    {
        return $this->setMethod('GET')->setUrl($url)->setParam($param)->setHeader($header)->exec();
    }

    /**
     * @var POST请求
     *
     * @param string url
     * @param array param
     * @param array header
     *
     * @return HttpClient
     */
    public function post(String $url, Array $param = [], $header = [])
    {
        return $this->setMethod('POST')->setUrl($url)->setParam($param)->setHeader($header)->exec();
    }

    /**
     * @var 清理垃圾
     */
    public function __destruct()
    {
        $this->url = null;
        $this->method = null;
        $this->param = null;
        $this->header = null;
        $this->response = null;
    }
}

简单工厂模式

1.创建一个私有属性

 private $httpclient;

2.当HttpClient类被实例化时给属性赋值对象(构造方法)

public function __construct()
   {
       $this->httpclient = new HttpClient;
   }

3.使用PHP7写法定义参数类型,并规定request方法的返回值必须为一个HttpClient类实例
4.当完成调用时销毁赋值(析构方法)
工厂类:Ease.php

<?php
require 'D:\phpstudy_pro\WWW\project\HttpClient.php';
class Ease
{
    //创建一个私有属性
    private $httpclient;
    //当HttpClient类被实例化时给属性赋值对象
    public function __construct()
    {
        $this->httpclient = new HttpClient;
    }
    //使用PHP7写法定义参数类型,并规定request方法的返回值必须为一个HttpClient类实例
    public function request(string $url,Array $param = [],Bool $isPost = true) : HttpClient
    {
        //变量先定义,执行效率比未定义的要快些,这是小技巧
        $response  = null;
        if ($isPost) {
            $response = $this->httpclient->post($url, $param);
        }else{
            $response = $this->httpclient->get($url);
        }
        return $response;
    }
    //当完成调用时销毁赋值(析构函数)
    public function __destruct ()
    {
        $this->httpclient = null;
    }
}

使用

<?php
require './factory/Ease.php';

$ease = new Ease;

$res = $ease->request('https://www.baidu.com/',[],true);
echo "<pre>";
var_dump($res);
echo "</pre>";

显示结果页
在这里插入图片描述

工厂方法

创建一个抽象工厂类和多个具体工厂类,一旦需要增加新的功能,需要修改抽象工厂类和他所有子类

1.工厂方法类依赖于类的抽象,而不是具体将被创建的类,这是工厂方法模式与简单工厂模式和静态工厂模式最重要的区别

2.抽象类与接口说明参考文档:https://blog.csdn.net/luyaran/article/details/54137702

3.抽象类中只需要实现抽象方法,其它方法可以选择性的实现
工厂类:Method.php

<?php
require 'D:\phpstudy_pro\WWW\project\HttpClient.php';
//工厂方法类依赖于类的抽象,而不是具体将被创建的类,这是工厂方法模式与简单工厂模式和静态工厂模式最重要的区别
//抽象类与接口说明参考文档:https://blog.csdn.net/luyaran/article/details/54137702
//抽象类中只需要实现抽象方法,其它方法可以选择性的实现
abstract class Method
{
    //创建一个私有属性
    protected $httpclient;
    //当HttpClient类被实例化时给属性赋值对象
    public function __construct()
    {
        $this->httpclient = new HttpClient;
    }

    //当完成调用时销毁赋值(析构函数)
    public function __destruct ()
    {
        $this->httpclient = null;
    }
    //定义的抽象方法   每个方法都只有声明而没有实现
    abstract public function request(String $url, Array $param = [], Array $header = []) : HttpClient;
}

class Get extends Method
{
    public function  request(String $url, Array $param = [], Array $header = []) : HttpClient
    {
        return $this->httpclient->get($url, $param = [], $header = []);
    }
}

class Post extends Method
{
    public function  request(String $url, Array $param = [], Array $header = []) : HttpClient
    {
        return $this->httpclient->post($url, $param, $header);
    }
}

使用工厂方法

<?php
include './factory/Method.php';

$get = new Get();
$res = $get->request('https://www.baidu.com/');
echo "<pre>";
var_dump($res);
echo "</pre>";

$post = new Post();
$res02 = $post->request('https://www.baidu.com/');
echo "<pre>";
var_dump($res02);
echo "</pre>";

抽象工厂

创建一个工厂接口和多个工厂实现类,一旦需要增加新的功能,直接增加新的工厂类

1.接口中每个方法都只有声明而没有实现

2.接口需要实现,用implements

3.接口中只能声明public的方法,不能声明private和protected的方法,不能对方法进行实现,也不能声明实例变量;但是抽象类中可以
抽象工厂类

<?php
require 'D:\phpstudy_pro\WWW\project\HttpClient.php';

//接口中每个方法都只有声明而没有实现
//接口需要实现,用implements
//接口中只能声明public的方法,不能声明private和protected的方法,不能对方法进行实现,也不能声明实例变量;但是抽象类中可以
interface  AbstractFactory
{
     public function get(String $url, Array $param = [], Array $header = []) : HttpClient;
     public function post(String $url, Array $param = [], Array $header = []) : HttpClient;
}

//Requst 实现AbstractFactory接口
class Requst implements AbstractFactory
{
    protected $httpclient;

    public function __construct()
    {
        $this->httpclient = new HttpClient;
    }

    public function __destruct()
    {
        $this->httpclient = null;
    }

    public function get(String $url, Array $param = [], Array $header = []) : HttpClient
    {
        return $this->httpclient->get($url, $param, $header);
    }

    public function post(String $url, Array $param = [], Array $header = []) : HttpClient
    {
        return $this->httpclient->post($url, $param, $header);
    }
}


class MyVue extends Requst
{
    public function home()
    {
        return $this->get('https://fanyi.baidu.com/translate?aldtype=16047&query=&keyfrom=baidu&smartresult=dict&lang=auto2zh#en/zh/response')->getBody();
    }

}

class GitHub extends Requst
{
    public function apiList()
    {
        return $this->get('https://api.github.com/', [], [
            'CURLOPT_USERAGENT' => 'http://developer.github.com/v3/'
        ])->getBody();
    }
}

使用抽象工厂

<?php

include './factory/AbstractFactory.php';
$github = new GitHub;
$res = $github->apiList();
echo "<pre>";
var_dump(json_decode($res,true));
echo "</pre>";
``
查询结果页面
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200531172642971.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTIxODQ2NA==,size_16,color_FFFFFF,t_70)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值