star

胖胖 Model 的減重方法:Presenter

開發application時,常常會有大量的呈現(presentation)邏輯。

像是日期格式、金額格式(是否穿插逗號)、名稱(是否需要大寫)等等。

把這些logic寫在model的話,很容易就會導致model過胖。

舉例來說,如果文章model在不同地方需要呈現日期、日期時間、西方格式、台灣格式,

model就會長這樣(以Laravel Eloquent舉例):

要將這類presentation logic抽出來,許多框架採用了「helper function」的作法,

也就是定義好幾個functions用來處理呈現邏輯。

除了helpers的作法之外,還有一個非常簡單有效的方法。

也就是使用Decorator pattern來封裝出presenter,像這樣:

概念上只是把原本的model從constructor傳進去,原本的function搬過去,

把$this改寫成$this->article即可。

然而,這樣會導致view裡面需要初始化物件:

在view裡面做這種事,怎麼看都是很醜的。

多寫一個function即可改善:

view內會變成這樣:

新的問題來了:多次呼叫present會浪費記憶體。

可以這樣改善:

多個model都使用presenter的話,這段code會重複。善用PHP trait可以解決這個問題:

Laravel社群至少有3套成熟的presenter實作:

https://github.com/laracasts/Presenter

https://github.com/robclancy/presenter

https://github.com/laravel-auto-presenter/laravel-auto-presenter

有的功能豐富、有的比較陽春,但是概念上一樣,都是decorator pattern的應用。

下次你的application包含大量presentation logic時,不妨試試看這個作法。

(Photo via Susanne Nilsson, CC licensed)