最近在對業(yè)務(wù)代碼進行重構(gòu)壶唤,遇到了一些比較典型的“散發(fā)著難聞味道”的代碼泌参,可以用又臭又長來形容喉镰。
這部分的業(yè)務(wù)是發(fā)布動態(tài)栖疑,包括以下步驟:
- 敏感詞過濾
- 話題提取
- 動態(tài)數(shù)據(jù)入庫
- 敏感詞記錄
- 話題及話題動態(tài)關(guān)聯(lián)關(guān)系入庫
之所以說重構(gòu)前的代碼“又臭又長”,首先最直觀的一點汞斧,方法的行數(shù)超過了200行夜郁,其次上面四個步驟的邏輯全都寫在了一起,沒有按功能模塊拆分粘勒,這也是方法過長的原因竞端。
如果按功能劃分,發(fā)布動態(tài)包含三個模塊:
- 敏感詞模塊
- 動態(tài)模塊
- 話題模塊
其中的敏感詞模塊和話題模塊都是為動態(tài)模塊服務(wù)的庙睡。一個動態(tài)可以有敏感詞事富,也可以沒有敏感詞技俐,比如用戶分享一個鏈接,這就不需要做敏感詞過濾與記錄了统台,所以敏感詞模塊與動態(tài)模塊應(yīng)該是“松耦合”的雕擂。同樣,一個動態(tài)可以包含話題饺谬,也可能不包含捂刺,所以話題模塊與動態(tài)模塊也應(yīng)該是松耦合的。
既然敏感詞模塊與話題模塊都是為動態(tài)模塊服務(wù)的募寨,動態(tài)模塊就有必要與這兩個服務(wù)模塊建立一個服務(wù)約定:
- 我需要什么樣的服務(wù)
- 我們之間如何建立耦合關(guān)系
我需要什么樣的服務(wù)
在編程的世界里族展,約定可以抽象成接口
interface PublishContract
{
// Call this method before publishing
public function beforePublish();
// Call this method after publishing
public function afterPublish();
}
對于敏感詞模塊和話題模塊,只需要實現(xiàn)該接口拔鹰,動態(tài)模塊就可以根據(jù)約定調(diào)用它們提供的服務(wù)仪缸。
class SensitiveWords implements PublishContract
{
public function beforePublish()
{
//
}
public function afterPublish()
{
//
}
}
class TopicObserver implements PublishContract
{
public function beforePublish()
{
//
}
public function afterPublish()
{
//
}
}
這樣動態(tài)模塊就知道,在動態(tài)入庫前調(diào)用服務(wù)模塊的beforePublish服務(wù)列肢,入庫后調(diào)用服務(wù)模塊的afterPublish服務(wù)恰画。
我們?nèi)绾谓Ⅰ詈?/h2>
耦合關(guān)系的建立應(yīng)該由動態(tài)發(fā)布的調(diào)用方?jīng)Q定,動態(tài)模塊需提供相應(yīng)的接口瓷马,
class Feeds
{
// PublishContract[]
protected $serviceModules = [];
public function addServiceModule(PublishContract $service)
{
$this->serviceModules[get_class($service)] = $service;
}
public function removeServiceModule($serviceClassName)
{
unset($this->serviceModules[$serviceClassName]);
}
public function publish()
{
foreach ($this->serviceModules as $service) {
$service->beforePublish();
}
// do something about publishment
foreach ($this->serviceModules as $service) {
$service->afterPublish();
}
}
}
這樣拴还,動態(tài)發(fā)布的調(diào)用方可以通過addServiceModule/removeServiceModule動態(tài)地添加/刪除服務(wù)模塊。
UML圖
重構(gòu)帶來的好處
松耦合
服務(wù)模塊與核心模塊是獨立的欧聘,通過接口建立松耦合的關(guān)系片林;可動態(tài)添加/刪除服務(wù)模塊。
易于維護
服務(wù)模塊的修改不會直接影響核心模塊怀骤。
易于擴展
如果需要添加其它服務(wù)模塊费封,只需實現(xiàn)服務(wù)約定的接口,并將新的服務(wù)模塊動態(tài)添加到核心模塊即可蒋伦。