php设计模式

php常用设计模式之观察者模式.

 观察者模式:

        当一个对象的状态发生改变时候,与之相关的对象会全部收到通知,并自动更新.

  场景:

            一个事件发生后,要知行一系列的更新操作,传统的方式是直接在事件之后加入逻辑代码,当逻辑更新增多一行 维护变得很难,这种方式是高耦合,侵入式的,增加新的逻辑需要修改主题代码.

  观察者模式优点 实现了低耦合,非侵入式的通知与更新机制.

class Ob1 implements \PublicDir\Observer
{
   function update($a=null)
   {
       echo time().'goods';
   }
}

$event = new \PublicDir\Event;
$event->addObserver(new Ob1);
$event->trigger();

namespace PublicDir;

class Event extends \PublicDir\EventGenerator
   {
       function trigger()
       {
           echo 'update';
           $this->notify();
       }
   }
   
   namespace PublicDir;

abstract class EventGenerator
{
   protected $observers = [];
   function addObserver(observer$observer)
   {
       $this->observers[] = $observer;
   }
   function notify()
   {
       foreach($this->observers as $observer)
       {
           $observer->update();
       }
   }
}

namespace PublicDir;

interface Observer
{
   function update($info=null);
}


原型模式 当需要多次创建一个比较大的对象时 为避免重复初始化浪费太多内存 而使用克隆对象

$protype = new \PublicDir\Canvas;
$protype->init();
$canvas1 = clone $protype;
$canvas1->rect(4,6,4,12);
$canvas1->draw();
echo "<=====================><br/>";
$canvas2 = clone $protype;
//$canvas2 ->rect(4,6,4,10);
$canvas2->draw();

namespace PublicDir;


class Canvas
{
    public $data;
    protected $decorators = [];

    function init($width=20,$height=10)
    {
        $data = [];
        for($i=0;$i<$height;$i++)
        {
            for($j=0;$j<$width;$j++)
            {
             $data[$i][$j] = '*';
            }
        }
        $this->data = $data;
    }

    function addDecorator(DrawDecorator $obj)
    {
        $this->decorators[] = $obj;
    }

    function beforeDraw()
    {
        foreach($this->decorators as $obj)
        {
            $obj->interfaceBeforeDraw();
        }
    }

    function afterDraw()
    {
        $obj = array_reverse($this->decorators);
        foreach($obj as $v)
        {
            $v->interfaceAfterDraw();
        }
    }

    function draw()
    {
        $this->beforeDraw();
        foreach($this->data as $line)
        {
            foreach($line as $char)
            {
                echo $char;
            }
            echo "<br/>";
        }

        $this->afterDraw();

    }

    function rect($a1,$a2,$b1,$b2)
    {
        foreach($this->data as $k1=>$line)
        {
            if($k1 < $a1 or $k1 > $a2 ) continue;
            foreach($line as $k2 => $char)
            {
                if($k2 < $b1 or $k2 > $b2) continue;
                $this->data[$k1][$k2] = "&nbsp;";
            }
        }
    }
}

装饰器模式
$canvas1 = new \PublicDir\Canvas;
$canvas1->init();
$canvas1->addDecorator(new \PublicDir\ColorDrawDecorator('orange'));
$canvas1->addDecorator(new \PublicDir\SizeDrawDecorator('40px'));
$canvas1->rect(4,6,4,10);
$canvas1->draw()

namespace PublicDir;


class ColorDrawDecorator implements DrawDecorator
{
    protected $color;
    function __construct($color)
    {
        $this->color = $color;
    }
    function interfaceBeforeDraw($color="red")
    {
        echo "<div style='color: {$this->color};'>";
    }
    function interfaceAfterDraw()
    {
        echo '</div>';
    }
}

namespace PublicDir;

class SizeDrawDecorator implements \PublicDir\DrawDecorator
{
    protected $size;
    function __construct($size="14px")
    {
        $this->size = $size;
    }
    function interfaceBeforeDraw()
    {
        echo "<div style='font-size: {$this->size};'>";
    }

    function interfaceAfterDraw()
    {
        echo "</div>";
    }
}

 



这里可以获得部分代码 https://github.com/kok888/smallFrame

感谢阅读,如果要表示感谢,扫码请我喝杯咖啡把!

              

nickname
content