国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

我是如何將業務代碼寫優雅的

voyagelab / 708人閱讀

摘要:高內聚低耦合高內聚低耦合一直是軟件設計領域里亙古不變的話題,重構的目標是提高代碼的內聚性,降低各功能間的耦合程度,降低后期維護成本,特別是寫業務代碼,這一點相當重要。

0x00 前言

我是一名來自螞蟻金服-保險事業群的前端工程師,在一線大廠的業務部門寫代碼,非常辛苦但也非常充實。業務代碼不同于框架代碼、個人項目或者開源項目,它的特點在于邏輯復雜、前后依賴多、可復用性差、迭代周期短,今天辛辛苦苦寫的代碼,上線運行一周可能就下線了。能熟練書寫框架代碼、構建底層基礎設施的工程師不一定能寫好業務代碼。

有人說,業務代碼無非就是按部就班,優不優雅?who care?。但實際業務規則復雜得多,不是依葫蘆畫瓢就能輕松解決的,寫一段糟糕的代碼,可能要用雙倍的時間去發現和解決問題,麻煩了自己、也難受了和你并肩作戰的戰友。

有時候為了減少重復開發的成本,反復提煉和沉淀有復用價值的功能,就需要我們對業務代碼進行合理抽象、甚至精雕細琢,要把業務代碼寫得優雅并非易事。我一直認為,程序設計和搬磚的最大區別在于設計二字,寫代碼也是一門藝術活。今天就借此機會,站在前端工程師的視角,給大家分享關于書寫業務代碼的最佳實踐。

0x01 漸進式重構

漸進式重構是不斷地對既有代碼進行抽象、分離和組合。做代碼重構之前需要回答兩個問題:

1、什么樣的代碼需要重構?
2、何時進行重構?

設計不是一蹴而就的,有時候寫著寫著才發現某些代碼可以抽離出來多帶帶使用,需要重構的代碼需要滿足幾個條件:

1、代碼后期可復用
2、代碼無副作用
3、代碼邏輯單一

過早重構可能會因需求變化太快白白浪費許多時間;過晚重構會因為代碼邏輯復雜、相似代碼積壓過多導致變更風險太高,難以維護。漸進式重構如下圖所示(紅色部分為增加的代碼):

首先我們在同一個源文件中新增功能,發現部分代碼無副作用且可分離,因此在同一個文件中進行代碼分割,形成許多功能單一的模塊。如此往復后發現單文件的體積越來越大,此時就可以將功能相關聯的模塊抽出來放到多帶帶的文件中統一管理,如 helpers、components、constants 等等。

0x02 高內聚低耦合

高內聚低耦合一直是軟件設計領域里亙古不變的話題,重構的目標是提高代碼的內聚性,降低各功能間的耦合程度,降低后期維護成本,特別是寫業務代碼,這一點相當重要。

舉個栗子,比如新需求希望在現有的產品頁面上增加發紅包功能,以吸引用戶開通某個功能,按照正常邏輯,我需要:

1、在當前頁面中引入相關依賴
2、初始化,查詢紅包相關信息
3、用戶點擊時,觸發紅包發送

白色部分表示上個版本的代碼,紅色部分表示完成這個需求需要變更的代碼:

這樣一來,這個發紅包功能就和以前的代碼嚴重耦合,如果這是個只需要上線一周的臨時需求,下線代碼的時候就是一個高風險的動作;如果上線運行期間還需要對產品頁面進行迭代,越往后就越搞不清楚誰是誰了。合理的設計應該是下面這個樣子的:

將和產品代碼無關的功能性代碼拆分出來,放到另一個文件中內部維護好整個生命周期狀態,對外只暴露少量的接口或是方法,這樣一來對產品頁面的改造只需要:

1、引入紅包組件
2、用戶點擊時,調用紅包組件的發獎方法

這樣的變更是極小的、明確的、可控的。換句話說,整個紅包功能是高內聚的,與產品代碼是低耦合的。這樣實踐也帶來另一個好處:我得到了一個可復用的紅包組件!

0x03 合理冗余

業務需求是多變的,寫出來的代碼也是如此,頻繁地抽象很可能導致過度設計,一個抽象很可能隨著迭代次數的增多變得十分復雜。在存在多個變量的分支業務場景,比如同時包含活動是否過期、是否已參加活動、是否完成一次任務這樣的情況,會存在多個嵌套 if-else 結構,這時將代碼冗余設計是個不錯的選擇。下面舉一個例子來說明什么是合理冗余:

e.g. 有這樣一個需求,一開始很簡單,需要設計兩個運營展位:

那么抽象一個組件:

const Item = ({ title, content }) => (
  <div>
    <h4>{title}h4>
    <p>{content}p>
  div>
);

現在需求要求在第一個展位的標題上增加熱文標記:

也很容易:

const Item = ({ title, content }, index) => (
  <div>
    <h4>{title}{index === 0 && <span>hotspan>}h4>
    <p>{content}p>
  div>
);

需求又變了,要求:在第一個展位去掉內容,并且在下方加個按鈕;第二個展位的標題右邊增加一個超鏈接以及增加一個副標題:

這下有點惡心了:

const Item = ({ title, content }, index) => (
  

{title} {index === 0 && hot} {index === 1 && 去看看}

{index === 1 &&
副標題
}

{index !== 0 && content} {index === 0 &&

);

可以看到,之前抽象的好好的,現在需求一變,代碼就面目全非了,中間混雜著兩個狀態(第一個、第二個)的判斷邏輯。實際情況很可能比這個更復雜,在多狀態交織邏輯難以通過一套代碼表達清楚時,進行合理冗余就是個不錯的選擇,將上面的例子用兩個 if 重寫如下:

// 第一個展位
if (index === 0) {
  return (
    

標題一hot

); } // 第二個展位 if (index === 1) { return (

標題二去看看

副標題

內容

); }

合理冗余其實也是一種重構,根據業務邏輯和代碼規模,做相似抽象還是代碼冗余,這其實也是漸進式重構的一種體現。無論采用何種方式,只要能把業務邏輯表達清楚,讓代碼始終保持良好的可讀性和可維護性,就OK。

下面介紹一個過度抽象的例子。

0x04 拒絕過度抽象

在 JavaScript 代碼中進行深度抽象有時并非好事,有 OOP(面向對象編程)背景的同學很容易先入為主設計:所有數據結構都想封裝成一個類 (Class) 。實際上 Class 在 JavaScript 中是個不好的設計,它并非真正的類。幾年前,我曾看到一位 Java 轉前端的同學寫出了類似這樣的代碼:

class DataItem {
  constructor(id, name, value) {
    this.id = id;
    this.name = name;
    this.value = value;
  }
}

class DataCollection {
  constructor() {
    this.items = new Array();
  }
  insert(item) {
    this.items.push(item);
  }
}

const item1 = new DataItem(1, "name1", 100);
const item2 = new DataItem(2, "name2", 200);
const list = new DataCollection();
list.insert(item1);
list.insert(item2);
...

一股濃濃的 Java 味道撲面而來。上面的代碼并沒有發揮出 JavaScript 的語言優勢,也增加了不少理解成本,如果用面向對象編程的思路去寫前端代碼,特別是業務代碼,可真是一場噩夢。正確的寫法如下:

const list = [{
  id: 1,
  name: "name1",
  value: 100
}, {
  id: 2,
  name: "name2",
  value: 200
}];

由于 JS 屬于弱類型語言,弱類型語言就要發揮弱類型的優勢,無需過多類型定義和 Class 抽象,用最原始的 object 和 function 足以勝任從簡單到復雜的業務場景。這里特別想提及前端所熟知的 Redux 狀態管理器,Redux 中,state 就是普通的 object,reducer 就是普通的 function,action 也是普通的 object,不加任何類型約束。因為簡單,所以強大。

0x05 眼觀六路

用弱類型語言編程意味著無需編譯,無需編譯的語言天生存在一個問題是在運行前缺少必要的類型檢查,將問題暴露在運行時往往會導致非常嚴重的故障。這就要求開發者能在寫代碼的階段嚴格保證代碼質量,特別是寫業務代碼。

集成開發環境(IDE)對 JavaScript 代碼的智能提示能力有限,很多時候不能通過 IDE 查找某個變量或者函數的所有引用,這時就要善用 Ctrl + F 進行全局查找來保證自己的單點變更不會影響到其他地方。如果使用 TypeScript,在類型檢查、引用查找上的幫助會更好。

0x06 總結

今天給大家分享了關于書寫業務代碼的一些實踐經驗:對代碼進行漸進式重構是提升代碼健壯性的有力武器;設計高內聚低耦合的代碼可以讓你在做需求的過程中沉淀出一套通用解決方案;合理冗余可以簡化復雜的場景,讓開發變得高效、測試變得容易;拒絕過度抽象,擁抱簡單,靈活變化。保持 眼觀六路 的好習慣能讓代碼質量提升一個臺階。

最后,希望大家能在實際開發過程中去體會和學習,不斷思考和總結,將業務代碼寫優雅,是個很大的挑戰。

?


關于我們:

我們是螞蟻保險體驗技術團隊,來自螞蟻金服保險事業群。我們是一個年輕的團隊(沒有歷史技術棧包袱),目前平均年齡92年(去除一個最高分8x年-團隊leader,去除一個最低分97年-實習小老弟)。我們支持了阿里集團幾乎所有的保險業務。18年我們產出的相互寶轟動保險界,19年我們更有多個重量級項目籌備動員中?,F伴隨著事業群的高速發展,團隊也在迅速擴張,歡迎各位前端高手加入我們~

我們希望你是:技術上基礎扎實、某領域深入(Node/互動營銷/數據可視化等);學習上善于沉淀、持續學習;性格上樂觀開朗、活潑外向。

如有興趣加入我們,歡迎發送簡歷至郵箱:yiyuan.lpy@antfin.com


本文作者:螞蟻保險-體驗技術組-祎遠

掘金地址:micooz

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/6820.html

相關文章

  • 史上最優雅在VM層取消Coroutine方式

    摘要:問題為了防止銷毀時異步任務仍然在進行所導致的內存泄露,我們都會在方法中去取消異步任務??偨Y層可以天然自動監視銷毀,我一直在找尋如何優雅的自動取消異步任務,在目前來看是最佳的方案。協程絕對是最先進的,效率最高,最優雅的技術棧組合。前提 在Android MVVM模式,我使用了Jetpack包中的ViewModel來實現業務層,當然你也可以使用DataBinding,關于Android業務層架構...

    cuieney 評論0 收藏0
  • 從0到1優雅實現PHP多進程管理

    摘要:目的綜上所述,我的目標就是實現基于模式實現的多進程管理工具。備注下文中,父進程統稱為子進程統稱為。最后我們通過下圖來簡單的總結和描述這個多進程實現的過程控制上面實現了多進程和多進程的常駐內存,那如何去管理呢答案多進程通信。 _ | | _ __ __ _ _ __...

    lakeside 評論0 收藏0
  • 我是如何一步步“改造”redux

    摘要:但是在使用開發的過程中還是感覺不太順手,本文將闡述我是如何對進行一步步改造以適應個人和團隊開發需求的。所以說,我們如何在保證的設計原則以及項目規范性上,對其進行簡化改造,是我這里需要解決的問題。 從Vue換到React+Redux進行開發已經有半年多的時間,總的來說體驗是很好的,對于各種邏輯和業務組件的抽象實在是方便的不行,高階組件,洋蔥模型等等給我帶來了很多編程思想上的提升。但是在使...

    jemygraw 評論0 收藏0
  • SegmentFault 社區訪談 | mcfog:自由進出 Coding && A

    摘要:上次的訪談,介紹了下可愛的依云醬,回憶傳送門。這里簡單地介紹下龍女仆,全名小林家的龍女仆,為什么介紹這部劇呢因為設計獅顏值同學也安利了這部。劇情簡介在獨身又勞累的小林劃重點一名程序員身邊突然出現的穿著女仆服裝的美少女托爾。 showImg(https://segmentfault.com/img/bVR6p5?w=900&h=385); 上次的訪談,介紹了下可愛的依云醬,回憶傳送門。不...

    neroneroffy 評論0 收藏0
  • SegmentFault 社區訪談 | mcfog:自由進出 Coding && A

    摘要:上次的訪談,介紹了下可愛的依云醬,回憶傳送門。這里簡單地介紹下龍女仆,全名小林家的龍女仆,為什么介紹這部劇呢因為設計獅顏值同學也安利了這部。劇情簡介在獨身又勞累的小林劃重點一名程序員身邊突然出現的穿著女仆服裝的美少女托爾。 showImg(https://segmentfault.com/img/bVR6p5?w=900&h=385); 上次的訪談,介紹了下可愛的依云醬,回憶傳送門。不...

    lx1036 評論0 收藏0

發表評論

0條評論

voyagelab

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<