前言
策略模式相对比较简单, 但是也是使用最频繁的一个用法, 是对一类事物的抽象. 简单整理一下, 共勉.
解决的问题
很多人在写代码的时候经常遇到很多 if ... else if ... else ... 的问题, 依据开闭原则的体现, 这些条件分支的代码, 如果是经常容易变更的,或者增加删减比较频繁的, 那么我们应该把对代码的修改转换为对扩展的修改.
代码示例
现在我们用 最常见的多数据库的db类举例.
// 耦合的写法
if ($dbClass === 'mysqlDb') {
$db = new MysqlDb();
$db->doConnect();
// todo
$db->close();
}
else if ($dbClass === 'sqlite') {
$db = new SqliteDb();
$db->doConnect();
// todo
$db->close();
}
else {
$db = new OricleDb();
$db->doConnect();
// todo
$db->close();
}
// 策略类的写法
interface Db {
public function doConnect(): Db;
public function close(): void;
}
class Mysql implements Db {
public function doConnect(): self {
// todo
return $this;
}
public function close(): void {
}
}
class Sqlite implements Db {
public function doConnect(): self {
// todo
return $this;
}
public function close(): void {
}
}
// 使用的时候
if ($dbClass === 'mysqlDb') {
$db = new Mysql();
$db->doConnect();
// todo
$db->close();
}
else if ($dbClass === 'sqlite') {
$db = new Sqlite();
$db->doConnect();
// todo
$db->close();
}
else {
// todo
}
如上的代码成功的将修改转移到各自的扩展里, 而不需要在本身的类中掺杂过多的业务类, 依据最少知道原则, 封装各自的类.
使用时机参考
如果某些类具有一些共通的特性, 或者属于一种性质的类, 尽量使用其抽象, 特别在有分支的时候需要考虑 比如 if else 或者 switch类.