• 當前位置:首頁 > IT技術 > 移動平臺 > 正文

    手里拿著錘子,看啥都像釘子
    2021-08-08 14:07:45

    一、背景

    有人在我的構造器文章下提了下面一個問題:

    老師,提一個問題,在實際生活中遇到的 比如說我寫了一個發送消息的方法。比如說有一個參數是 messageDTO,但是他有很多屬性,比如說 topic,tag,shadingKey,msg, delayTime 等等,但是我希望別人在使用這個方法的時候傳入 messageDTO 是我想要的,即我會將無參構造方法私有化,因為我不想讓別人使用無參構造new一個對象出來,(因為自己去set可能某一些參數設置有遺漏),然后只限制了 幾種構造函數,或者使用靜態方法來創建對象。
    然后對象的入參是由要求的。比如說你想法 普通消息,那么需要 topic和msg,發延遲消息,需要topic msg和delayTime,發順序消息需要額外再加一個shadingKey,請問在這種情況下如何使用建造者模式。即只允許使用某一組參數來創建對象

    二、探索

    每種設計模式(甚至任何技術)都有自己適合的場景。
    雖然我們學了建造者模式,未必一定要用建造者模式。

    針對這種場景,有很多方法可以更優雅地實現:

    • 可以使用工廠模式,通過函數名體現類型。
    • 可以通過繼承的方式通過類名來體現類型。
    • Builder 模式變通。

    2.1 靜態工廠

    MessageFactory類
    構造普通消息

    public static MessageDTO buildCommonMsg(String topic, String msg) {
    
    // 直接 new 然后 set 或者用 builder都可以
    }
    

    構造延時消息

     public  static MessageDTO buildDelayMsg(String topic, String msg,Long delayTime) {
    // 省略
     }
    

    順序消息類似

     public static MessageDTO buildOrderedMsg(String topic, String msg, String shadingKey) 
    {
        // 省略
     }
    

    可以加上參數校驗。

    2.2 利用繼承來表意

    普通消息 CommonMsgDTO

    public class CommonMsgDTO{
      private String topic;
      private String msg;
    
       // 提供全參構造方法
    }
    

    延時消息 DelayMsg

    public class DelayMsgDTO extends CommonMsgDTO{
      private Long delayTime;
    
       // 提供全參構造方法
    }
    

    順序消息 DelayMsg

    public class OrderedMsgDTO extends CommonMsgDTO{
      private String shadingKey;
    
       // 提供全參構造方法
    }
    

    這樣構造時只有全參數構造函數,就不容易傳錯,而且看名知意。
    如果傳 null 可以報錯。


    2.3 builder模式活用

    public static class Builder{  
     // 省略
     public Builder(String topic, String msg){
       // 省略
     }
       // 其他屬性的set 方法
    }  
    

    對普通的 builder 模式稍微改造下,將必備參數作為 Builder 的唯一構造函數的參數。
    這樣必備屬性必然會傳入。
    但是如果必傳參數太多,不推薦使用這種方式。


    哪怕是不同的 builder 模式,在 build時進行參數校驗。

    可能還有很多解決方案,上面給出兩個比較簡單且常見的方法。
    在執行發送消息的函數上加上參數校驗,這樣就不容易出錯。

    三、總結

    希望大家一定要破除 ”手里拿著錘子,看啥都像釘子“的心理。
    在學習任何技術時,思考其最適合的場景,為了解決什么問題,局限是什么。

    在解決問題前想清楚問題是什么?

    比如這位同學核心是為了能讓使用者清晰地區分類型,然后讓使用者知道不同類型的參數差異。
    然后再去思考怎樣更容易區分開呢?必傳參數一定要早構造的時候校驗嗎?
    慢慢地,問題就明了了,就更容易得到更科學的答案。

    總之,既要埋頭苦學,又要抬頭看路。學而不思則罔!


    如果想在開發中少趟坑,感興趣可以看看我最近出的幾個 GitChat:

    • 《程序員進階之排錯和避坑方法論》
    • 《CodeReview 的正確姿勢》

    ?

    本文摘自 :https://blog.51cto.com/u

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码