前端技術突破之前,就是要「以正合」,也就是精通JS/CSS/HTML絕對是必要的前提,因為沒有合何來之後的勝。
如何精通前端技術核心概念,前幾篇都有提到,不再贅述。
這邊要講的是,前端技術要突破,非以奇制勝不可。
前端猶如海賊王中的魯夫橡皮人一樣,回應與解決方案都需因時因地制宜,呼應了前端RWD(Responsive Web Design)的特性。
而要有這樣的特性,你必須先能夠吸收所有好的壞的程式碼的案例,海納百川後方能成其大業。意思就是說,看別人的code要看的多,不管好的爛的都要看。
然後就是下海去改! 沒有爛code可以改? 網路上open source多的是,找一個就對了。(雖然以下都不是爛code)
react本身就是一個open source:
https://github.com/facebook/react
https://github.com/reduxjs/react-redux
https://github.com/erikras/redux-form
python的flask框架也是:
https://github.com/pallets/flask
https://github.com/flask-restful/flask-restful
https://github.com/wxWidgets/wxPython
並且遵照以下原則去修改。
因為怕出糗而不敢問?
這就是大部分的年輕工程師學習止步的第一關鍵。
Are You Asking The Right Questions?
透過敏捷的引導,知道我們需要團隊,需要被夥伴激勵。結果有人在團隊中,也不去主動問問題的話,就失去團隊共同學習的意義。
問蠢問題只是第一步。重點要先問,才有可能進一步問出對的問題。
比如與團隊成員的對話如下:
P君: 請問你怎麼知道要改哪些地方? 哪些地方程式碼可以刪掉?
I君: 就很簡單的搜尋啊。(講這句話並沒有貶抑意思,但很多年輕工程師聽到這句話就玻璃心了,為什麼很簡單...)分析這次後端資料改動的是basketItemKey值,改用item id。所以全站尋找這個key值改掉,包含組合basketItemKey的地方直接刪除掉。color與style也是一樣,全站搜尋...
然後I君就從頭到尾pair programming的做一次給P君看。如果P君沒有問I君,P君可能要花兩倍的時間,還沒摸索出怎麼改。
最後P君在例會分享,再用自己的話跟大家說明一遍,他怎麼做這個重構,才算真正學會。
學到東西永遠是自己的,而且嘴巴長在別人臉上,你不問他也沒有義務要跟你說。
真所謂亂世出英雄,亂碼出貓熊(因為都在熬夜看code)。不,是亂碼出geek。
每一次的重構與大型新專案開發,永遠都是在時程不夠的狀況下逐步完成,那如何在亂中取勝呢?
當在開發時程只有1週的狀況下,我們要如何在現有龐大的Legacy Code中抽絲剝繭,並在時程內完成任務,且顧及一定的品質還稍微重構一些不好的程式碼?
比如I君要套用一個之前同事做的元件。但已有一段時間沒有人maintain,這要如何評估一週內做的完?
先測痛點。
那就是這個元件主要是要拿來播放m3u8串流格式的影片,但到底能不能播才是最重要的。
但年輕的前端工程師,可能就會不斷專注在原本的元件寫的太死,或者沒有用es6的語法去寫等問題。而花時間去改不是最重要的事情,改完一週也過去了,才發現此元件m3u8無法播放。
應該先寫死塞一個m3u8的串流檔案進去看看,發現若可以播,那基本上我們不需要整個重寫,因為時程也不夠我們整個去重構。
然後我只專注在少量的程式碼重新整理,比如if else條件有重複的做整併,一些非使用this且複用性高的function改成用static寫在元件內。
static getMediaSource = () => {
if (typeof window !== 'undefined') {
return window.MediaSource || window.WebKitMediaSource
}
}
static isHlsSupported = () => {
const mediaSource = EHSPlayer.getMediaSource()
const sourceBuffer = window.SourceBuffer || window.WebKitSourceBuffer
const isTypeSupported =
mediaSource &&
typeof mediaSource.isTypeSupported === 'function' &&
mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"')
const sourceBufferValidAPI =
!sourceBuffer ||
(sourceBuffer.prototype &&
typeof sourceBuffer.prototype.appendBuffer === 'function' &&
typeof sourceBuffer.prototype.remove === 'function')
return isTypeSupported && sourceBufferValidAPI
}
...
EHSPlayer.isHlsSupported()
每次只要有優化一點就是進步。
這過程就是需要不斷「化繁為簡」的練習。
要做到「化繁為簡」,中心思想便在於「捕捉事物的共通性,界定事物的相異性」。 - 出自2007年iThome的文章
與我之前文章所提到的物件三大原則運用在生活上,不謀而合。
繼承不是找一個富爸爸,而是找到這世界彼此的關聯性。
上述的static就是如此。在過程中,把共通的東西給抽離出來,並大膽的刪除不必要的程式碼。
剩下的就是做好測試。
小東西還好,但如果是比較大型的feature,就要考量未來是不是可能要不斷改寫某些元件。
這個設計的過程,都與物件導向的概念有關連。SOLID中的單一功能、依賴反轉,還有loose coupling鬆耦合。
這還進一步關係到設計模式(Design Pattern),可以去了解,但不用每個都精通。這裡無法一一贅述。
我只舉一個React中最常使用的例子。
裝飾者(修飾)模式。它顧名思義,就是在現有的元件中加入擴充的功能,讓原本的單一元件不需要修改內部即可有所改變。範例如下:
const withPromoTag = WrappedComponent =>
class extends React.Component {
displayName = `withPromoTag(${getDisplayName(WrappedComponent)})`
static defaultProps = {
promoMsg: ''
}
render() {
const { promoMsg } = this.props
return (
<div className={styles.promoWrap}>
<WrappedComponent {...this.props} />
{promoMsg && <div className={styles.tag}>{promoMsg}</div>}
</div>
)
}
}
WrappedComponent就是被裝飾的元件,withPromoTag就是裝飾品。利用hoc(high order component)來實現。
雖然這樣比較麻煩還要多寫一個PromoTag的元件,但這樣對於往後使用的開發者,更有彈性去增加其他裝飾品。
寫完這篇才發現,網路上其實很多人寫過這類精進的心法: https://kknews.cc/n/8vj33on.html
大同小異,只是看你願不願意做而已。
學到東西永遠是自己的,而且嘴巴長在別人臉上,你不問他也沒有義務要跟你說。
喜歡這句話,會寫,也要會講
而會講之前,要先學會問