设计模式

PHP技术
473
0
0
2022-07-10

设计模式

设计模式

单例模式

工厂模式

工厂模式,工厂方法或者类生成对象,而不是在代码中直接new。
public function test1($arr)
{
    $people = new PeopleClass();
}
public function test2($arr)
{
    $people = new PeopleClass();
}

上边如果需要修改类名需要修改两处

class PeopleClassFactory{ 
    /* * 如果某个类在很多的文件中都new ClassName(),那么万一这个类的名字 * 发生变更或者参数发生变化,如果不使用工厂模式,就需要修改每一个PHP * 代码,使用了工厂模式之后,只需要修改工厂类或者方法就可以了。 */ 
    static function createObject(){ 
        $object = new PeopleClass(); 
        return $object; 
    } 
}//这样就不需要改了 
public function test3($arr)
{
    $people = PeopleClassFactory::createObject;
}

注册模式

注册模式,解决全局共享和交换对象。已经创建好的对象,挂在到某个全局可以使用的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局的树上。任何地方直接去访问。

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]);
        //移除某个注册到树上的对象。 
    }
}

适配器模式

PHP中的数据库操作有MySQL,MySQLi,PDO三种,可以用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。
这个说白了就是基于 interface ,比如 redis 和 Memchache ,还有文件缓存, 基本功能比如 get set 等可以写在一个接口中,类去继承自 这个 interface
//使用redis 
$app  = ['cache'=>new redis()];
$app['cache']->set('aaa',100,2000);
//使用Memchache
$app  = ['cache'=>new Memchache()];
$app['cache']->set('aaa',100,2000);

策略模式

策略模式,将一组特定的行为和算法封装成类,以适应某些特定的上下文环境。

用户接口

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>"; 
    } 
    //get set 方法,实现注入 
    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();

观察者模式

1:观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。

2:场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。

3:观察者模式实现了低耦合,非侵入式的通知与更新机制。

定义一个事件触发抽象类。 EventGenerator.php

<?php
require_once 'Loader.php';
abstract class EventGenerator{
    private $observers = array(); 
    function addObserver(Observer $observer)
    { 
        $this->observers[]=$observer; 
    } 
    function notify()
    { 
        foreach ($this->observers as $observer)
        { 
            $observer->update(); 
        } 
    }
}

定义一个观察者接口, Observer.php

<?php
require_once 'Loader.php';
interface Observer{
    function update();//这里就是在事件发生后要执行的逻辑
}

实现代码

<?php
//一个实现了EventGenerator抽象类的类,用于具体定义某个发生的事件
require 'Loader.php';
//继承自抽象类
//1. 抽象类继承抽象类时,不能重写父类中的抽象方法
//2. 非抽象类继承抽象类时,必须实现抽象类中的所有方法
//3. 至少有一个抽象方法的类就是抽象类

//定义一个基于 EventGenerator 抽象类的  事件类
class Event extends EventGenerator
{
    function triger()
    { 
        echo "Event<br>"; 
    }
}
class Observer1 implements Observer
{
    function update()
    { 
        echo "逻辑1<br>"; 
    }
}
class Observer2 implements Observer
{
    function update()
    { 
        echo "逻辑2<br>"; 
    }
}
//
$event = new Event();
//把时间需要执行的逻辑注册进去
$event->addObserver(new Observer1());
//
$event->addObserver(new Observer2());
//
$event->triger();
//执行继承自接口后的逻辑
$event->notify();

原型模式

原型模式(对象克隆以避免创建对象时的消耗)

1:与工厂模式类似,都是用来创建对象。

2:与工厂模式的实现不同,原型模式是先创建好一个原型对象,然后通过clone原型对象来创建新的对象。这样就免去了类创建时重复的初始化操作。

3:原型模式适用于大对象的创建,创建一个大对象需要很大的开销,如果每次new就会消耗很大,原型模式仅需要内存拷贝即可。

Canvas.php

<?php
require_once 'Loader.php';
class Canvas{
    private $data; 
    function init($width = 20, $height = 10)
    { 
        $data = array(); 
        for($i = 0; $i < $height; $i++) 
        { 
            for($j = 0; $j < $width; $j++) { 
                $data[$i][$j] = '*'; 
            } 
        } 
        $this->data = $data; 
    } 
    function rect($x1, $y1, $x2, $y2)
    { 
        foreach($this->data as $k1 => $line) 
        { 
            if ($x1 > $k1 or $x2 < $k1) continue; 
            foreach($line as $k2 => $char) { 
                if ($y1>$k2 or $y2<$k2) continue; 
                $this->data[$k1][$k2] = '#'; 
            } 
        } 
    } 
    function draw()
    { 
        foreach ($this->data as $line)
        { 
            foreach ($line as $char)
            { 
                echo $char; 
            } 
            echo "<br>;"; 
        } 
    }
}

Index.php

<?php
require 'Loader.php';
$c = new Canvas();
$c->init();
/ $canvas1 = new Canvas();
// $canvas1->init();
$canvas1 = clone $c;//通过克隆,可以省去init()方法,这个方法循环两百次
//去产生一个数组。当项目中需要产生很多的这样的对象时,就会new很多的对象,那样
//是非常消耗性能的。
$canvas1->rect(2, 2, 8, 8);
$canvas1->draw();
echo "-----------------------------------------<br>";
// $canvas2 = new Canvas();
// $canvas2->init();
$canvas2 = clone $c;
$canvas2->rect(1, 4, 8, 8);
$canvas2->draw();

装饰器模式

1:装饰器模式,可以动态的添加修改类的功能
2:一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重写实现类的方法
3:使用装饰器模式,仅需要在运行时添加一个装饰器对象即可实现,可以实现最大额灵活性。