Showing posts with label Design Pattern. Show all posts
Showing posts with label Design Pattern. Show all posts

Monday, 12 November 2012

JavaScript Module Pattern

สำหรับใครที่กำลังศึกษา หรือว่ากำลังเขียน JavaScript Framework ควรที่จะอ่านบทความนี้ดูก่อนครับ คิดว่าหากนำไปใช้ จะช่วยให้สามารถวางโครงสร้างของ Framework ได้ flexible มากขึ้น โดยเราสามารถออกแบบ Framework ออกเป็น module แล้วค่อยๆ include เพิ่มเติมตามความจำเป็น ซึ่งช่วยให้ Framework ของเราไม่ใหญ่เกินความจำเป็นด้วยครับ ลองศึกษาดูได้ที่นี่ครับ http://bit.ly/Uy44Y8

ควรศึกษาการใช้งาน require.js เพิ่มเติมด้วยนะครับ อ่านเพิ่มเติมได้ที่นี่ครับ http://requirejs.org

Wednesday, 18 July 2012

Design Pattern - FlyWeight Pattern


ห้องสมุดก็มีการใช้ FlyWeight Pattern

หากพูดคำว่า FlyWeight Pattern หลายๆคนอาจจะไม่รู้จัก แต่ถ้าพูดถึงคำว่า "ห้องสมุด" คิดว่าหลายๆคนน่าจะคุ้นเคยมากกว่า เราเคยสงสัยหรือไม่ว่า ทำไมห้องสมุดสามารถให้บริการแก่ผู้ใช้จำนวนมากได้ ทั้งๆที่หนังสือก็ไม่ได้มีจำนวนเล่มเท่ากับจำนวนผู้มาใช้บริการ

เหตุผลที่ห้องสมุดสามารถให้บริการแก่ผู้ใช้จำนวนมาก ก็คือ ในขณะใดขณะหนึ่งมีจำนวนผู้ใช้ที่ต้องการอ่านหนังสือเล่มเดียวกันเพียงแค่จำนวนหนึ่ง (อาจจะ 4-5 คน แล้วแต่ความนิยมของหนังสือ) ทำให้ห้องสมุดเพียงแค่จัดหาหนังสือให้เพียงพอกับความต้องการใช้บริการในขณะเดียวกันก็เพียงพอแล้ว เพราะเมื่อผู้ใช้บริการแต่ละคนใช้บริการเสร็จ ก็จะนำหนังสือไปคืน ทำให้ผู้ใช้บริการคนอื่นสามารถใช้บริการได้อีก ซึ่งเป็นเทคนิคเดียวกันกับที่ใช้ใน FlyWeight Pattern นั่นเอง

FlyWeight Pattern เป็นเทคนิคในการนำ Object ที่สร้างไว้แล้ว กลับมาใช้ใหม่ โดยการสร้าง Object ใน FlyWeight Pattern จะทำผ่าน FlyWeight Factory ซึ่งจะทำหน้าที่บริหารการสร้าง instance (โดยการใช้ Object Pool เข้ามาช่วย) ซึ่งจะช่วยให้เราใช้ Memory ได้อย่างมีประสิทธิภาพ สำหรับภาพที่จะแสดงให้ดูต่อไปนี้เป็น UML Diagram สำหรับ FlyWeight Pattern

FlyWeight Pattern UML Diagram

จาก Diagram ข้างต้น จะเห็นว่า FlyWeight Factory จะมี Pool สำหรับเก็บ Object (ในที่นี้คือ FlyWeight Object) อยู่ภายใน ในการใช้งาน Client จะทำการสร้าง Object ผ่าน method ที่ชื่อว่า getFlyWeight() ของ FlyWeightFactory (ซึ่งใน method นี้จะมีการ implement logic ในการนำ Object ที่อยู่ใน pool กลับมาใช้ใหม่)

FlyWeight Pattern เหมาะสำหรับระบบที่มีการสร้าง Object ชนิดเดียวกันจำนวนมากๆ เพราะจะสามารถ Utilize การใช้ object pool ได้อย่างเต็มที่ สำหรับผู้ที่สนใจศึกษาเพิ่มเติม สามารถดู Source Code ที่ implement FlyWeight Pattern ได้ที่นี่ครับ http://en.wikipedia.org/wiki/Flyweight_pattern

แหล่งที่มา: http://en.wikipedia.org/wiki/Flyweight_pattern

Design Pattern - Proxy Pattern


บริการตัวแทนไปรษณีย์ ก็คือ Proxy Service รูปแบบหนึ่ง

หากพูดถึงคำว่า Proxy หลายๆคนที่ไม่ได้คุ้นเคยกับระบบ Network อาจจะไม่ค่อยคุ้นเคยเท่าที่ควร หรืออาจจะเคยได้ยินชื่อ แต่ไม่รู้ว่ามันคืออะไร คำว่า Proxy แปลเป็นภาษาไทยว่า "ผู้แทน" หรือ "ผู้รับมอบฉันทะ" (แปลจาก dictionary ของ Lexitron)

สำหรับในชีวิตประจำวันของเรา มีบริการหลายๆอย่างที่เป็น Proxy Service ยกตัวอย่างเช่นบริการไปรษณีย์ เราสามารถส่งจดหมายหรือพัสดุโดยไม่ต้องไปที่ไปรษณีย์ด้วยตนเอง เพียงแค่ใช้บริการตัวแทนไปรษณีย์ที่อยู่ตามอาคารสำนักงานใหญ่ๆ หรือตามห้างสรรพสินค้า ซึ่งจะสามารถช่วยแบ่งภาระของไปรษณีย์ไทยในการรองรับผู้ใช้บริการในสถานที่ต่างๆไปได้มาก สำหรับผู้ใช้บริการเองก็สะดวก เพราะไม่ต้องเดินทางไปที่ไปรษณีย์เอง ทำให้ประหยัดเวลาและค่าใช้จ่าย

Proxy Server

จะเห็นได้ว่าที่จริงแล้วเราคุ้นเคยกับ Proxy Service เหล่านี้มานานแล้ว เพียงแค่เราไม่รู้ว่ามันคือ Proxy Service ซึ่งแนวคิดของ Proxy Pattern ก็คือ การมอบหมายให้ Class หนึ่งทำหน้าเป็น "ตัวแทน" สำหรับอีก Class หนึ่ง เดี๋ยวผมจะลองยกตัวอย่างในกรณีของ Server ที่ทำหน้าที่เป็น Reverse Proxy ให้ดูนะครับ Reverse Proxy คือ Server ที่รับ Request จาก internet เอาไว้ ก่อนที่จะส่งไปให้ Real Server จริงอีกทีหนึ่ง ซึ่ง Reverse Proxy อาจจะใช้ในการตรวจสอบ Request หรือใช้ในการเปลี่ยนแปลงข้อมูลของ Request ก่อนที่จะส่งไปให้กับ Real Server หรือบางครั้งก็สามารถ Response แทน Real Server ได้ ทั้งนี้เพื่อช่วยลดภาระในการทำงานและเพิ่มความปลอดภัยให้กับ Real Server

เช่นเดียวกัน ในแง่ของการพัฒนาโปรแกรม Proxy Class ก็จะทำหน้าที่รับ Request จาก Client ก่อนที่จะเรียก Real Class จริงๆให้ทำงานต่อไป เดี๋ยวมาลองดู UML Diagram กันก่อนแล้วกันนะครับ

Proxy Pattern UML Diagram

จากใน Diagram จะเห็นว่าทั้ง Proxy และ RealSubject ต่างก็ implement Subject interface และยังแสดงให้เห็นว่า  Proxy มีการ delegate request ไปยัง RelSubject class ให้สังเกตุว่า Client จะมีการ interact กับ Subject interface นั่นหมายความว่า Client สามารถทำงานได้กับทั้ง Proxy และ RealSubject

เราสามารถนำ Proxy Pattern ไปประยุกต์ใช้งานในกรณีที่เราจำเป็นต้องใช้งาน Complex Object หลายๆตัวใน Application ซึ่งแทนที่เราจะสร้าง Complex Object ขึ้นมาหลายๆตัว (ซึ่งเป็นการสิ้นเปลือง Memory) เราสามารถสร้าง Complex Object เพียงแค่ตัวเดียว แต่สร้าง Proxy Object ขึ้นมาหลายๆตัวแทน (ซึ่งจะประหยัด Memory มากกว่า) โดยให้ Proxy แต่ละตัวรับ request แล้ว delegate request ไปที่ Complex Object แทน

สำหรับผู้ที่สนใจศึกษาเพิ่มเติม สามารถดู Source Code ที่ implement Proxy Pattern ได้ที่นี่ครับ http://en.wikipedia.org/wiki/Proxy_pattern

แหล่งที่มา: http://en.wikipedia.org/wiki/Proxy_pattern

Design Pattern - Bridge Pattern

Wikipedia เขียนอธิบายแนวความคิดหลักของ Bridge Pattern ใเอาไว้ว่า คือการแยกส่วนของ Abstraction ออกจาก  Implementation อ่านกี่ทีก็งง เอาเป็นว่าผมจะอธิบายในแบบของผมแล้วกัน


Bridge Pattern คือแนวคิดในการยืมความสามารถจาก Class ภายนอกมาใช้งาน ยกตัวอย่างเช่น Messi ได้รับการคัดเลือกให้ร่วมแข่งขัน Tennis Wimbledon แต่ Messi ตี Tennis ไม่เป็น ก็เลยโทรหา Federer ให้มาช่วย พอถึงตอนแข่ง Federer ก็เข้าสิงในร่างของ Messi ทำให้ Messi สามารถตี Tennis ได้เหมือนกับ Federer

จากตัวอย่างจะสังเกตุว่า Messi ไม่มีความสามารถในการตี Tennis แต่ Messi สามารถตี Tennis ได้ โดยยืมความสามารถดังกล่าวมาจาก Federer นั่นคือความหมายของคำว่า Bridge นั่นเอง เดี๋ยวมาลองดู UML Diagram กันแล้วกันนะครับ

Bridge Pattern UML Diagram

จาก UML Diagram ข้างต้น ด้านซ้ายมือคือ class หลักที่เราจะนำใช้งาน ในที่นี้เราจะเรียกว่า Abstraction ส่วนด้านขวามือคือ class ที่เราจะไปขอยืมความสามารถมา ซึ่งในที่นี้จะเรียกว่า Implementor ให้สังเกตุว่า class ที่ชื่อว่า ConcreteImplementorA และ ConcreteImplementorB ต่างก็ implement Implementor interface ด้วยกันทั้งคู่ จากใน Diagram เราจะเห็นว่า Abstraction class มี "has a" relationship กับ Implementor ซึ่งหมายความว่า Abstraction class จะมี Implentor อยู่ภายในนั่นเอง นอกจากนั้นใน Diagram ยังแสดงให้เห็นว่า ใน Abstract class นั้นมีความสามารถภายในตัวอยู่ ซึ่งในที่นี้คือ method ที่ชื่อว่า operation() แต่ในขณะเดียวกันก็ยังสามารถเรียกใช้ method ที่ชื่อว่า implementation() จาก Implementor interface ได้ (เพราะมี class ที่ implement Implementor interface อยู่ภายใน)

สำหรับผู้ที่สนใจศึกษาเพิ่มเติม สามารถดู Source Code ตัวอย่างที่ implement Bridge Pattern ได้ที่นี่ครับ http://en.wikipedia.org/wiki/Bridge_pattern

แหล่งที่มา: http://en.wikipedia.org/wiki/Bridge_pattern

Design Pattern - Abstract Factory Pattern


Abstract Factory

Abstract Factory Pattern คือ Design Pattern รูปแบบหนึ่งที่อยู่ในกลุ่มของ Creation Pattern ซึ่งมีแนวคิดดังนี้คือ Client ไม่จำเป็นต้องติดต่อกับ concrete Factory เพื่อสร้าง Object แต่ให้ติดต่อผ่าน abstract Factory แทน ซึ่งจะช่วยลด Dependency ระหว่าง Client และ Concrete Factory และจะส่งผลเราสามารถเพิ่มหรือเปลี่ยนแปลง Factory ได้ในภายหลัง โดยที่ไม่กระทบกับการทำงานของ client

ผมอยากกิน "ซาลาเปา Rabbit" ผมไม่สนว่าใครจะผลิตให้ผม!

หากเราสังเกตุดีๆ เราจะพบว่าทุกๆ Design Pattern นั้นแท้จริงแล้วมันอยู่รอบๆตัวเรานี่เอง เพียงแค่เราอาจจะไม่ได้สังเกตุ ผมจะลองยกตัวอย่างที่เป็นรูปธรรมขึ้นมาหน่อย เพื่อที่จะได้เข้าใจได้ง่ายขึ้นนะครับ ยกตัวอย่างเช่น Ronaldo มาเมืองไทย อยากกินซาลาเปา Rabbit เลยเดินเข้าไปซื้อซาลาเปา Rabbit จาก 7-Eleven  ซึ่ง Ronaldo จะสนใจเพียงแค่ว่าจ่ายเงินแล้วจะได้กินซาลาเปา Rabbit ซึ่ง Ronaldo ไม่สนใจว่าซาลาเปาที่ได้จะสั่งผลิตมาจากไหน จากตัวอย่างนี้ Key Message จะอยู่ที่ว่า "Ronaldo ไม่ได้สนใจว่าซาลาเปาจะผลิตมาจากไหน" ซึ่ง 7-Eleven อาจจะจ้างให้ Apple เป็นผู้ผลิต "ซาลาเปา" หรือไม่ก็จ้างให้ Samsung เป็นผู้ผลิตให้ก็แล้วแต่ ตราบใดที่ Ronaldo ไม่สนใจ

จากตัวอย่างข้างต้น Ronaldo เปรียบเสมือนกับ Client (ผู้ใช้บริการ) ส่วน 7-Evelen เปรียบเสมือน Abstract Factory จะสังเกตุว่า Ronaldo ไม่ได้สั่งซื้อ "ซาลาเปา" จาก Apple หรือ Samsung (ในที่นี้ Apple และ Sumsung ถือว่าเป็น Concrete Factory) โดยตรง แต่จะซื้อผ่าน 7-Eleven เท่านั้น จะเห็นได้ว่าในมุมมองของ Ronaldo นั้น เหมือนกับว่า 7-Eleven คือผู้ที่ผลิต "ซาลาเปา" แต่แท้ที่จริงแล้ว 7-Eleven อาจจะจ้างให้ Apple หรือ Samsung เป็นผู้ผลิตให้ก็ได้

สำหรับ Abstract Factory Pattern สามารถแสดงเป็น UML Diagram ได้ดังนี้ครับ

จากในภาพจะเห็นว่า ConcreteFactoryA และ ConcreteFactoryB ต่างก็ implement AbstractFactory interface ซึ่งตรงนี้ผมอยากจะเน้นว่า ในการใช้งานนั้น Client จะ interact กับ Abstract Factory แต่จะไม่ได้ interact กับ ConcreteFactory โดยตรง ซึ่งเป็นสิ่งที่สำคัญ เพราะจะทำให้เราสามารถเพิ่มหรือเปลี่ยนแปลง ConcreteFactory ในภายหลังได้นั่นเอง

สำหรับผู้ที่สนใจสามารถศึกษาเพิ่มเติมจาก Source Code  ที่ implement Abstract Factory Pattern ได้ที่นี่ครับ http://en.wikipedia.org/wiki/Abstract_factory_pattern

แหล่งที่่มา: http://en.wikipedia.org/wiki/Abstract_factory_pattern

Tuesday, 17 July 2012

Design Pattern - Builder Pattern



เมื่อ พูดถึง Builder Pattern หลายๆคนอาจจะงงๆว่ามันคืออะไร จริงๆแล้ว Builder Pattern มันอยู่ในชีวิตประจำวันของเรานี่เอง มันอยู่ในข้าวผัดกระเพราไก่ครับ เดี๋ยวผมจะเล่าให้ฟังว่ามันไปอยู่ในข้าวผัดกระเพราไก่ได้ยังไง

ก่อนอื่นมาพูดถึงทฤษฎีกันก่อนแล้วกันนะครับ สำหรับ Builder เป็นหนึ่งใน Design Pattern ที่อยู่ในกลุ่มของ Creation Pattern มีหน้าที่ในการสร้าง Object แต่จะซับซ้อนกว่า Factory Method คือสำหรับ Factory Method เมื่อมีการเรียกใช้งาน ก็จะคืนค่ากลับมาในรูปแบบของ Single Object ที่เสร็จเรียบร้อย พร้อมที่จะนำไปใช้งาน แต่สำหรับ Builder Pattern นั้นจะใช้ในการสร้าง Object ที่มีความซับซ้อนมากกว่า โดยที่เราสามารถกำหนดการสร้าง Object ทีละส่วนเองได้

ผม คิดว่าทุกคนน่าจะเคยสั่งข้าวผัดกระเพราเวลาไปร้านอาหารตามสั่ง เดี๋ยวเราจะมาดูว่า Builder Pattern กับข้าวผัดกระพราไก่มันเกี่ยวข้องกันอย่างไร ปกติเวลาที่เราสั่งข้าวผัดกระพรา บางคนก็จะใส่พริก ไม่ใส่พริก เอาไข่ดาว ไม่เอาไข่ดาว ซึ่งตอนที่ทางร้านเค้ากำลังเตรียมข้าวผัดกระเพราให้เรา เรารู้หรือไม่ว่า เค้ากำลังใช้ Builder Pattern อยู่

การ ใช้ Builder Pattern จะช่วยให้เราสามารถกำหนดวิธีในการสร้าง Object (ในที่นี่คือข้าวผัดกระเพราไก่นั่นเอง) โดยขั้นตอนในที่นี้ก็อาจจะเป็น ใส่พริก ใส่ไขดาว สำหรับ Object ที่ทำหน้าที่กำหนดการทำงานในขั้นตอนี้เราจะเรียกว่า Director (ซึ่งในที่นี่ก็คือคนที่จด Order ให้เรานั่นเอง) จากนั้น Director จะสั่งให้ Builder (ในที่นี้ก็คือแม่ครัวทำหน้าที่เตรียมข้าวผัดกระเพราให้เรานั่นเอง) ทำหน้าที่สร้าง Object ตามขั้นตอนที่กำหนดไว้ สังเกตุว่าการใช้ Builder Pattern จะทำให้เราสามารถที่จะสร้าง Object ที่มีความแตกต่างกันในรายละเอียด (บางคนใส่พริก ไม่ใส่พริก บางคนเอาไข่ดาว ไม่เอาไข่ดาว) ภาพที่จะแสดงต่อไปนี้เป็นภาพที่แสดงความสัมพันธ์ระหว่าง Client, Direcotr และ Builder (เนื่องจากผมไม่สามารถหาภาพตัวอย่างที่เป็น flow ของผัดกระเพราได้ จึงขอแสดงตัวอย่างเป็น Fast Food แทนแล้วกันนะครับ)



สำหรับ ภาพที่จะแสดงต่อไปนี้ เป็น UML Diagram ของ Builder Pattern ซึ่งแสดงความสัมพันธ์ระหว่างส่วนประกอบต่างๆใน Builder Pattern ซึ่งหลักๆก็คือ Concrete Class ที่ implement Builder interface และ Director ซึ่งจะเรียกใช้งาน Builder อีกที

Builder Pattern UML Diagram

จากใน UML Diagram เราจะเห็นว่า class BuilderType1 และ BuilderType2 มีการ implement interface ที่ชื่อว่า buildPart(), buildPart() และ getProduct() (เนื่องจาก inherit มาจาก Abstract Class ที่ชื่อว่า Builder อีกทีหนึ่ง) ส่วนต่อมาทางด้านซ้ายมือคือ class ที่มีชื่อว่า Director ซึ่งจะเรียกใช้งาน class ที่ implement Builder interface (ในที่นี้คือ BuilderType1 และ BuilderType2)

สัง เกตุว่าใน Builder Pattern นั้น class ที่ทำหน้าที่เป็น Builder นั้นจะรู้เพียงแค่วิธีการสร้างในแต่ละส่วน ของตนเองเท่านั้น แต่สำหรับขั้นตอนหรือวิธีการการสร้างจะเป็นหน้าที่ของ class ที่ทำหน้าที่เป็น Director เป็นผู้กำหนด การนำ Builder interface มาใช้ จะทำให้ class ที่ทำหน้าที่เป็น Director ไม่มีความเกี่ยวข้องกับ class ที่ทำหน้าที่เป็น Builder โดยตรง ซึ่งจะทำให้ Application ที่เราพัฒนามีความยืดหยุ่นสูง เนื่องจากเราสามารถสร้าง Builder เพิ่มขึ้นได้ในอนาคต ตราบใดที่เรายัง implement Builder interface ส่วน Client ที่ต้องการสร้าง Object จะไม่ติดต่อโดยตรงกับ Builder แต่จะสร้าง Object ผ่านทาง Director แทน

สำหรับผู้ที่สนใจ สามารถเข้าไปดู Source Code ตัวอย่าง สำหรับการ implement Builder Pattern ได้ที่นี่ครับ http://en.wikipedia.org/wiki/Builder_pattern



แหล่งที่มา: http://en.wikipedia.org/wiki/Builder_pattern

Design Pattern -Factory Pattern



การสร้าง Object โดยใช้ Factory Pattern เป็นการจำลองรูปแบบการสร้างสินค้าภายในโรงงาน คือ เวลาที่เราต้องการสินค้า เราก็จะสั่งให้โรงงานผลิต โรงงานก็จะทำหน้าที่ผลิตสินค้าให้โดยที่เราไม่ต้องสนใจว่าจะผลิตอย่างไร เช่นเดียวกัน Factory Method ก็จะทำหน้าที่สร้าง Object โดย abstract วิธีการสร้างไว้ภายใน

การนำ Factory Pattern มาใช้ในการสร้าง Object จะช่วยให้เราสามารถ Encapsulate ความซับซ้อนในกระบวนการสร้าง Object นอกจากนั้นยังเป็นการ abstract ในส่วนของการสร้าง Object โดยเราสามารถสร้าง Object ที่แตกต่างกันจาก Factory Method เดียวกัน เดี๋ยวลองมาดูตัวอย่างกันนะครับ


สำหรับตัวอย่างที่นำมาแสดงให้ดูนี้ เป็นตัวอย่างการสร้างผลไม้กระป๋อง (FruitCan) โดยภายใน class FruitCan จะบรรจุ class Fruit ไว้อีกที นอกจากนั้นยังมี factory method ที่ชื่อว่า build (ในที่นี่เราสร้างเป็นแบบ static) เอาไว้สำหรับสร้าง instance ของ FruitCan โดยที่เราสามารถส่งชื่อ class ของผลไม้ที่เราต้องการจะสร้าง (ในที่นี้คือ Mango และ Lemon) เข้าไปได้

ให้สังเกตุว่าเราสร้าง instance ของ FruitCan โดยผ่าน factory method ที่ชื่อว่า build ซึ่งจะ wrap กระบวนการสร้าง FruitCan เอาไว้ภายใน นอกจากนั้นเรายังออกแบบให้ build รับ parameter ที่เป็นชื่อ class ของผลไม้ เพื่อที่ว่าเราจะสามารถสร้าง FruitCan จากผลไม้ชนิดอื่นๆ (โดยการสร้าง class ของผลไม้เพิ่มเติมได้ในภายหลัง) ได้ในอนาคต

แหล่งที่มา: http://en.wikipedia.org/wiki/Factory_method_pattern

Friday, 13 July 2012

Design Pattern - Mediator Pattern


Mediator Pattern

ในการพัฒนา Application ที่มี Object จำนวนมาก การเขียน Code เพื่อ interact ระหว่าง Object ก็จะมีความซับซ้อนมากขึ้น ซึ่งเราสามารถลดความซับซ้อนดังกล่าวลงได้ โดยการใช้ Mediator Pattern

Mediator Pattern มีวัตถุประสงค์เพื่อลดการ interact กันโดยตรงระหว่าง Object โดยย้าย Code ในส่วนของการ interact ที่เกิดขึ้นไปไว้ใน Mediator Object แทน สำหรับเวลาที่ Object ต้องการ interact ระหว่างกัน จะทำผ่าน Mediator Object แทน ซึ่งจะช่วยลด dependency ระหว่าง Object ลง

สำหรับตัวอย่างต่อไปนี้ เป็นการใช้งาน Mediator Object ในการควบคุมสถานะของ Button 3 อัน ได้แก่ BtnView, BtnSearch และ BtnBook

Code ในส่วนของ Mediator Object

Code ในส่วนของ Button

จาก Code ตัวอย่างข้างต้น จะเห็นได้ว่า Code ในส่วนที่มีการ interact กัน ถูกย้ายไปไว้ใน Mediator Object ซึ่งจะช่วยให้เราสามารถ Maintain ได้ง่ายขึ้นครับ

แหล่งที่มา: http://en.wikipedia.org/wiki/Mediator_pattern

Wednesday, 11 July 2012

Design Pattern - Facade Pattern

สำหรับ Pattern อันนี้ ผมคิดว่าน่าจะเป็น Pattern ที่เข้าใจง่ายที่สุดในบรรดา Design Pattern ตัวอื่นๆ และผมเชื่อว่าหลายๆคนอาจจะเคยใช้อยู่แล้ว เพียงแต่ไม่รู้ว่ามันมีชื่อว่า Facade Pattern คำว่า Facade เป็นศัพท์ทางสถาปัตยกรรมมีที่มาจากภาษาฝรั่งเศส แปลว่า ด้านหน้าของอาคาร ซึ่งโดยปกติด้านหน้าของอาคารที่เราเห็นทั่วไป มักจะได้รับการตกแต่งเป็นกรณีพิเศษเพื่อให้ดูสวยงาม น่ามอง ซึ่งเป็นที่มาของ Facade Pattern นั่นเอง 

Facade of Saint Peter's basilica in Vatican City
Facade Pattern เป็นเทคนิคการออกแบบที่่มีวัตถุประสงค์เพื่อลดความ Complex ของการเขียน Program ลง โดยการนำ Code ที่การเรียกใช้งานอาจประกอบด้วยหลายขั้นตอน มา Wrap ไว้ใน Object ใหม่ ที่่อาจเรียกใช้งานได้ง่ายขึ้น โดยจากการเรียกใช้งานหลายขั้นตอน พอ Wrap แล้วอาจเหลือเพียงขั้นตอนเดียว เป็นต้น เดี๋ยวลองดูภาพประกอบกันนะครับ


จากในภาพ Client1 และ Client2 เรียกใช้งาน doSomething() ผ่าน Facade Object แทนที่จะต้องสร้าง Class ขึ้นมาทีละ Class และเรียกใช้งานเอง ซึ่งค่อนข้างจะวุ่นวาย สังเกตุว่าการใช้ Facade Pattern จะช่วยทำให้ Code ที่เราเขียนสั้นลง เข้าใจได้ง่ายขึ้น อีกทั้งยังดูแลได้ง่ายขึ้นอีกด้วย ก็ลองเอาไปประยุกต์ใช้งานกันดูแล้วกันนะครับ

แหล่งที่มา: http://en.wikipedia.org/wiki/Facade_pattern

Design Pattern - Decorator Pattern

เมื่อเราต้องการแก้ไขหรือเปลี่ยนแปลงความสามารถของ Object เรามักจะใช้วิธี Subclass ซึ่ง กระบวนการดังกล่าวจะเกิดขึ้นในขณะที่เรา Compile (ซึ่งนั่นหมายความว่าเราต้องมี Source Code ถึงจะสามารถ Compile ได้) แต่ถ้าหากเราไม่มี Source Code แล้วเราจะทำอย่างไร ?

Decorator Pattern คือวิธีการออกแบบให้เราสามารถแก้ไขหรือเพิ่ม Object Functionality ในขณะ Run Time (ซึ่งหมายความว่า เราไม่จำเป็นต้องมี Source Code) เดี๋ยวเราจะลองดูว่ามีวิธีการอย่างไร ก่อนอื่นมาดู UML Diagram ของ Decorator กันก่อนแล้วกันนะครับ

Decorator Pattern UML

จากใน Diagram เราจะเห็นว่า Decorator เป็น Class ที่ inherit มาจาก Component และภายในยังมี Child Object ที่ inherit มาจาก Component อยู่ด้วย ส่วน ConcreateDecorator จะ inherit มาจาก Decorator อีกทีหนึ่ง

หลักการของ Decorator Pattern ก็คือ เราจะสร้าง Class ขึ้นมาใหม่ ซึ่ง implement interface เดียวกันกับ Class ที่เราจะทำการ Decorate (เพราะเราต้องการให้ Class ที่สร้างขึ้นมาใหม่ มีคุณสมบัติเหมือน Class เดิม)  ซึ่งเราจะทำการ Wrap Class ที่เราต้อง Decorate ไว้ภายใน ซึ่งจะทำให้เราแก้ไข method ได้ตามที่เราต้องการ ในขณะที่เรายังคงสามารถเรียกใช้งานความสามารถของ Class เดิมผ่านทาง Class ที่เราได้ทำการ Wrap เอาไว้ก่อนหน้า ถ้ายังไม่เข้าใจตอนนี้ไม่เป็นไร เดี๋ยวดู Source Code แล้วจะเข้าใจมากขึ้นครับ ตัวอย่างที่นำมาแสดงดังต่อไปนี้เป็นการแก้ไข method ที่ชื่อ getIngredients() ของ class SimpleCoffee โดยผ่าน Class ที่ทำหน้าที่เป็น Decorator ที่ชื่อว่า CoffeeDecorator

เราจะเริ่มจากการสร้าง SimpleCoffee class โดย implment Coffee interface ดังต่อไปนี้

Coffee Interface และ Simple Coffee Class

ขั้นตอนต่อไป เราจะสร้าง Abstract Class ชื่อว่า CoffeeDecorator ขึ้นมา โดย implement Coffee interface (เพราะเราต้องการให้ CoffeeDecorator มีคุณสมบัติเหมือนกับ SimpleCoffee) ส่วน Decorator ที่จะนำไปใช้งาน (Concrete Class) เราจะทำการ inherit จาก CoffeeDecorator อีกทีหนึ่ง จากตัวอย่างที่จะแสดงต่อไปนี้ เราจะสร้าง Decorator ขึ้นมา 3 ตัว คือ Milk, Whip และ Sprinkles ซึ่ง Decorator แต่ละตัวจะทำให้เกิดการเปลี่ยน ingredient และ cost


จากตัวอย่าง เราจะเห็นว่า ใน Class ที่ทำหน้าที่เป็น Decorator มีการเปลี่ยนแปลงความสามารถไปจากเดิม ในขณะเดียวกันก็ยังคงสามารถเรียกใช้ความสามารถเดิมผ่าน super.getIngredients() และ super.getCost() (ซึ่งจะไปเรียก getIngredients() และ getCost() ของ class ที่ implement Coffee Interface ที่เราได้ทำการ Wrap เอาไว้ก่อนหน้า)

ต่อไปเป็นตัวอย่างการเรียกใช้งาน Decorator จะสังเกตุว่า เราสามารถเรียกใช้งาน Decorator ในลักษณะ chain กันไปเรื่อยๆได้

ตัวอย่างการเรียกใช้งาน Decorator

สังเกตุว่าการใช้ Decorator มีความยืดหยุ่นมากกว่าการใช้ Subclass เพราะว่าเราสามารถเปลี่ยนแปลงความสามารถของ Class ในขณะ Run Time ทำให้เราสามารถเพิ่มความสามารถโดยพิจารณาจากเงื่อนไขอื่นๆได้ อีกทั้งเรายังสามารถเปลี่ยนลำดับของการเรียกใช้งาน Decorator ได้อย่างอิสระ หรือเลือกที่จะใช้หรือไม่ใช้ Decorator อันไหนก็ได้ ซึ่งการใช้ Subclass จะไม่สามารถทำได้ ถือว่าเป็น Design Pattern ตัวนึงที่ผมชอบ ยังไงก็ลองเอาไปประยุกต์ใช้งานกันดูแล้วกันนะครับ

แหล่งที่มา: http://en.wikipedia.org/wiki/Decorator_pattern

Design Pattern - Composite Pattern

เวลาที่เราออกแบบโครงสร้างในแบบ Tree Structure เรามักจะมองว่า Leaf Node กับ Branch Node มีการทำงานที่แตกต่างกัน ซึ่งจะทำให้การออกแบบมีความ Complex แต่ถ้าเรามองว่า Branch Node กับ Leaf Node ต่างก็มีการทำงานคล้ายกัน จะทำให้การออกแบบง่ายขึ้น สำหรับวันนี้ผมจะมาแนะนำให้รู้จักกับ Composite Pattern ที่่มักใช้ในการแก้ปัญหาในการออกแบบ Tree Structure ก่อนอื่นต้องดู UML ของ Composite Pattern ก่อน ดังภาพต่อไปนี้

Composite Pattern UML

จากในภาพจะเห็นว่า Leaf (Leaf Node) และ Composite (Branch Node) มีการ implement method ที่ชื่อว่า operation() เหมือนกัน เนื่องจากมีการ inherit มาจาก Parent เดียวกันก็คือ Component ในขณะเดียวกัน Composite ยังสามารถที่จะมี Child Object ที่ inherit มาจาก Component อยู่ภายในตัวเอง (ซึ่งจุดนี้เองที่ทำให้ Branch Node แตกต่างจาก Leaf Node แต่ยังคงคล้ายกัน เนื่องจากมี method ชื่อว่า operation() เหมือนกัน) สิ่งที่เพิ่มเข้ามาใน Composite (Branch Node) ก็คือ method สำหรับการทำงานกับ Child Object อย่างเช่น add(), remove() และ getChild()

Key Concept ของ Composite Pattern ก็คือ เราสามารถใช้งาน Single Object (Leaf) หรือ Group of Object (Branch) ได้ในแบบเดียวกัน ซึ่งจากในภาพ ก็คือเราสามารถ เรียก method ที่ชื่อว่า operation() ได้ทั้งจาก Leaf หรือ Composite (Branch Node) เดี๋ยวเราจะลองมาดู Source Code เพื่อจะได้เข้าใจมากขึ้น ซึ่ง Code ตัวอย่างที่จะแสดงดังต่อไปนี้ เป็นการ implement Graphic Class ในภาษา Java


  จาก Code ข้างต้น เราจะเห็นว่า เราสามารถเรียก print() ผ่าน CompositeGraphic ได้ ไม่แตกต่างจากการเรียกจาก Ellipse ซึ่งการเรียก print() ผ่าน CompositeGraphic มีผลทำให้ print() ที่อยู่ใน Child Object ถูกเรียก ดังนั้นถ้าหากเราต้องการเรียก print() ของทุกๆ Graphic Object แทนที่เราจะสั่งเรียกทีละตัว เราก็จะสามารถเรียกผ่าน CompositeGraphic แทนได้ ก็ลองเอาไปประยุกต์ใช้งานดูละกันนะครับ

แหล่งที่มา: http://en.wikipedia.org/wiki/Composite_pattern


Saturday, 7 July 2012

Amplify.js - Publish and Subscribe messaging pattern in your front-end application



Amplify.js เป็น JavaScript Library ที่ช่วยในการนำ Publish และ Subscribe Pattern มาใช้งานสำหรับ Front-End Application โดยเตรียม 2 method ไว้ให้เรียกใช้งานได้แก่ amplify.publish และ amplify.subscribe ประโยชน์ของการนำ Publish และ Subscribe (หรือเรียกสั้นๆว่า PubSub) มาใช้ ก็คือจะเป็นการแบ่ง logic ในส่วนของการ Broadcast (Publish) และการ Listen (Subscribe) ออกจากกัน ซึ่งจะส่งผลทำให้การ reuse และ maintain สามารถทำได้ง่ายขึ้น

ตัวอย่างการใช้งาน Amplify.js

สำหรับผู้ที่สนใจ สามารถศึกษาการใช้งาน amplify.js ได้ที่นี่ครับ http://amplifyjs.com/api/pubsub/

แหล่งที่มา: http://amplifyjs.com/api/pubsub/

JavaScript Make It Better - Revealing Module Pattern

สำหรับเทคนิคต่อไปนี้ เป็นเทคนิคที่ใช้สำหรับการพัฒนา Module สำหรับให้ Application อื่นๆเรียกใช้งาน เป็น Design Pattern ตัวหนึ่งที่นิยมใช้ มีชื่อว่า Revealing Module Pattern ครับ หลักการที่สำคัญของเทคนิคนี้ก็คือ เราจะคืนค่า function ที่ต้องการให้เรียกใช้งานภายใน Module ออกมาในรูปแบบของ Object ดังตัวอย่างดังต่อไปนี้ครับ


 จากตัวอย่างข้างต้น จะสังเกตุว่ามีการใช้ (function(){}()) ซึ่งการใช้ () ต่อท้าย function จะเป็นการสั่งให้ function ทำการ execute โดยอัตโนมัติ หรือที่เรียกกันว่า SEAF (Self-Excecuting Anonymous Function) ทำให้เมื่อเราเรียก NS.App ก็เท่ากับเป็นการเรียกให้ function ทำงาน โดยที่จะคืนค่า object ที่ภายในประกอบด้วย function ที่สามารถเรียกใช้งานได้กลับคืนมานั่นเองครับ

สำหรับใครที่อยากศึกษาเพิ่มเติมเกี่ยวกับ Module Pattern ผมมีบทความที่อยากจะแนะนำครับ เป็นบทความที่่ชื่่อว่า JavaScript Module Pattern In Depth เขียนโดย Ben Cherry ครับ

แหล่งที่มา: http://net.tutsplus.com/tutorials/javascript-ajax/principles-of-maintainable-javascript/

Thursday, 14 June 2012

Adapter Pattern

Adapter Pattern คือ วิธีการออกแบบ Application ที่่จะสามารถรองรับต่อการเปลี่ยนแปลงในอนาคต ยกตัวอย่างเช่น Application ที่เราพัฒนา มีการเรียกใช้งาน Twitter API ต่อมาภายหลัง Twitter มีการเปลี่ยนวิธีการเรียก API เราจะทำอย่างไร ? ในกรณีนี้ เราจะนำ Adapter Pattern มาช่วยในการออกแบบ กล่าวคือ Application ของเราจะเรียกใช้งาน Twitter API ผ่านทาง Twitter Adapter แทนทีจะเรียกตรงไปที่ Twitter API ในกรณีที่ Twitter API มีการเปลี่ยนวิธีการเรียกใช้งาน เราก็จะสร้าง Twitter Adapter ขึ้นมาใหม่ แต่วิธีการเรียกใช้งาน Adapter ยังคงเหมือนเดิม

Singleton Pattern

เราจะใช้ Singleton Pattern สำหรับในกรณีที่เราต้องการสร้าง instance ของ Class เพียง instance เดียว ใน Application ไม่ว่าจะมีการเรียกใช้งานกี่ครั้งก็ตาม ยกตัวอย่างกรณีที่เรามักใช้ Singleton Pattern อย่างเช่น การสร้าง Database Connection

ตัวอย่างต่อไปนี้เป็นการ Implement Singleton Pattern ในภาษา Java


จาก Code จะสังเกตุว่ามีการประกาศ Constructor ให้เป็นชนิด Private เพราะเราไม่ต้องการให้สร้าง Instance ผ่านทาง Constructor แต่เราต้องการให้มีการสร้าง Instance ผ่านทาง Static Method ที่ชื่อว่า getInstance() แทน โดยภายใน Method นี้จะมีการ check ว่ามีการสร้าง instance ไว้แล้วหรือเปล่า ถ้าเคยสร้างไว้แล้ว ก็จะคืน instance เดิมกลับไปให้

สำหรับตัวอย่างดังต่อไปนี้ เป็นวิธีเรียกใช้งานในกรณีที่่เราต้องการสร้าง Instance ของ Class จะสังเกตุว่า เราจะเรียกใช้งานผ่าน Static Method ของ Class ที่มีชื่อว่า getInstance() แทน



แหล่งที่มา: http://bit.ly/Nyby90