[{"data":1,"prerenderedAt":66},["ShallowReactive",2],{"article-28":3},{"code":4,"msg":5,"data":6,"count":14},200,"查询成功",{"id":7,"title":8,"keywords":9,"description":10,"category_id":11,"content":12,"body_html":13,"thumb_up":14,"clicks":15,"sort":14,"remark":16,"status":17,"is_open":17,"is_deleted":14,"is_top":14,"is_recommend":14,"create_time":18,"update_time":19,"image_id":20,"url":13,"member_id":14,"cate_name":21,"prev":22,"next":25,"tags":28,"words":37,"read_time":38,"comments":14,"cover":39,"relevant":40},28,"PHP设计模式之观察者、原型以及装饰模式","php,设计模式,观察者,原型,装饰","本文章讲述php设计模式中的观察者、原型以及装饰模式以及实例代码",2,"一、观察者模式\n\n1. 观察者模式（ Observer ），当一个对象状态发生改变时，依赖它的对象全部会收到通知，并自动更新。\n2. 场景：一个事件发生后，要执行一连串更新操作。传统的编程方式，就是在事件的代码之后直接加入处理逻辑。当更新的逻辑增多后，代码会变得难以维护。\n\n这种方式是耦合的，入侵式的，增加新的逻辑需要修改事件主体的代码。\n\n3. 观察者模式实现了低耦合，非入侵式的通知与更新机制。\n\n实例代码：\n```php\nabstract class EventGenerator{\n    private $observers = array();\n    public function addObsserver($observer){\n    $this->observers[] = $observer;\n    }\n    public function notify(){\n    foreach ($this->observers as $key => $observer) {\n       $observer->update();\n    }\n    }\n}\ninterface Observer{\n    public function update($event_info = null);\n}\nclass Event extends EventGenerator{\n    public function trigger(){\n    echo \"事件发生\";\n    \u002F\u002Fupdate code\n    $this->notify();\n    }\n}\nclass ObserverOne implements Observer{\n    public function update($event_info = null){\n    echo \"逻辑1\";\n    }\n}\nclass ObserverTwo implements Observer{\n    public function update($event_info = null){\n    echo \"逻辑2\";\n    }\n}\n$event = new Event();\n$event->addObsserver(new ObserverOne);\n$event->addObsserver(new ObserverTwo);\n$event->trigger();\n```\n二、原型模式\n\n1. 与工厂模式作用类似，都是用来创建对象。\n\n2. 与工厂模式的实现不懂，原型模式是首先创建好一个原型对象，然后通过clone原型对象来创建新的对象。这样就免去了类创建是重复的初始化操作。\n\n3. 原型模式适用于大对象的创建。创建一个大对象需要很大的开销，如果每次new就会消耗很大，原型模式仅需内存拷贝即可。\n\n实例代码：\n```php\nclass Canvas{\n    public $data;\n    protected $decorators = array();\n    public function init($width = 20, $height = 10){\n        $data = array();\n        for($i = 0; $i \u003C $height; $i++){\n            for($j = 0; $j \u003C $width; $j++){\n                $data[$i][$j] = '*';\n            }\n        }\n        $this->data = $data;\n    }\n    public function draw(){\n        foreach($this->data as $line){\n            foreach($line as $char) {\n                echo $char;\n            }\n            echo \"\\n\";\n        }\n    }\n    public function rect($a1, $a2, $b1, $b2){\n        foreach($this->data as $k1 => $line){\n            if ($k1 \u003C $a1 or $k1 > $a2) \n                continue;\n            foreach($line as $k2 => $char){\n                if ($k2 \u003C $b1 or $k2 > $b2) \n                    continue;\n                $this->data[$k1][$k2] = ' ';\n            }\n        }\n    }\n}\n\u002F**\n * 创建原型对象\n * [$prototype description]\n * @var Canvas\n *\u002F\n$prototype = new Canvas();\n$prototype->init();\n\n$canvas = clone $prototype;\u002F\u002F克隆原型对象\n$canvas->rect(3, 6, 4, 12);\n$canvas->draw();\necho \"--------------\";\n$canvas1 = clone $prototype;\n$canvas1->rect(3, 3, 3, 3);\n$canvas1->draw();\n```\n三、装饰模式\n\n1.装饰模式,可以动态的添加修改类的功能。\n\n2.一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个之类集成它,并重新实现类的方法。\n\n3.使用装饰模式,仅需在运行时添加一个装饰对象即可实现,可以实现最大的灵活性。\n\n实例代码：\n\n```php\nclass Canvas{\n    public $data;\n    protected $decorators = array();\n    public function init($width = 20, $height = 10){\n        $data = array();\n        for($i = 0; $i \u003C $height; $i++){\n            for($j = 0; $j \u003C $width; $j++){\n                $data[$i][$j] = '*';\n            }\n        }\n        $this->data = $data;\n    }\n    public function addDecorator($decorator){\n        $this->decorators[] = $decorator;\n    }\n    public function beforeDraw(){\n        foreach($this->decorators as $decorator){\n            $decorator->beforeDraw();\n        }\n    }\n    public function afterDraw(){\n        $decorators = array_reverse($this->decorators);\n        foreach($decorators as $decorator){\n            $decorator->afterDraw();\n        }\n    }\n    public function draw(){\n        $this->beforeDraw();\n        foreach($this->data as $line){\n            foreach($line as $char) {\n                echo $char;\n            }\n            echo \"\\n\";\n        }\n        $this->afterDraw();\n    }\n    public function rect($a1, $a2, $b1, $b2){\n        foreach($this->data as $k1 => $line){\n            if ($k1 \u003C $a1 or $k1 > $a2) \n                continue;\n            foreach($line as $k2 => $char){\n                if ($k2 \u003C $b1 or $k2 > $b2) \n                    continue;\n                $this->data[$k1][$k2] = ' ';\n            }\n        }\n    }\n}\ninterface DrawDecorator{\n    public function beforeDraw();\n    public function afterDraw();\n}\nclass ColorDrawDecotator implements DrawDecorator{\n    protected $color;\n    public function __construct($color = 'red'){\n    $this->color = $color;\n    }\n    public function beforeDraw(){\n    echo \"+++++++++++\";\n    }\n    public function afterDraw(){\n    echo \"-----------\";\n    }\n}\nclass SizeDrawDecotator implements DrawDecorator{\n    protected $size;\n    public function __construct($size = '12px'){\n    $this->size = $size;\n    }\n    public function beforeDraw(){\n    echo \"before draw\";\n    }\n    public function afterDraw(){\n    echo \"after draw\";\n    }\n}\n$canvas = new Canvas();\n$canvas->init();\n$canvas->addDecorator(new ColorDrawDecotator('green'));\n$canvas->addDecorator(new SizeDrawDecotator('24px'));\n$canvas->rect(3, 6, 4, 12);\n$canvas->draw();\n```\n \n",null,0,485,"",1,"2019-01-17 23:02:29","2026-04-19 15:14:56",125,"PHP",{"id":23,"title":24},27,"PHP设计模式之适配、策略以及数据对象映射模式",{"id":26,"title":27},29,"PHP设计模式之迭代器、代理模式",[29,31,34],{"id":30,"name":21},25,{"id":32,"name":33},47,"设计模式",{"id":35,"name":36},48,"后端",2583,6,"https:\u002F\u002Ftp.myong.top\u002Fstorage\u002Farticle\u002Fde\u002Fe160ee009b815eba64cecaaccf60f8.jpg",[41,46,51,56,61],{"id":42,"title":43,"create_time":44,"description":45},93,"PHP执行Python脚本解压，压缩文件夹操作","2020-08-06 14:59:05","PHP是有解压缩类文件的，但在实际项目中，用户方使用Python脚本压缩，很容易出现中文解压乱码，导致文件内容丢失的情况，本文主要介绍PHP执行Python脚本解压缩出现的问题以及解决方法",{"id":47,"title":48,"create_time":49,"description":50},92,"PHP对图片的处理","2020-07-30 15:53:38","图片处理函数功能：缩放、剪切、相框、水印、锐化、旋转、翻转、透明度、反色处理并保存历史记录的思路：当有图片有改动时自动生成一张新图片",{"id":52,"title":53,"create_time":54,"description":55},96,"PHP中字符串跟0做比较永远是true","2021-02-04 16:16:27","最近在项目中做数据对比的功能，发现一个特殊的情况，0跟任何字符串做比较永远返回true，特意了解了一下。",{"id":57,"title":58,"create_time":59,"description":60},13,"Win系统下配置PHP链接Oracle","2019-01-17 22:23:36","该文章内容主要介绍window系统下，php连接oracle的配置。",{"id":62,"title":63,"create_time":64,"description":65},103,"面向对象三大特性五大原则 + 低耦合高内聚[转载]","2021-10-31 23:18:58","面向对象的三大特性是\"封装、\"多态\"、\"继承\"，五大原则是\"单一职责原则\"、\"开放封闭原则\"、\"里氏替换原则\"、\"依赖倒置原则\"、\"接口分离原则\"。",1783431669203]