設計模式之裝飾器模式–各種功能隨意擴展
裝飾器模式
是靈活給原有類裝飾新功能。
動態的給對象添加額外職責,就增加功能來說,裝飾模式比生成子類更爲靈活。
爲什麼要使用裝飾器模式
如果你需要添加一些額外的功能,再不修改原有類的基礎上,給原有類套個殼。並且可以套多個殼,我覺得裝飾器模式有點像中間件。
比如你現在有一個登錄的功能。
你現在需要給登錄加一個權限控制。然後還要增加一個登錄日誌。還要增加登錄微信通知。如果修改原有類可能引起未知bug。
可以使用裝飾器模式。
/**
* 裝飾器模式
* 裝飾器父類
*/
class Decorate {
function __construct($compent) {
$this->compent = $compent;
}
function login() {
$this->compent->login();
}
}
/**
* 裝飾器模式
* 權限裝飾器
*/
class LoginAuth extends Decorate {
function login() {
dump('判斷登錄權限');
parent::login();
}
}
/**
* 裝飾器模式
* 登錄日誌裝飾器
*/
class LoginLog extends Decorate {
function login() {
parent::login();
dump('記錄登錄日誌');
}
}
/**
* 裝飾器模式
* 微信通知裝飾器
*/
class LoginWechat extends Decorate {
function login() {
parent::login();
dump('發送微信登錄通知');
}
}
下面是原來的登錄功能
/**
* 裝飾器模式
* 核心代碼
* 登錄功能
*/
class login {
function login() {
dump('用戶登錄');
}
}
原來的客戶端直接調用login,只有登錄功能。
$login = new login();
$login->login();
增加了裝飾器以後可以把登錄功能放入裝飾器。
$login = new login;
//使用權限裝飾器
$login = new LoginAuth($login);
//使用登錄日誌裝飾器
$login = new LoginLog($login);
//使用微信通知裝飾器
$login = new LoginWechat($login);
$login->login();
還可以任意調換裝飾器的位置,可以先發送微信通知在記錄登錄日誌。
$login = new login;
//使用微信通知裝飾器
$login = new LoginWechat($login);
//使用登錄日誌裝飾器
$login = new LoginLog($login);
//使用權限裝飾器
$login = new LoginAuth($login);
$login->login();
這個模式就非常靈活,可以任意組裝自己的裝飾,比如購買支付的時候,需要裝飾積分發放,賬單通知這些。而且每個裝飾器的職責單一,方便插拔,如果不需要一個裝飾器的時候把這個裝飾器去掉就可以了。
代碼放在了我的github上面。