
一、观察者模式
- 观察者模式( Observer ),当一个对象状态发生改变时,依赖它的对象全部会收到通知,并自动更新。
- 场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理逻辑。当更新的逻辑增多后,代码会变得难以维护。
这种方式是耦合的,入侵式的,增加新的逻辑需要修改事件主体的代码。
- 观察者模式实现了低耦合,非入侵式的通知与更新机制。
实例代码:
abstract class EventGenerator{
private $observers = array();
public function addObsserver($observer){
$this->observers[] = $observer;
}
public function notify(){
foreach ($this->observers as $key => $observer) {
$observer->update();
}
}
}
interface Observer{
public function update($event_info = null);
}
class Event extends EventGenerator{
public function trigger(){
echo "事件发生";
//update code
$this->notify();
}
}
class ObserverOne implements Observer{
public function update($event_info = null){
echo "逻辑1";
}
}
class ObserverTwo implements Observer{
public function update($event_info = null){
echo "逻辑2";
}
}
$event = new Event();
$event->addObsserver(new ObserverOne);
$event->addObsserver(new ObserverTwo);
$event->trigger();二、原型模式
与工厂模式作用类似,都是用来创建对象。
与工厂模式的实现不懂,原型模式是首先创建好一个原型对象,然后通过clone原型对象来创建新的对象。这样就免去了类创建是重复的初始化操作。
原型模式适用于大对象的创建。创建一个大对象需要很大的开销,如果每次new就会消耗很大,原型模式仅需内存拷贝即可。
实例代码:
class Canvas{
public $data;
protected $decorators = array();
public 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;
}
public function draw(){
foreach($this->data as $line){
foreach($line as $char) {
echo $char;
}
echo "\n";
}
}
public 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] = ' ';
}
}
}
}
/**
* 创建原型对象
* [$prototype description]
* @var Canvas
*/
$prototype = new Canvas();
$prototype->init();
$canvas = clone $prototype;//克隆原型对象
$canvas->rect(3, 6, 4, 12);
$canvas->draw();
echo "--------------";
$canvas1 = clone $prototype;
$canvas1->rect(3, 3, 3, 3);
$canvas1->draw();三、装饰模式
1.装饰模式,可以动态的添加修改类的功能。
2.一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个之类集成它,并重新实现类的方法。
3.使用装饰模式,仅需在运行时添加一个装饰对象即可实现,可以实现最大的灵活性。
实例代码:
class Canvas{
public $data;
protected $decorators = array();
public 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;
}
public function addDecorator($decorator){
$this->decorators[] = $decorator;
}
public function beforeDraw(){
foreach($this->decorators as $decorator){
$decorator->beforeDraw();
}
}
public function afterDraw(){
$decorators = array_reverse($this->decorators);
foreach($decorators as $decorator){
$decorator->afterDraw();
}
}
public function draw(){
$this->beforeDraw();
foreach($this->data as $line){
foreach($line as $char) {
echo $char;
}
echo "\n";
}
$this->afterDraw();
}
public 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] = ' ';
}
}
}
}
interface DrawDecorator{
public function beforeDraw();
public function afterDraw();
}
class ColorDrawDecotator implements DrawDecorator{
protected $color;
public function __construct($color = 'red'){
$this->color = $color;
}
public function beforeDraw(){
echo "+++++++++++";
}
public function afterDraw(){
echo "-----------";
}
}
class SizeDrawDecotator implements DrawDecorator{
protected $size;
public function __construct($size = '12px'){
$this->size = $size;
}
public function beforeDraw(){
echo "before draw";
}
public function afterDraw(){
echo "after draw";
}
}
$canvas = new Canvas();
$canvas->init();
$canvas->addDecorator(new ColorDrawDecotator('green'));
$canvas->addDecorator(new SizeDrawDecotator('24px'));
$canvas->rect(3, 6, 4, 12);
$canvas->draw();评论
暂无评论
评论(0)