<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          答應我,別再 if/else 走天下了可以嗎?

          共 4434字,需瀏覽 9分鐘

           ·

          2020-02-14 23:29

          來源:CodeSheep

          作者:hansonwong99

          ?哎,曾幾何時?

          想當年,其實我也特別鐘情于 if/else連環(huán)寫法,上來就是一頓SAO操作,比如舉個好理解的簡單栗子

          一般來說我們正常的后臺管理系統(tǒng)都有所謂的角色的概念,不同管理員權限不一樣,能夠行使的操作也不一樣,比如:

          • 系統(tǒng)管理員(?ROLE_ROOT_ADMIN):有?A操作權限
          • 訂單管理員(?ROLE_ORDER_ADMIN):有?B操作權限
          • 普通用戶(?ROLE_NORMAL):有?C操作權限

          比如一個用戶進來,我們需要根據(jù)不同用戶的角色來判斷其有哪些行為,這時候SAO代碼出現(xiàn)了:

          1. publicclassJudgeRole{


          2. publicString judge( String roleName ) {

          3. String result = "";

          4. if(roleName.equals("ROLE_ROOT_ADMIN")) { // 系統(tǒng)管理員有A權限

          5. result = "ROLE_ROOT_ADMIN: "+ "has AAA permission";

          6. } elseif( roleName.equals("ROLE_ORDER_ADMIN") ) { // 訂單管理員有B權限

          7. result = "ROLE_ORDER_ADMIN: "+ "has BBB permission";

          8. } elseif( roleName.equals("ROLE_NORMAL") ) { // 普通用戶有C權限

          9. result = "ROLE_NORMAL: "+ "has CCC permission";

          10. } else{

          11. result = "XXX";

          12. }

          13. return result;

          14. }


          15. }

          這樣當系統(tǒng)里有幾十個角色時,那幾十個 if/else嵌套可以說是非常酸爽了…… 這樣一來非常不優(yōu)雅,別人閱讀起來很費勁;二來則是以后如果再復雜一點,或者想要再加條件的話不好擴展;而且代碼一改,以前的老功能肯定還得重測,豈不瘋了……

          所以,如果在不看下文的情況下,你一般會如何去對付這些令人頭痛的if/else語句呢?

          當然有人會說用 switch/case來寫是否會優(yōu)雅一些呢?答案是:毛區(qū)別都沒有

          接下來簡單講幾種改進方式,別再 if/else走天下了


          ?有枚舉為啥不用?

          什么角色能干什么事,這很明顯有一個對應關系,所以學過的枚舉為啥不用呢?


          首先定義一個公用接口 RoleOperation,表示不同角色所能做的操作:

          1. publicinterfaceRoleOperation{

          2. String op(); // 表示某個角色可以做哪些op操作

          3. }


          接下來我們將不同角色的情況全部交由枚舉類來做,定義一個不同角色有不同權限的枚舉類 RoleEnum

          1. publicenumRoleEnumimplementsRoleOperation{


          2. // 系統(tǒng)管理員(有A操作權限)

          3. ROLE_ROOT_ADMIN {

          4. @Override

          5. publicString op() {

          6. return"ROLE_ROOT_ADMIN:"+ " has AAA permission";

          7. }

          8. },


          9. // 訂單管理員(有B操作權限)

          10. ROLE_ORDER_ADMIN {

          11. @Override

          12. publicString op() {

          13. return"ROLE_ORDER_ADMIN:"+ " has BBB permission";

          14. }

          15. },


          16. // 普通用戶(有C操作權限)

          17. ROLE_NORMAL {

          18. @Override

          19. publicString op() {

          20. return"ROLE_NORMAL:"+ " has CCC permission";

          21. }

          22. };

          23. }


          接下來調(diào)用就變得異常簡單了,一行代碼就行了, if/else也灰飛煙滅了:

          1. publicclassJudgeRole{

          2. publicString judge( String roleName ) {

          3. // 一行代碼搞定!之前的if/else沒了!

          4. returnRoleEnum.valueOf(roleName).op();

          5. }

          6. }


          而且這樣一來,以后假如我想擴充條件,只需要去枚舉類中加代碼即可,而不是去改以前的代碼,這豈不很穩(wěn)!

          除了用枚舉來消除 if/else,工廠模式也可以實現(xiàn)



          ?有工廠模式為啥不用?

          不同分支做不同的事情,很明顯就提供了使用工廠模式的契機,我們只需要將不同情況單獨定義好,然后去工廠類里面聚合即可。

          首先,針對不同的角色,單獨定義其業(yè)務類:

          1. // 系統(tǒng)管理員(有A操作權限)

          2. publicclassRootAdminRoleimplementsRoleOperation{


          3. privateString roleName;


          4. publicRootAdminRole( String roleName ) {

          5. this.roleName = roleName;

          6. }


          7. @Override

          8. publicString op() {

          9. return roleName + " has AAA permission";

          10. }

          11. }

          1. // 訂單管理員(有B操作權限)

          2. publicclassOrderAdminRoleimplementsRoleOperation{


          3. privateString roleName;


          4. publicOrderAdminRole( String roleName ) {

          5. this.roleName = roleName;

          6. }


          7. @Override

          8. publicString op() {

          9. return roleName + " has BBB permission";

          10. }

          11. }

          1. // 普通用戶(有C操作權限)

          2. publicclassNormalRoleimplementsRoleOperation{


          3. privateString roleName;


          4. publicNormalRole( String roleName ) {

          5. this.roleName = roleName;

          6. }


          7. @Override

          8. publicString op() {

          9. return roleName + " has CCC permission";

          10. }

          11. }


          接下來再寫一個工廠類 RoleFactory對上面不同角色進行聚合:

          1. publicclassRoleFactory{

          2. staticMap<String, RoleOperation> roleOperationMap = newHashMap<>();


          3. // 在靜態(tài)塊中先把初始化工作全部做完

          4. static{

          5. roleOperationMap.put( "ROLE_ROOT_ADMIN", newRootAdminRole("ROLE_ROOT_ADMIN") );

          6. roleOperationMap.put( "ROLE_ORDER_ADMIN", newOrderAdminRole("ROLE_ORDER_ADMIN") );

          7. roleOperationMap.put( "ROLE_NORMAL", newNormalRole("ROLE_NORMAL") );

          8. }


          9. publicstaticRoleOperation getOp( String roleName ) {

          10. return roleOperationMap.get( roleName );

          11. }

          12. }


          接下來借助上面這個工廠,業(yè)務代碼調(diào)用也只需一行代碼, if/else同樣被消除了:

          1. publicclassJudgeRole{

          2. publicString judge( String roleName ) {

          3. // 一行代碼搞定!之前的 if/else也沒了!

          4. returnRoleFactory.getOp(roleName).op();

          5. }

          6. }


          這樣的話以后想擴展條件也很容易,只需要增加新代碼,而不需要動以前的業(yè)務代碼,非常符合“開閉原則”

          來,我們接著來,除了工廠模式,策略模式也不妨試一試



          ?有策略模式為啥不用?

          策略模式和工廠模式寫起來其實區(qū)別也不大!

          在上面工廠模式代碼的基礎上,按照策略模式的指導思想,我們也來創(chuàng)建一個所謂的策略上下文類,這里命名為 RoleContext

          1. publicclassRoleContext{


          2. // 可更換的策略,傳入不同的策略對象,業(yè)務即相應變化

          3. privateRoleOperation operation;


          4. publicRoleContext( RoleOperation operation ) {

          5. this.operation = operation;

          6. }


          7. publicString execute() {

          8. return operation.op();

          9. }

          10. }


          很明顯上面?zhèn)魅氲膮?shù) operation就是表示不同的“策略”。我們在業(yè)務代碼里傳入不同的角色,即可得到不同的操作結果:

          1. publicclassJudgeRole{

          2. publicString judge( RoleOperation roleOperation ) {

          3. RoleContext roleContext = newRoleContext( roleOperation );

          4. return roleContext.execute();

          5. }

          6. }

          1. publicstaticvoid main( String[] args ) {

          2. JudgeRole judgeRole = newJudgeRole();

          3. String result1 = judgeRole.judge(newRootAdminRole("ROLE_ROOT_ADMIN"));

          4. System.out.println( result1 );

          5. String result2 = judgeRole.judge(newOrderAdminRole("ROLE_ORDER_ADMIN"));

          6. System.out.println( result2 );

          7. String result3 = judgeRole.judge(newNormalRole("ROLE_NORMAL"));

          8. System.out.println( result3 );

          9. }




          ?共? ?勉?

          好了,先講到這里吧,本文僅僅是拋磚引玉,使用了一個極其簡單的示例來打了個樣,然而其思想可以廣泛地應用于實際復雜的業(yè)務和場景,思想真的很重要!寫代碼前還是得多思考一番,考慮是否有更具可擴展性的寫法!

          推薦閱讀

          全部文章分類與整理(算法+數(shù)據(jù)結構+計算機基礎),持續(xù)更新

          【吐血整理】那些讓你起飛的計算機基礎知識:學什么,怎么學?

          普普通通,我的三年大學

          寫公眾號15個月以來,這一路上的學習與收獲

          歷經(jīng)兩個月,我的秋招之路結束了!

          2020 第一篇原創(chuàng) | 我是如何讓自己變的更加優(yōu)秀的?

          瀏覽 33
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰久草 | 婷婷亚洲丁香 | 日本不卡a | 伊人在线成人视频 | 日本免费不卡视频 |