单例模式
构造函数和析构函数必须声明为私有,防止外部程序new 类从而失去单例模式的意义
getInstance()方法必须设置为公有的,必须调用此方法 以返回实例的一个引用
::操作符只能访问静态变量和静态函数
new对象都会消耗内存
使用场景:最常用的地方是数据库连接。
使用单例模式生成一个对象后, 该对象可以被其它众多对象所使用。
私有的__clone()方法防止克隆对象
单例模式,使某个类的对象仅允许创建一个。构造函数private修饰,
申明一个static getInstance方法,在该方法里创建该对象的实例。如果该实例已经存在,则不创建。比如只需要创建一个数据库连接。
<?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/102420902 及 https://www.cnblogs.com/yuanwanli/p/8796402.html
评论 (0)