明明開發時間很趕,我為什麼還要重構整個專案

2021-10-02 04:44:11 字數 3640 閱讀 5578

首先談為什麼要進行重構吧,畢竟已經維護了兩年了,大大小小也經歷了很多次迭代開發,為何這次會進行重構呢?

這要先交代一下我們這個介面專案是咋回事。

controlers #控制器層

models #模型類層

common #公用函式

config #配置檔案目錄

libs #基礎類庫

ext #第三擴充套件

index.php #入口檔案

複製**從**的專案結構看得出來,最主要的是控制器層和模型層:

控制器層(controllers)

controllers

v1.0.0

v1.0.1

...v5.0.0

複製**模型層(models):

業務邏輯層,也包含對資料進行curd,呼叫第三方,引數校驗等功能,幾乎所有業務功能都在這裡,不同版本的模型層相互呼叫,所以這一層也是功能最混亂的層,因此也是最需要重構的分層,models目錄的版本劃分與controllers類似,不同版本的model類有大量重複的**。

models

v1.0.0

v1.0.1

...v5.0.0

複製**通過上面的介紹,其實你會發現,這個是乙個簡單到不能再簡單的專案,但再簡單的專案,隨著業務的推進以及多個迭代開發,**的**極其混亂,總結起來大概是以下幾個問題:

沒有良好的目錄分層,大體上只是簡單分了控制器層和模型層,所有的業務邏輯都堆積在控制器層和模型層,完全沒有任何擴充套件性可言。

很多配置都直接寫死在**裡,雖然專案中有專門存放配置的目錄,但還是有很多的配置直接寫死在**,比如連線redis的**。

沒有編碼規範,無論變數名還是常量或是類名,命名都很隨意。

**裡還充斥著大量的魔法數值,如何有新人接手,會完全搞不清楚到底這些數值到底什麼意思。

所有的**都沒有輸出日誌,出現bug時,很難定位問題。

業務**直接堆積在控制層和模型層,沒有抽離公共**,新增乙個版本介面時,需要完全複製上個版本的**。

完全沒有使用php的命名空間,不能很好劃分不同的類。

上面列出專案的幾個問題,其實重構的過程,就是把上面提出問題的優化吧。

重構要達到的目的

重新劃分專案結構,使專案結構層級更加清晰。

進行版本迭代開發時,不需要複製乙份同樣的**,提公升開發效率。

增加**的可維護性。

重構的原則

單一職責原則:每個類的功能要單一,每個方法的作用要單一,避免**臃腫。

變數命名規範

避免在**中直接寫魔法數值

迭代介面,新增乙個介面版本時,不需要完全複製上乙個版本介面的**。

重新劃分的專案結構

controllers # 控制器層,只能將引數傳遞給services層。

v1_0_0

indexcontroller.php

v1_0_1

......

v5_0_0

services #具體業務邏輯層,可以呼叫manager層或models來實現業務邏輯

v1_0_0

v1_0_1

......

v5_0_0

handlers # 擴充套件層,對services的補充

models # 模型,針對資料表的curd**

entity #實體類

managers #業務封裝層

libs #類庫

ext #第三方類庫

common #公用函式

index.php #入口檔案

複製**下面的專案的目錄結構的截圖:

乙個controller類的示例:

class indexcontroller

public function actionindex()}

乙個service型別的示例:

#不同版本的service之間通用**抽取到service類,作為基類被繼承

class indexservice

//業務方法

public function index($page = 1)

protected function getarticle()

}

在重構過程中,之所以設計如上所示的目錄結構,乙個重要的考慮點就是如果在新增加乙個版本介面時,最大限度地復用上乙個版本的邏輯,這裡的新增介面的意思是現在首頁介面的版本為v1.0.0,但由於版本迭代,會把介面公升級為v1.0.1,也就是介面公升級。

乙個介面的公升級,無非兩個原因:

介面的業務處理邏輯發生改變,因此需要公升級介面。

介面的資料結構發生改變,比如新增資料或資料型別發生改變,因此需要公升級介面。

比如說,index介面從v1.0.0公升級v1.0.1時,getarticle()方法資料結構或者業務邏輯發生改變,這時候繼承父類介面,並覆蓋getarticle()方法即可。

class indexservice extends indexbaseservice

//重寫覆蓋父類邏輯

pulic function getarticle()}

但這時候,你會發現在getarticle()方法重寫的邏輯,只在v1.0.1這個版本中,如果這個重寫的邏輯在後續版本也是一樣的,那不是每個版本都要重寫?

這時候,可以將這段邏輯抽取出來,給每個需要的版本復用,如果某個有單獨的處理邏輯,可以使用的的覆蓋重寫的方法,而抽取出來的邏輯,放在handlers目錄結果中,handlers目錄是對services中需要重寫覆蓋並會在多個版本復用邏輯的抽取層。

所以我們把getarticle()方法抽取出來,如下所示:

trait getarticle}

這時候v3.0.1的介面,載入上面handlers的方法,完全邏輯復用。

class indexservice extends indexbaseservice

}老實說,專案開發時間不夠,而我個人能力也有限,因此我只能在本次的開發中,盡自己的能力去完善整個專案架構,很多不完善的地方,只能之後的開發中優化了。

重構後的優點

相比原先全部業務堆積在models層,劃分後的架構,每個層級只負責自己的事情,因此邏輯比較清晰,**可維護性強,每個類或方法的職責單一,降低了開發難度。

重構後的缺點

當然,原來的**非常簡單,就是controllers層直接呼叫models層,或者有時候,所有的業務邏輯直接寫在controller層,重構後,**的複雜性也會相應增加。

可能很多人會問,這麼簡單的專案,直接重做不就好了嗎?其實是這樣,除了上面重構中的重新分層,專案還有很多公用的**和模組,如果重新開發乙個專案的話,那麼這些基礎的也需要重新開始,而舊專案也需要繼續維護,更加增加開發和維護的成本,因此重構是比較合適的選擇。

老實說,我重構的這個介面專案一點也不複雜,最主要的**還是curd,並沒有非常複雜的業務邏輯,但由於從一開始就沒有進行嚴格的**架構分層,在開始過程也沒有一致的**規範,導致經過兩三年業務的發展與**迭代開發,造成了**混亂和重複業務邏輯堆積。

所以,對於任何專案來說,良好的**分層和開發規範,是保證專案可維護性的根本。

為什麼我使用 Linux 開發

當我對 linux 的印象似乎還停留在黑乎乎的命令列介面上的時候,我身邊的一些朋友告訴我或者建議我使用 linux 時,我會一臉驚訝的問他,那個怎麼用 來開發或者日常使用 首先說說我每天打交道最多的 shell 吧,我給自己設定的預設 shell 是 fish。你還可以搭配 fzf 這個軟體,實現高...

為什麼我不推薦敏捷開發?

當專案成員越多,我越不推薦敏捷開發,原因在於 當連自己要做什麼事 為什麼這樣做 這樣做為了解決什麼問題 都搞不清楚前,就跳下去玩敏捷開發,那和比通靈還慘,通靈起碼還有個目標物在前面,搞不清楚狀況的人只能陪他跳世界迷霧開地圖了 敏捷開發 mba智庫百科 最下方有段 對敏捷開發的誤解 可順便參考 敏捷軟...

我為什麼要開發亞馬遜ERP

在大學的時候時常聽經貿系的同學說,他的乙個同學搞亞馬遜,乙個月兩萬多的存收入,讓人聽起來無比的羨慕。在我看來,亞馬遜的印象還在停留在賣書的 這幾年,aws,傑夫 貝佐斯 jeff bezos 的字眼經常出現,讓我想深入了解一下亞馬遜。大學的學的是計算機系,在學校的時候做過幾個web應用,我自認為和網...