Avoid ugly If/else blocks & make your code modular with Strategy

06-Sep-19

คัมภีร์เทพ IT

See the original english version Click here!

 

Syntax ใหม่ ๆ ใน ES6 มีวัตถุประสงค์เพื่อทำให้ Code มีความกระชับและชัดเจนยิ่งขึ้น ซึ่งมีเครื่องมืออำนวยความสะดวกมากมายที่ช่วยในเรื่อง Readability แต่ก็ไม่น่าเชื่อที่ Iskander (เจ้าของบทความ) กลับรู้สึกว่า If/Else และ Switch Statements มักเป็นส่วนที่ดูวุ่นวายที่สุดใน Code ของเขา ดังนั้น เรามาดูวิธีหลีกเลี่ยง If/Else Blocks ที่ยุ่งเหยิงด้วยการจัดระเบียบ Code ด้วย Strategy Pattern ซึ่งน่าจะช่วยให้คุณหลีกเลี่ยงสถานการณ์เหล่านี้ได้

Strategies

Pattern ที่ Iskander กล่าวถึง จะถูกเรียกว่า Strategy ซึ่ง Pattern ตัวนี้ได้รับความนิยมจาก GoF (Gang of Four) และเป็นเครื่องมือที่ยอดเยี่ยมสำหรับการเพิ่มส่วนที่สามารถสลับสับเปลี่ยนกันได้ใน Application Logic ของคุณ

แล้วมันทำงานอย่างไรล่ะ? Strategies จะทำการ Implement ในส่วนตัวแปรของ Function การทำงาน กับ Interface ที่จะใช้งานสำหรับ Generic Object ที่เราเรียกว่า "Context" โดย Context จะใช้ Strategy ที่แตกต่างกันในการดำเนินการบางอย่างตามคำขอของลูกค้า

ให้คิดว่า ชุดของ Strategy เป็นเหมือน “กล่องเครื่องมือ” และ Context เป็นเหมือน “ช่างฝีมือ” ซึ่งช่างฝีมือจะใช้เครื่องมือที่แตกต่างกันไปขึ้นอยู่กับลักษณะของงาน แต่ในกรณีนี้ เครื่องมือทั้งหมดมีคำแนะนำประเภทเดียวกันเกี่ยวกับวิธีการใช้งานพวกมัน

และนี่ก็คือ Diagram เพื่ออธิบายเพิ่มเติมเกี่ยวกับแนวคิดนี้:

Passport.JS

Passport.JS ถือเป็นตัวอย่างที่ดีมากเกี่ยวกับการใช้ Strategy Pattern โดย Passport.JS เป็น Library สำหรับการ Integrate ตัว Authentication System ใน Node.JS Application ของคุณ มันมี Interface ต่าง ๆ มากมายสำหรับการตั้งค่า Authentication สำหรับ Provider ต่าง ๆ ที่คุณต้องการจะใช้ (Facebook, Google, Twitter เป็นต้น) สิ่งที่คุณต้องทำก็คือ เชื่อมต่อ Interface ที่คุณต้องการลงไปใน Authentication Logic ของคุณ ซึ่ง Interface เหล่านั้นสามารถใช้ทดแทนกันได้ และคุณก็สามารถสลับไปใช้ Interface อื่นได้อย่างง่ายดาย

Receipt Sender

ตอนนี้คิดว่าคุณน่าจะมีความเข้าใจพื้นฐานเกี่ยวกับ Strategy Pattern มาในระดับหนึ่งแล้วในทางทฤษฎี ถ้าอย่างงั้นลองมาสร้างระบบง่าย ๆ สำหรับการส่งใบเสร็จรับเงิน (Receipt) ให้กับ User ที่เป็นลูกค้าที่เคยมีการสั่งซื้อ

Define Strategies

มาเริ่มต้นกันด้วย การกำหนด Email Strategy ของเรากันก่อน:

เรากำลังใช้ mailgun Module ในการส่ง Emails ซึ่งใน Strategy Object มี 1 Method send ซึ่งจะรับ receiptHtml และ userEmail เป็น Parameters

คราวนี้ เราจะไปยัง Slack Strategy ของเรากันต่อ:

เรากำลังใช้ NPM Library ของ Slack ในการส่ง Receipt ผ่าน Slack Bot ของเรา และที่สำคัญก็คือ send Method Signature ของ Strategy นั้นก็เหมือน ๆ กับ Email ของมันนั่นเอง

Receipt Manager

ตอนนี้เราได้กำหนด Strategy ของเราเรียบร้อยแล้ว ต่อไปเรามากำหนด Receipt Manager Class ของเราซึ่งจะ Generate Html สำหรับ Receipt และใช้ Strategy ของเราในการส่ง Receipt ให้กับ User:

จะขอข้ามการ Implement ตัว _generateReceiptHtml Method ไปก่อน เนื่องจากมันไม่เกี่ยวข้องกับตัวอย่างของเรา แต่ส่วนที่น่าสนใจก็คือ sendReceipt Method:

  • เรา Generate Html สำหรับ Receipt โดยใช้ _generateReceiptHtml
  • เราส่ง Receipt โดยใช้ Strategy ที่ถูกส่งถึงเรา เป็น Argument

เนื่องจากทั้ง 2 Strategy ของเรามี Method Signature เดียวกัน เราจึงสามารถใช้แทนกันได้โดยที่ ReceiptManager นั้นจะไม่รู้ถึงความแตกต่าง

ทีนี้ เรามาดูกันว่า sendReceipt จะมีลักษณะอย่างไร หากเราไม่ได้กำหนด Strategy ขึ้นมา:

ตอนนี้คุณคงจะสังเกตเห็นได้ว่า Switch  Statement นั้นลด Readability ใน Code ของเราลงได้อย่างไรบ้าง แม้วิธีนี้อาจจะดูไม่ได้แย่มากเท่าไรนักในตอนนี้ แต่ต่อไปหากคุณคิดที่จะเพิ่มช่องทางการส่ง Receipt ที่หลากหลายขึ้น Method นี้จะเริ่มดูยุ่งเหยิงมากขึ้นทันที

Client

ตอนนี้เรามาถึงส่วนสุดท้ายกันแล้ว มาดูกันว่ามันจะง่ายมากแค่ไหนที่จะใช้ Strategy ของเราร่วมกับ Receipt Manager:

มันดูง่ายขึ้นไหม? สิ่งที่เราต้องทำก็คือ การเลือกใช้ Strategy ที่เหมาะสม ซึ่งขึ้นอยู่กับช่องทางที่เราต้องการใช้ และส่งต่อไปยัง Receipt Manager ของเรา

ส่งท้ายบทความ

Strategy Pattern อาจไม่สามารถใช้ได้กับทุกกรณี และบางครั้งอาจดูเป็นการทำที่มากเกินความจำเป็น เพราะท้ายที่สุดแล้ว Pattern นี้เป็นเพียงแค่ “เครื่องมือ” และเหมือนกับเครื่องมืออื่น ๆ คือ คุณต้องการให้แน่ใจว่า พวกมันเหมาะกับลักษณะของงาน อย่างไรก็ตาม Strategy อาจเป็นวิธีที่ดีในการบังคับเรื่อง Separation of Concerns และทำให้ Code ของคุณนั้นแยกออกเป็นส่วน ๆ ได้ และสามารถสลับสับเปลี่ยนกันได้มากขึ้น

ที่มา:  https://itnext.io/

 

 

รับตำแหน่งงานไอทีใหม่ๆ ด้วยบริการ IT Job Alert

 

อัพเดทบทความจากคนวงในสายไอทีทาง LINE ก่อนใคร
อย่าลืมแอดไลน์ @techstarth เป็นเพื่อนนะคะ

เพิ่มเพื่อน

 

บทความล่าสุด