<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      需求變更,代碼改的像辣雞 - 論代碼質(zhì)量

       

      一句注釋引發(fā)的思考

      接到一個有雞毛信般的緊急需求(當(dāng)然,002的需求向來是如此緊急的):大屏展示原來只有二個品牌數(shù)據(jù),現(xiàn)增加到三個品牌的數(shù)據(jù)。一句話的需求,且沒有業(yè)務(wù)邏輯變更,我認(rèn)為可以迅雷不及掩耳之勢,2小時收拾干凈交差。當(dāng)我滿腔激情的定位的核心邏輯部分時,這樣一句注釋(見下圖),讓我頓時思緒天馬行空:

      這個作者經(jīng)歷了什么樣一個撕心裂肺的過程?但是可以肯點(diǎn)的是這一定是一個有想法的作者,不由得心中肅然起敬。

      這段代碼經(jīng)歷了多少次的蹂躪,才會讓作者的心潮有如此波瀾?

      抑或,這到底提出了怎么樣一個需求,讓作者需要通過這樣的注釋來宣泄心中怨氣?

      注釋圖

         

        巴拉開代碼修改記錄,作者已經(jīng)去別的地方高就了,要不是留了這些代碼,實(shí)在想不起有這樣的一個同事存在過;代碼提交記錄比較整潔,大部分代碼是在5月29號提交,5月30大概是修復(fù)bug提交了小部分代碼。如此看來,代碼沒有經(jīng)歷過什么苦難,這里的需求僅僅是每個品牌的門店按訂單數(shù)量排序(如下圖),想想怎么也鬧出什么大動靜... 再細(xì)讀作者留下的代碼,只能說作者給自己設(shè)置了難度系數(shù)(這說法太含蓄了),稍微有一點(diǎn)改動,便是牽一發(fā)而動全身,于是留了這樣一個不太成熟且不太有價(jià)值的注釋,想起了最近在讀的一本書,Bob大叔的《代碼整潔之道》,頗有一點(diǎn)不成熟的感觸。

       

       

      如何衡量代碼質(zhì)量

      《代碼整潔之道》一書開篇第一句話就是一個著名的論斷:衡量代碼質(zhì)量的唯一有效標(biāo)準(zhǔn):WTF/min。 一看到WTF這樣的簡稱就不明覺厲,一頓搜索居然沒有找到“標(biāo)準(zhǔn)”的解釋,更覺得高深莫測。 也是在后來一個偶然的時間看到原來是 What-The-Fuck 的縮寫,看重看這張經(jīng)典的圖,一下子恍然頓悟:原來如此,就該如此。

      原本學(xué)得這是一本好書,甚至覺得大部分程序都應(yīng)該去閱讀這類的書籍一遍(比如 馬丁·福勒出品的《重構(gòu)-改善既有代碼的設(shè)計(jì)》)。 看到這樣的論述,更覺此書接地氣,仿佛與大師拉近了距離了。回想起過往種種,以及最近修改歷史代碼時的反應(yīng),沒什么比WTF更有表達(dá)力了。

       

       再回到開篇講的注釋,當(dāng)時的作者必然也是有類似的反應(yīng),只是他的吐嘲對象是他自己,或者他只會認(rèn)為這是需求的而不是代碼的問題。所以 WTF/min作為衡量代碼質(zhì)量的唯一有效標(biāo)準(zhǔn),還得加一個定語:優(yōu)秀的Coder喊出的WTF次數(shù),才是真正的標(biāo)準(zhǔn)。 至于如何為優(yōu)秀的代碼,在《代碼整潔之道》,《重構(gòu)-改善既有代碼的設(shè)計(jì)》等經(jīng)典書籍里都有詳細(xì)的描述:

      • 從變量命名,到注釋,到方法,到類,到模塊都有非常詳細(xì)的規(guī)范;
      • 從抽象到邊界,到依賴也有完整的方法論;
      • 從SOLID設(shè)計(jì)原則到,組件相關(guān)的 CRP,CCP,CRP等原則都有從理論到落地的解說。

       坦白講,讀完這些書后,我感覺自己原來寫的代碼,很多都缺乏這樣的思考,也有不少代碼相當(dāng)丑陋,甚至覺得:在code這件事讓,只能算得上初窺門徑。于是越時讀書,越覺得自己無知。最近讀技術(shù)書籍的間歇,順便翻讀了幾本名人傳記:奧本海默為了讓人覺得他是天才,總是"偷偷"的讀書學(xué)習(xí);特斯拉甚至在病危之際也是一心讀書;讓我們有在劍手的錢學(xué)森利用所有空閑時間閱讀方能一年完成碩士學(xué)位,并獲得航空和數(shù)學(xué)雙博士,成本最年輕的終生教授...(省略好多榮譽(yù))。他們無一不是通過自己努力讀書,思考,實(shí)踐終成我等學(xué)習(xí)的楷模。最近招聘的經(jīng)歷中,大部分應(yīng)聘的人幾乎不看技術(shù)書籍的了,也是讓我捉摸不透。

      讀技術(shù)書籍沒用了嗎

      最近兩月一直忙于面試,溝通了沒有100個也有80個候選人,大部分人都沒有了讀書習(xí)慣,更不用說技術(shù)書籍了,倒是有部分說覺得blog比書籍有用多了。有些說工作太忙,有得說沒有用....他們中有的在傳統(tǒng)公司朝9晚5,有的在互聯(lián)網(wǎng)企業(yè)996,有從小企業(yè)過來的,也有從阿里,快手過來的... 其中一個人的話,讓我記憶非常深刻,最后環(huán)節(jié),我問他現(xiàn)在還讀書不,他說為了進(jìn)阿里,他非常努力了2年,把《深入理解java虛擬機(jī)》讀了2遍,《高性能mysql》,《深入理解kafka》... 都仔細(xì)閱讀了,后來進(jìn)了阿里,覺得這些書都沒有沒啥用了,也不在閱讀其他技術(shù)書籍了,最后我不知道應(yīng)該說啥,畢竟我沒去過阿里,于是結(jié)束了面試。就我自己而言,早些年面試也是被問得體無完膚,也有過這樣的心態(tài)閱讀了大量類似 《深入理解java虛擬機(jī)》,《MySQL技術(shù)內(nèi)幕:InnoDB存儲引擎》,《RocketMQ技術(shù)內(nèi)幕:RocketMQ架構(gòu)設(shè)計(jì)與實(shí)現(xiàn)原理》,《從Paxos到Zookeeper:分布式一致性原理與實(shí)踐》等書籍,確實(shí)也讓自己在后來的面試中可以從容面對。但越是閱讀,越是感覺自己不知道的東西越多,越是想要通過閱讀來充實(shí)自己。于是又開始閱讀系統(tǒng)設(shè)計(jì),架構(gòu)一類的書籍。時至今日,讀到《代碼整潔之道》時,依然覺得即使在做了10年的編碼這件事上,不懂的依然有非常之多(哈哈,也許是悟性不夠)。 從前面的名人,到我身邊認(rèn)識的人,大凡優(yōu)秀的人的,獨(dú)有閱讀的習(xí)慣,并且有大量閱讀自己專業(yè)相關(guān)的書籍。

      最近和媳婦探討讀書這件事兒,說我周末在家除了溜娃就是刷新聞,現(xiàn)如今的新聞包括熱搜又大部分是沒有“營養(yǎng)”的,也聊到目下短視頻盛行,下到3歲,上到70,地鐵上,公園里,城市里,老家里... 到處都是,當(dāng)然也包括我們自己的爸媽,談及此,心中不覺升起一股名族憂心(哈哈,操心有點(diǎn)多了)。于是我放下了新聞,當(dāng)然了周5晚上,等娃睡著后,我們買些宵夜,找一部金典電影還是保持著。 一段時間后,發(fā)現(xiàn)一個周閱讀10幾個小時好像也挺正常的,閱讀成生活的一部分。也沒有了過去那種讀了多久了,要休息下的,看看新聞,看看電視的想法了。現(xiàn)在想來,讀書也好,新聞,短視頻也罷,本質(zhì)且沒啥差異,內(nèi)心富足就好。

      再回到前面的面試,也不知道,我在面試過程中,把讀書這一塊看得如此重,是否合適,但是我相信:喜歡閱讀技術(shù)書籍的人,應(yīng)該都不會太差。 

      回到前面的代碼

      回家開篇的注釋問題,想和大家一直分享下代碼重構(gòu)過程,如果不幸被作者看到,希望不要介懷,就如Bob大叔所講,每個程序員都應(yīng)該接專業(yè)眼光的檢視(哈哈也許我也不是那么專業(yè))。 需求比較簡單,就是兩個品牌下的門店根據(jù)訂單數(shù)排序。 現(xiàn)在的需求是增加了第三個品牌,門店信息有品牌屬性。

      如果作者閱讀了Clean Code ,他就會明白代碼走向整潔的4原則:

      • 運(yùn)行所有測試;
      • 不可重復(fù);
      • 表達(dá)了程序員的意圖;
      • 盡可能減少類和方法的數(shù)量。

      就會把排序算法抽離出來,與業(yè)務(wù)邏輯分離,避免大量重復(fù);

      如果他深刻喊出了 Don't Repeat YourSelf, 就不會有么多 ConsultationOrderRank 對象的出事化,甚至不會單獨(dú)處理有數(shù)據(jù)與沒數(shù)據(jù)的情況。

      如果作者閱讀了Clean Architecture,他就會明白要面向抽象,而不是具體去編程,

      他就會面向品牌這個概念去編程,而不是面向具體的品牌1,品牌2去實(shí)現(xiàn)。

       

      
      
      //需求變更,改的像辣雞。
      if (CollectionUtils.isEmpty(orderList)) {
                  List<CfgStore> allStoreList = cfgStoreService.getStoresBLAndBabyBL();
                  List<CfgStore> bellaList = allStoreList.stream().filter(st -> {
                      return st.getType() == 0;
                  }).sorted(Comparator.comparingInt(CfgStore::getStoreId)).collect(Collectors.toList());
      
                  ArrayList<ConsultationOrderRank> ballaResult = new ArrayList<>();
                  int bellaIndex = 0;
                  for (CfgStore store : bellaList) {
                      ConsultationOrderRank consultationOrderRank = new ConsultationOrderRank();
                      consultationOrderRank.setStoreName(store.getNameAlias());
                      consultationOrderRank.setStoreId(store.getStoreId());
                      consultationOrderRank.setOrderNum(0);
                      consultationOrderRank.setSort(bellaIndex);
                      ballaResult.add(consultationOrderRank);
                      bellaIndex++;
                  }
                  List<ConsultationOrderRank> blRankResult = ballaResult.stream()
                          .sorted(Comparator.comparing(ConsultationOrderRank::getSort)).collect(Collectors.toList());
      
                  List<CfgStore> babyBellaList = storeList.stream().filter(st -> {
                      return st.getType() == 1;
                  }).sorted(Comparator.comparingInt(CfgStore::getStoreId)).collect(Collectors.toList());
      
                  ArrayList<ConsultationOrderRank> babyBallaResult = new ArrayList<>();
                  int babyIndex = 0;
                  for (CfgStore store : babyBellaList) {
                      ConsultationOrderRank consultationOrderRank = new ConsultationOrderRank();
                      consultationOrderRank.setStoreName(store.getNameAlias());
                      consultationOrderRank.setStoreId(store.getStoreId());
                      consultationOrderRank.setOrderNum(0);
                      consultationOrderRank.setSort(babyIndex);
                      babyBallaResult.add(consultationOrderRank);
                      babyIndex++;
                  }
      
                  List<ConsultationOrderRank> babyRankResult = babyBallaResult.stream()
                          .sorted(Comparator.comparing(ConsultationOrderRank::getSort))
                          .collect(Collectors.toList());
                  Order order = Order.builder().consultationOrderRankStBellaList(blRankResult)
                          .consultationOrderRankBabyBellaList(babyRankResult).build();
      
                  return order;
              }
      
              List<CfgStore> others = storeList.stream().filter(store -> {
                  return !Arrays.stream(storeIdArr).collect(Collectors.toList()).contains(store.getStoreId());
              }).collect(Collectors.toList());
      
              Map<Integer, CfgStore> storeMap = storeList.stream().collect(Collectors.toMap(CfgStore::getStoreId, store -> {
                  return store;
              }));
      
              //品牌1門店ID
              List<Integer> blIdList = storeList.stream().filter(st -> st.getType().equals(0))
                      .map(CfgStore::getStoreId).collect(Collectors.toList());
              //品牌2門店ID
              List<Integer> babyblIdList = storeList.stream().filter(st -> st.getType().equals(1))
                      .map(CfgStore::getStoreId).collect(Collectors.toList());
      
              //品牌2分組數(shù)據(jù)
              Map<Integer, List<HeOrder>> babyblMap = orderList.stream()
                      .filter(order -> babyblIdList.contains(order.getStoreId()))
                      .collect(Collectors.groupingBy(HeOrder::getStoreId));
              //品牌2分組數(shù)據(jù)
              Map<Integer, List<HeOrder>> blMap = orderList.stream()
                      .filter(order -> blIdList.contains(order.getStoreId()))
                      .collect(Collectors.groupingBy(HeOrder::getStoreId));
      
              //品牌1排行數(shù)據(jù)
              List<ConsultationOrderRank> bellaList = new ArrayList<>();
              //品牌2排行數(shù)據(jù)
              List<ConsultationOrderRank> babyBellaList = new ArrayList<>();
              //品牌1
              for (Entry<Integer, List<HeOrder>> entry : babyblMap.entrySet()) {
                  CfgStore cfgStore = storeMap.get(entry.getKey());
                  String storeName = cfgStore.getNameAlias();
                  if (Strings.isNotBlank(storeName)) {
                      List<HeOrder> orderNum = entry.getValue();
                      ConsultationOrderRank consultationOrderRank = new ConsultationOrderRank();
                      consultationOrderRank.setStoreName(storeName);
                      consultationOrderRank.setStoreId(entry.getKey());
                      consultationOrderRank.setOrderNum(orderNum == null ? 0 : orderNum.size());
                      babyBellaList.add(consultationOrderRank);
                  }
              }
      
              List<CfgStore> otherbabyBlList = others.stream().filter(store -> {
                  return store.getType() == 1;
              }).collect(Collectors.toList());
      
              for (CfgStore store : otherbabyBlList) {
                  ConsultationOrderRank consultationOrderRank = new ConsultationOrderRank();
                  consultationOrderRank.setStoreName(store.getNameAlias());
                  consultationOrderRank.setStoreId(store.getStoreId());
                  consultationOrderRank.setOrderNum(0);
                  babyBellaList.add(consultationOrderRank);
              }
      
              //品牌2
              for (Entry<Integer, List<HeOrder>> entry : blMap.entrySet()) {
                  CfgStore cfgStore = storeMap.get(entry.getKey());
                  String storeName = cfgStore.getNameAlias();
                  if (Strings.isNotBlank(storeName)) {
                      List<HeOrder> orderNum = entry.getValue();
                      ConsultationOrderRank consultationOrderRank = new ConsultationOrderRank();
                      consultationOrderRank.setStoreName(storeName);
                      consultationOrderRank.setStoreId(entry.getKey());
                      consultationOrderRank.setOrderNum(orderNum == null ? 0 : orderNum.size());
                      bellaList.add(consultationOrderRank);
                  }
              }
      
              List<CfgStore> otherBellaList = others.stream().filter(store -> {
                  return store.getType() == 0;
              }).collect(Collectors.toList());
      
              for (CfgStore store : otherBellaList) {
                  ConsultationOrderRank consultationOrderRank = new ConsultationOrderRank();
                  consultationOrderRank.setStoreName(store.getNameAlias());
                  consultationOrderRank.setStoreId(store.getStoreId());
                  consultationOrderRank.setOrderNum(0);
                  bellaList.add(consultationOrderRank);
              }
              //品牌1排序
              List<ConsultationOrderRank> blRank = bellaList.stream().sorted(Comparator.comparing(ConsultationOrderRank::getOrderNum).reversed())
                      .collect(Collectors.toList());
              int blSort = 0;
              int blIndexCounter = 0;
              for (int i = 0; i < blRank.size(); i++) {
                  //訂單=0, 訂單值不同, 遞增
                  boolean flag = blRank.get(i).getOrderNum() == 0 || (i != 0 && blRank.get(i).getOrderNum() != blRank.get(i - 1).getOrderNum());
                  if (flag) {
                      blSort = blSort + blIndexCounter + 1;
                      blIndexCounter = 0;
                  } else {
                      if (i != 0) {
                          blIndexCounter++;
                      }
                  }
                  blRank.get(i).setSort(blSort);
              }
      
              //品牌2排序
              List<ConsultationOrderRank> babyBlRank = babyBellaList.stream().sorted(Comparator.comparing(ConsultationOrderRank::getOrderNum).reversed())
                      .collect(Collectors.toList());
              int babySort = 0;
              int babyIndexCounter = 0;
              for (int i = 0; i < babyBlRank.size(); i++) {
                  //訂單=0, 訂單值不同, 遞增
                  boolean flag = babyBlRank.get(i).getOrderNum() == 0 || (i != 0 && babyBlRank.get(i).getOrderNum() != babyBlRank.get(i - 1).getOrderNum());
                  if (flag) {
                      babySort = babySort + babyIndexCounter + 1;
                      babyIndexCounter = 0;
                  } else {
                      if (i != 0) {
                          babyIndexCounter++;
                      }
                  }
                  babyBlRank.get(i).setSort(babySort);
              }

       

       我相信作者如果經(jīng)常閱讀技術(shù)書籍,寫出的代碼應(yīng)該是這樣的。

              //統(tǒng)計(jì)每個品牌每個門店訂單數(shù)量
              for (Integer brandType : brandTypeList){
                  Map<Integer, Long> theBrandStoreOrderCount = orderList.stream().filter(order -> brandType.longValue() == order.getBrandType()).collect(Collectors.groupingBy(HeOrder::getStoreId, Collectors.counting()));
                  List<CfgStore> brandStores = storeList.stream().filter(store -> store.getType().equals(brandType)).collect(Collectors.toList());
      
                  List<ConsultationOrderRank> storeOrderRank = new ArrayList<>();
      
                  brandStores.forEach(store ->{
                      Long orderCount = 0L;
                      if (theBrandStoreOrderCount.containsKey(store.getStoreId())){
                          orderCount = theBrandStoreOrderCount.get(store.getStoreId());
                      }
                      ConsultationOrderRank storeOrder = ConsultationOrderRank.builder()
                              .storeId(store.getStoreId())
                              .orderNum(orderCount.intValue())
                              .storeName(store.getStoreName())
                              .sort(0).build();
                      storeOrderRank.add(storeOrder);
                  });
                  List<ConsultationOrderRank> sortedStoreRank = storeOrderRank.stream().sorted(Comparator.comparing(ConsultationOrderRank::getOrderNum).reversed()).collect(Collectors.toList());
      
                  setSortWithSameRankNum(sortedStoreRank);
      
                  BrandOrderStatistic statistic = BrandOrderStatistic.builder()
                          .name(CfgStoreEnum.getValueByCode(brandType))
                          .storeOrderRank(sortedStoreRank)
                          .brandType(brandType).build();
                  brandOrderStatistics.add(statistic);
              }

       

      如此這般,我們當(dāng)時踐行了編碼里的童子軍規(guī):當(dāng)你離開營地時候,要讓它比你來的時候更整潔干凈。

      成為一名優(yōu)秀的程序員!

       

      posted @ 2024-07-04 10:36  2J  閱讀(3650)  評論(34)    收藏  舉報(bào)
      主站蜘蛛池模板: 俄罗斯少妇性XXXX另类| 亚洲国产欧美一区二区好看电影| 国产亚洲人成网站在线观看| 东方四虎av在线观看| 亚洲香蕉伊综合在人在线| 欧美综合婷婷欧美综合五月 | 国产高潮刺激叫喊视频| 日本黄色三级一区二区三区| 欧美成人午夜精品免费福利| 国产乱码精品一区二三区| 国产情侣草莓视频在线| av日韩在线一区二区三区| 九台市| 亚洲成人四虎在线播放| 韩国无码AV片午夜福利| 久久五月丁香合缴情网| 色色97| 美欧日韩一区二区三区视频| 亚洲精品国产aⅴ成拍色拍| 中文字幕日韩有码国产| 欧美日韩中文字幕视频不卡一二区| 两个人免费完整高清视频| 中文字幕在线精品人妻| 久久国内精品一区二区三区| 国产妇女馒头高清泬20p多毛| 精品人妻一区二区三区蜜臀| 大地资源网第二页免费观看| 91久久夜色精品国产网站| 门国产乱子视频观看| 亚洲国产一区二区三区久| 国产精品偷伦费观看一次| 欲乱人妻少妇邻居毛片| 国产精品一线天粉嫩av| 亚洲国产无线乱码在线观看| 亚洲高清国产拍精品网络战 | 看全色黄大黄大色免费久久| 亚洲国产大胸一区二区三区| 国产91丝袜在线播放动漫| 亚洲av熟女国产一二三| 中文字幕乱码无码人妻系列蜜桃| 成人午夜福利精品一区二区|