你還想if/else用多久?來學(xué)學(xué)這幾種改進(jìn)方式吧
哎,曾幾何時(shí)
想當(dāng)年,其實(shí)我也特別鐘情于 if/else連環(huán)寫法,上來就是一頓SAO操作,比如舉個(gè)好理解的簡單栗子:
一般來說我們正常的后臺(tái)管理系統(tǒng)都有所謂的角色的概念,不同管理員權(quán)限不一樣,能夠行使的操作也不一樣,比如:
- 系統(tǒng)管理員( ROLE_ROOT_ADMIN):有 A操作權(quán)限
- 訂單管理員( ROLE_ORDER_ADMIN):有 B操作權(quán)限
- 普通用戶( ROLE_NORMAL):有 C操作權(quán)限
比如一個(gè)用戶進(jìn)來,我們需要根據(jù)不同用戶的角色來判斷其有哪些行為,這時(shí)候SAO代碼出現(xiàn)了:
- public class JudgeRole {
- public String judge( String roleName ) {
- String result = "";
- if (roleName.equals("ROLE_ROOT_ADMIN")) {
- // 系統(tǒng)管理員有A權(quán)限
- result = "ROLE_ROOT_ADMIN: " + "has AAA permission";
- } else if ( roleName.equals("ROLE_ORDER_ADMIN") ) {
- // 訂單管理員有B權(quán)限
- result = "ROLE_ORDER_ADMIN: " + "has BBB permission";
- } else if ( roleName.equals("ROLE_NORMAL") ) {
- // 普通用戶有C權(quán)限
- result = "ROLE_NORMAL: " + "has CCC permission";
- } else {
- result = "XXX";
- }
- return result;
- }
- }
這樣當(dāng)系統(tǒng)里有幾十個(gè)角色時(shí),那幾十個(gè) if/else嵌套可以說是非常酸爽了…… 這樣一來非常不優(yōu)雅,別人閱讀起來很費(fèi)勁;二來則是以后如果再復(fù)雜一點(diǎn),或者想要再加條件的話不好擴(kuò)展;而且代碼一改,以前的老功能肯定還得重測,豈不瘋了……
所以,如果在不看下文的情況下,你一般會(huì)如何去對付這些令人頭痛的if/else語句呢?
當(dāng)然有人會(huì)說用 switch/case來寫是否會(huì)優(yōu)雅一些呢?答案是:毛區(qū)別都沒有!
接下來簡單講幾種改進(jìn)方式,別再 if/else走天下了
有枚舉為啥不用
什么角色能干什么事,這很明顯有一個(gè)對應(yīng)關(guān)系,所以學(xué)過的枚舉為啥不用呢?
首先定義一個(gè)公用接口 RoleOperation,表示不同角色所能做的操作:
- public interface RoleOperation {
- String op(); // 表示某個(gè)角色可以做哪些op操作
- }
接下來我們將不同角色的情況全部交由枚舉類來做,定義一個(gè)不同角色有不同權(quán)限的枚舉類 RoleEnum:
接下來調(diào)用就變得異常簡單了,一行代碼就行了, if/else也灰飛煙滅了:
- public class JudgeRole {
- public String judge( String roleName ) {
- // 一行代碼搞定!之前的if/else沒了!
- return RoleEnum.valueOf(roleName).op();
- }
- }
而且這樣一來,以后假如我想擴(kuò)充條件,只需要去枚舉類中加代碼即可,而不是去改以前的代碼,這豈不很穩(wěn)!
除了用枚舉來消除 if/else,工廠模式也可以實(shí)現(xiàn)
有工廠模式為啥不用
不同分支做不同的事情,很明顯就提供了使用工廠模式的契機(jī),我們只需要將不同情況單獨(dú)定義好,然后去工廠類里面聚合即可。
首先,針對不同的角色,單獨(dú)定義其業(yè)務(wù)類:
接下來再寫一個(gè)工廠類 RoleFactory對上面不同角色進(jìn)行聚合:
接下來借助上面這個(gè)工廠,業(yè)務(wù)代碼調(diào)用也只需一行代碼, if/else同樣被消除了:
- public class JudgeRole {
- public String judge( String roleName ) {
- // 一行代碼搞定!之前的 if/else也沒了!
- return RoleFactory.getOp(roleName).op();
- }
- }
這樣的話以后想擴(kuò)展條件也很容易,只需要增加新代碼,而不需要?jiǎng)右郧暗臉I(yè)務(wù)代碼,非常符合“開閉原則”。
來,我們接著來,除了工廠模式,策略模式也不妨試一試
有策略模式為啥不用
策略模式和工廠模式寫起來其實(shí)區(qū)別也不大!
在上面工廠模式代碼的基礎(chǔ)上,按照策略模式的指導(dǎo)思想,我們也來創(chuàng)建一個(gè)所謂的策略上下文類,這里命名為 RoleContext:
很明顯上面?zhèn)魅氲膮?shù) operation就是表示不同的“策略”。我們在業(yè)務(wù)代碼里傳入不同的角色,即可得到不同的操作結(jié)果: