PHP设计模式 五 (观察者 策略 装饰器模式)

观察者模式

观察者模式(有时又被称为发布-订阅Subscribe>模式、模型-视图View>模式、源-收听者Listener>模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
当一个对象的状态发生改变时,依赖他的对象全部会接到通知,并自动更新。观察者模式实现了低耦合 非入侵式的通知与更新机制。

观察者模式示例:
首先创建一个事件生成器 EventGenerator.php

<?php

namespace Components\ObServer;

abstract class EventGenerator {
	
	private $obServers = array();
	function addObServer(IObServer $obServer) {//添加事件
		$this->obServers[] = $obServer;
	}
	
	function notify() {
		foreach ($this->obServers as $obServer) {//一一执行更新
			$obServer->update();
		}
	}
}

创建一个观察者接口IObServer.php
<?php

namespace Components\ObServer;

interface IObServer {
	function update($event_info = NULL);
}

事件主体:
class Event extends \Components\ObServer\EventGenerator{
	function tringger() {
		echo "<br>Event<br/>";
		$this->notify();
	}
}

观察者:
//观察者1
class ObServer1 implements \Components\ObServer\IObServer {
	function update($event_info = null) {
		echo "logic1<br>";
	}
}

//观察者2
class ObServer2 implements \Components\ObServer\IObServer {
	function update($event_info = null) {
		echo "logic2<br>";
	}
}

触发:
$event = new Event();
$event->addObServer(new ObServer1());
$event->addObServer(new ObServer2());
$event->tringger();




策略模式

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

应用场景:
1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

组成
1、抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
2、具体策略角色:包装了相关的算法和行为。
3、环境角色:持有一个策略类的引用,最终给客户端调用。

分类广告策略示例:
抽象策略角色
vim Istrategy.php

<?php

namespace Components\Strategy;

/**
 * 策略模式 接口
 * @author YUNDUAN
 *
 */
interface IStrategy{
	
	function showAd();
	
	function showCategory();
	
}

具体策略角色
vim FemaleUser.php
<?php

namespace Components\Strategy;

class FemaleUser implements IStrategy {
	
	function showAd() {
		echo '女性广告<br>';
	}
	
	function showCategory() {
		echo '女装<br>';
	}
}

vim MaleUser.php
<?php

namespace Components\Strategy;

class MaleUser implements IStrategy {
	
	function showAd() {
		echo '男性广告<br>';
	}
	
	function showCategory() {
		echo '电子产品<br>';
	}
}

环境角色:
vim Home.php
/**
 * 策略模式 解耦和
 * @author YUNDUAN
 *
 */
class Home {
	protected $strategy;
	function index() {
		echo "AD:";
		$this->strategy->showAd();
		
		echo "Category:";
		$this->strategy->showCategory();
	}
	
	function setStrategy(Components\Strategy\IStrategy $strategy) {
                //依赖注入   注入一个对象
		$this->strategy = $strategy;
	}
	
}

使用:
$home = new Home();

if (isset($_GET['female'])) {
	$strategy = new \Components\Strategy\FemaleUser();
}else {
	$strategy = new \Components\Strategy\MaleUser();
}
/*策略模式*/
$home->setStrategy($strategy);
$home->index();



装饰器模式

在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

装饰器接口IDecorator.php:

<?php

namespace Components\Decorator;

/**
 * 装饰器模式  接口
 * @author WH
 *
 */
interface IDecorator {
	
	function before();
	
	function after();
	
}


装饰器1 DecoratorAttr1.php:
<?php

namespace Components\Decorator;

class DecoratorAttr1 implements IDecorator{
	
	function before() {
		echo '<br><div style="color:red">';
	}
	
	function after() {
		echo '</div>';
	}
	
}


装饰器2  DecoratorAttr2.php:
<?php

namespace Components\Decorator;

class DecoratorAttr2 implements IDecorator{
	
	function before() {
		echo '<br><div style="font-size:30px">';
	}
	
	function after() {
		echo '</div>';
	}
	
}

使用:
/* 装饰器模式 原类 */
class DecoratorClassTest {
	protected $decorators = array();
	
	//添加装饰器
	function addDecorator(\Components\Decorator\IDecorator $decorator) {
		$this->decorators[] = $decorator;//添加装饰器
	}
	
	function before(){
		foreach ($this->decorators as $decorator) {
			$decorator->before();//调用装饰器
		}
	}
	
	function after(){
		//这里可用栈
		$decorators = array_reverse($this->decorators);
		foreach ($decorators as $decorator) {
			$decorator->after();//结束装饰器
		}
	}
	
	function test() {
		$this->before();
		echo 'running<be>';
		$this->after();
		
	}
}

$decoratorTest = new DecoratorClassTest();
$decoratorTest->addDecorator(new \Components\Decorator\DecoratorAttr1());
$decoratorTest->addDecorator(new \Components\Decorator\DecoratorAttr2());
$decoratorTest->test();



策略模式

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

应用场景:
1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

组成
1、抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
2、具体策略角色:包装了相关的算法和行为。
3、环境角色:持有一个策略类的引用,最终给客户端调用。

分类广告策略示例:
抽象策略角色
vim Istrategy.php

<?php

namespace Components\Strategy;

/**
 * 策略模式 接口
 * @author YUNDUAN
 *
 */
interface IStrategy{
	
	function showAd();
	
	function showCategory();
	
}

具体策略角色
vim FemaleUser.php
<?php

namespace Components\Strategy;

class FemaleUser implements IStrategy {
	
	function showAd() {
		echo '女性广告<br>';
	}
	
	function showCategory() {
		echo '女装<br>';
	}
}

vim MaleUser.php
<?php

namespace Components\Strategy;

class MaleUser implements IStrategy {
	
	function showAd() {
		echo '男性广告<br>';
	}
	
	function showCategory() {
		echo '电子产品<br>';
	}
}

环境角色:
vim Home.php
/**
 * 策略模式 解耦和
 * @author YUNDUAN
 *
 */
class Home {
	protected $strategy;
	function index() {
		echo "AD:";
		$this->strategy->showAd();
		
		echo "Category:";
		$this->strategy->showCategory();
	}
	
	function setStrategy(Components\Strategy\IStrategy $strategy) {
                //依赖注入   注入一个对象
		$this->strategy = $strategy;
	}
	
}

使用:
$home = new Home();

if (isset($_GET['female'])) {
	$strategy = new \Components\Strategy\FemaleUser();
}else {
	$strategy = new \Components\Strategy\MaleUser();
}
/*策略模式*/
$home->setStrategy($strategy);
$home->index();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值