JM8.6(H.264編碼器)原始碼註釋——位元速率控制部分主要推導
使用場景
假設專案經理讓我們寫了一個登陸介面,咔咔擦擦寫完了
-
第二天讓我們加入統計登陸次數,然後在後面加程式碼
-
第三天讓我們判斷登陸地區,又在後面加程式碼
-
第四天讓我們在使用者登陸後推送活動,再再後面加程式碼
-
第N天,這個介面已經雜亂到沒人想維護了
我們需要讓專案保持高內聚低耦合,就可以用到觀察者模式(也不是非要,看需求)
概念
觀察者,觀察者,首先要有個被人觀察的角色,這是唯一的,然後會有無數個觀察者去看她,可以說是一群人在圍觀一個人,既然有無數個觀眾,那總得有個東西記錄有哪些觀察者,那就應該有一個類似於陣列一樣來儲存所有觀察者,總結就是一個被觀察者,無數個觀察者,再有一個容器記錄
★我的php高階學習交流社群「點選」管理準備好的社群專屬資料:BAT等一線大廠進階知識體系(相關學習資料以及筆面試題)以及不限於:分散式架構、高可擴充套件、高效能、高併發、伺服器效能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell指令碼、Docker、微服務、Nginx等多個知識點高階進階乾貨
程式碼示例
- 介面示例
// 主題介面 interface Subject{ public function register(Observer $observer); public function notify(); } // 觀察者介面 interface Observer{ public function watch(); }
Subject就是被觀察者,Observer就是觀眾,也就是觀察者
被觀察者
// 被觀察者 class Action implements Subject{ public $_observers=array(); public function register(Observer $observer){ $this->_observers[]=$observer; } public function notify(){ foreach ($this->_observers as $observer) { $observer->watch(); } } }
Action實現了被觀察者介面,他現在就是被觀察者,再定義一個$_observers陣列,他就是記錄觀眾的容器了。
首先實現register方法,用它傳入一個觀察者,然後塞到數組裡,再實現notify()方法,它會遍歷容器陣列,執行每個觀察者的watch()方法。
觀察者
// 觀察者
class Cat implements Observer{
public function watch(){
echo "Cat watches TV<hr/>";
}
}
class Dog implements Observer{
public function watch(){
echo "Dog watches TV<hr/>";
}
}
class People implements Observer{
public function watch(){
echo "People watches TV<hr/>";
}
}
這裡定義了三個觀察者,全都實現了Observer介面,前面的Subject會迴圈呼叫每個觀察者的watch()方法,所以我們需要實現每個觀察者的watch()方法。
呼叫
// 應用例項
$action=new Action();
$action->register(new Cat());
$action->register(new People());
$action->register(new Dog());
$action->notify();
首先new被觀察者物件,執行它的register()方法,把每個觀察者都放入容器陣列,最後執行notify()方法,通知所有觀察者執行自己的方法。
PHP原生自帶的觀察者模式
PHP有自帶的觀察者模式
-
splsubject介面 - 被觀察者
-
Observer介面 - 觀察者
-
SplObjectStorage物件 - 容器
首先我們有一個使用者登入類
class user{
public function login()
{
echo '登入完畢'
}
讓他實現splsubject介面成為被觀察者。
-
首先在建構函式裡,讓他new SplObjectStorag()物件並賦值到屬性上方便後面呼叫
-
實現attach()方法,用來註冊觀察者
-
實現detach()方法,用來刪除觀察者
-
實現notify()方法,用來遍歷容器,呼叫每個觀察者的update方法(必須是update)
-
rewind方法是容器指標重置到最開始,valid方法檢測容器是否遍歷完成並返回布林,current方法是獲取當前的觀察者,next方法是將指標後移一位
-
修改login()方法,在裡面呼叫notify()來通知觀察者事件完成了
class user implements splsubject{
protected $observer = null;
public function __construct()
{
$this->observer = new SplObjectStorage();
}
public function login()
{
$this->notify();
echo '登入完畢';
}
public function attach(SplObserver $observer)
{
$this->observer->attach($observer);
}
public function detach(SplObserver $observer)
{
$this->observer->detach($observer);
}
public function notify()
{
$this->observer->rewind();
while ($this->observer->valid())
{
$observer = $this->observer->current();
$observer->update($this);
$this->observer->next();
}
}
}
觀察者
每個觀察者實現SplObserver介面,並實現update()方法
class cat implements SplObserver {
public function update(SplSubject $subject)
{
echo '小貓叫一下';
}
}
class dog implements SplObserver {
public function update(SplSubject $subject)
{
echo '小狗吼一聲';
}
}
應用
// 實時觀察
$user = new user();
$user->attach(new cat());
$user->attach(new dog());
$user->login();
PHP 網際網路架構師 50K 成長指南+行業問題解決總綱(持續更新)
面試10家公司,收穫9個offer,2020年PHP 面試問題
★如果喜歡我的文章,想與更多資深開發者一起交流學習的話,獲取更多大廠面試相關技術諮詢和指導,歡迎加入我們的群-點選此處。
本文由部落格群發一文多發等運營工具平臺 OpenWrite 釋出