今日的課程是由我們課程助教Tyson來主講。
重點針對於前端的架構設計解析。
首先,我們要問怎麼樣才是一個好的程式架構?
很多從junior工程師要進階到senior的時候,都會有這樣的問題。
即使已經抄過不少別人寫出來的設計模式,但依然不知道何時該使用什麼模式。
本課程最後一張投影片已接露其中的心法。
那便是沒有最好的設計模式,只有當下適合的設計模式。
持續改善是我們的專業也是我們的宿命。
這就是為什麼我們一開始要三層式架構?(client <--> node server <--> python server)。
除了第一是為了SSR(Server Side Render)加強SEO與縮短瀏覽器端看見白屏的時間外,我認為最重要的是減少耦合;避免一台server單一擴充,如果中間有node server,我們可以在中間的node server設定cache,減少後端API(Python) server的負擔,因為API Server有可能不單只是有node server那邊的請求,可能有來自其他平台或外面導進的流量所影響。
這樣的架構也符合本身公司內部前台B2C未來的構想與規劃。所以我們一開始朝這樣的方向設計。
因此前端程式架構剛開始設計的原則,盡量簡單且符合目前系統的需求即可。
然後在程式碼的內容上我們也帶這學員去一步一步改善優化元件,從一開始最直接的寫法,到慢慢套用我們在課程中所帶到一些設計模式方法。
設計模式(design pattern)之前提到,包含但不限於有以下幾種模式:
Factory method(工廠模式)
Lazy initialization(惰性初始模式)
Prototype(原型模式)
Singleton(單例模式)
Cache Pattern(快取模式)
Decorator(裝飾者模式)
Extension object(擴展對象模式)
前端的模式可能有:
Compound Component
Render Props
High Order Component(類似裝飾者模式)
...
太多了。
很多人study了所有設計模式,然後在一些大型專案就隨意拿一個出來使用,並不曉得為何要使用這些設計模式。
因此我們的作法是漸進式的。
一開始我們的Image中的promoMsg(圖片左下角Discount 30% off的文字)是寫死在Image裡面
class Image extends React.Component {
constructor(props) {
super(props)
this.imageRef = React.createRef()
}
render() {
return (
<Fragment>
<div
className={`${this.props.className} ${styles.image}`}
data-src={this.props.src}
ref={this.imageRef}
/>
{this.props.promoMsg && <div className={styles.tag}>{this.props.promoMsg}</div>}
</Fragment>
)
}
}
後來我們發現可能這個Promo訊息,可能依照不同頁面或區塊的商品清單,而會顯示不同的位置,這時候我們就決定透過HOC將這一部分的UI抽離,透過類似裝飾者模式的方式,完成此優化。
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>
)
}
}
export default withPromoTag
改成以下使用方式
const ImageWithPromoTag = withPromoTag(Image)
...
return (
<div>
<ImageWithPromoTag src={product.image} promoMsg={product.promoMsg} />
</div>
)
過猶不及都是不好的。
再次強調。設計模式只有找到當下最適合的。
千萬不要認為設計模式是萬能的。
這導致有些人一但看到超出這些設計模式的程式碼,就不知從何看起。
這是在於大多數的人將設計模式真的視為設計模式。
設計模式並不是像拿一個蘋果在高空中放手,一定會往下掉的普遍真理。更不能說它是絕對真理。
它的出現是因為人性的需要。也就是因人而異,沒有絕對一定要怎麼做。
常有人討論設計模式到後來說,
「設計模式不要自己創好嗎? 你這根本是假的decorator。真正的decorator應該要這樣寫...」
這不是在討論技術,這是在炫技,也就沒有再繼續討論的必要。
任何程式的solution都是在解決人的問題。
設計模式最終是為了反映於人性。
模式錯了再改就可以,最好的是保留以後方便修改的彈性,才是比較重要的。
在課堂的後半段,講師Tyson也帶領大家體驗一次TDD(Test-Driven Development)的開發過程。
而TDD的精神也是如同設計模式般,擁有持續改善的精神,不用過度去寫沒有在測試範圍的程式功能。
我們也讓同學們一起刷leetcode。
就像之前文章所說,要落實TDD的開發流程,首先團隊都要清楚知道撰寫unit test的好處,並且養成先寫測試的習慣。
今日課程講師專業剪影