策略模式
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化,即封装变化的算法。
本质是将算法封装起来
下面看一个常见的代码
<?php
/**
* @param string $driver
* @param string $msg
* @datetime 2020/7/17 5:42 PM
* @author roach
* @email [email protected]
*/
function log($driver, $msg) {
switch ($driver) {
case 'db':
/**
* @var \PDO $db
*/
$stmt = $db->prepare('INSERT INTO `roach`(`msg`)VALUES(?)');
$stmt->execute([ $msg ]);
case 'redis':
/**
* @var \Redis $redis
*/
$redis->lPush('roach:log', $msg);
default:
file_put_contents('/tmp/roach.log', $msg, FILE_APPEND| LOCK_EX);
}
}
以上我们实现了记录日志的简单基本功能,调用端提供driver
和msg
参数即可,调用api
很简单,log
方法里的实现也就用了一个switch
,这里有什么问题呢?
上述代码看着很简单,没什么大问题,但是我们考虑一下,是否对修改关闭了?当我们需要修改某一个driver
记录日志的细节时,都需要修改log
方法,可见没有对修改关闭;再看一下,如果我们需要增加kafka
驱动,还是需要修改log
方法,可见也不是对扩展开放,那么怎么修改呢?
这里就用到了策略模式,下面是应用策略模式实现例程
<?php
/**
* @param string $driver
* @param string $msg
* @datetime 2020/7/17 5:42 PM
* @author roach
* @email [email protected]
*/
function log($driver, $msg) {
switch ($driver) {
case 'db':
/**
* @var \PDO $db
*/
$stmt = $db->prepare('INSERT INTO `roach`(`msg`)VALUES(?)');
$stmt->execute([ $msg ]);
case 'redis':
/**
* @var \Redis $redis
*/
$redis->lPush('roach:log', $msg);
default:
file_put_contents('/tmp/roach.log', $msg, FILE_APPEND| LOCK_EX);
}
}