前言
策略模式相對比較簡單, 但是也是使用最頻繁的一個用法, 是對一類事物的抽象. 簡單整理一下, 共勉.
解決的問題
很多人在寫代碼的時候經常遇到很多 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類.