[Design Pattern] Command Pattern in Depth

อันนี้น่าจะเป็น Paatern ที่ 4 ที่เขียนกันครับ

ทำไมต้องใช้ Command Pattern

  • ต้องการเชื่อมของหลายๆสิ่งเข้าด้วยกันได้ เช่น Remote กับเครื่องใช้ไฟฟ้า แต่ละอย่างในบ้าน เช่น หลอดไฟ, พัดลม หรือ ทีวี ที่มีลักษณะการทำงานคล้ายๆกัน เช่น เปิด(ON) หรือป ปิด(OFF) เป็นต้น แต่ไม่อยากให้มันผูกแน่นกันจนเกินไป
  • มาดูโจทย์ของเราดึงกว่า โดยผมรับ Requirement มาว่าให้ได้ออกแบบ Application ETradeStock อันนึงที่สามารถส่งคำสั่งไปที่ตลาดหุ้น SAT ซึ่งสำหรับ SAT มี API อยู่ 2 เจ้าครับ ได้แก่ DSC และ FWD
    • สิ่งที่ต้องการ คือ ทำอย่างไรก็ได้ให้ Application ของเรา สามารถส่งคำสั่งซื้อ-ขาย หลักทรัพย์ไปยังตลาดหุ้น SAT โดยที่ใช้ API ของ DSC และ FWD ได้ พร้อมทั้งรองรับการเพิ่ม API ได้ในอนาคตครับ

เมื่อไหร่ควรจะใช้

  • ต้องการสร้างสื่อกลางระหว่าง Control (คนสั่ง) กับ Receiver(คนทำตาม) แต่ไม่อยากให้ Controller รู้จักกับ Receiver มากนัก (อารมณ์เหมือนพวกแก๊งมาเฟีย ลูกน้องไม่รู้หรอกว่าใครสั่ง แต่ต้องทำตาม) สิ่งที่ต้องทำ คือ เพิ่มสื่อตรงกลางขั้นมา ซึ่งมัน คือ คำสั่ง (Command)
  • ต้องการเชื่อม Controller กับ Receiver แม้ว่าตัว Receiver ของแต่ละค่ายมันมี API เชื่อมต่างกันก็ตาม (ส่วนตัวมองว่าเป็น Special Case ของ Adapter Pattern นะ ตัว Command  == Adapter) เช่น
    • Event ระหว่าง Control ต่างๆ(คนสั่ง กับพวก Handler(คนทำตาม) มี่ Object Event มาเป็น Command
    • การเก็บ Log แม้ว่าจะเป็น Log ต่างๆค่ายกัน ถูกหุ้มด้วย Command แบบเดียวกัน
    • การ Implement ของ CallBack ในภาษากลุ่ม OOP
  • จากโจทย์ตัวอย่างของ Application ETradeStock มาแยกดีกว่าว่าแต่ละ Object เป็นอย่างไร
    • Control – ETradeStock
    • Receiver – DSCTradeService, FWDTradeService
    • Command – อันนี้ เป็นสิ่งที่ต้องเพิ่มครับ โดยระละเอียดดูได้จาหัวข้อถัดไปครับ

Pattern มันเป็นอย่างไร – Class Diagram

  • Template
  • Class Diagram จากโจทยฺ์ – ที่ผมแยกเป็น 2 แบบ เพราะ ถ้า Class Diagram จริงๆ บางทีอาจจะละตัว Invoker ไปเป็น Method ได้ครับ

มุมมองตอน Runtime – Object Diagram

  • Control >> Command >> Receiver

มุมมองลำดับการทำงาน – Sequence Diagram

  • แบบที่ใส่ตัว Invoker
  • แบบที่ไม่แสดงตัว Invoker

[Design Pattern] Decorator Pattern in Depth

ทำไมต้องใช้ Decorator Pattern

  • อยากเพิ่มความสามารถของ Object (Object ทำงานเหมือนเดิมนะ แต่ถูกเพิ่มความสามารถ)

เมื่อไหร่ควรจะใช้

  • ไม่อยากใช้คุณสมบัตินึงของ OOP-Inheritance มากเกินไป เพราะใช้ไปแล้ว ก็ต้อง Override ไปแก้ความสามารถที่ได้มาจาก Class แม่อีก หรือมี Class ลูก (Sub Class) ที่มากจนเกินไปครับ ซึ่งเจ้า Decorator มันมาช่วยตรงนี้ครับ ไม่ต้องแก้ แต่เราเพิ่ม (Wrap) ความสามารถใหม่ลงไป โดยที่ความสามารถเดิม ยังคงอยู่ ลดจำนวน Sub Class ลงได้
  • สนับสนุนแนวคิด Open -Close Principle ด้วย

    Open for Extension Closed for Modification

  • Note: ไม่บอกว่าห้ามใช้ Inheritance นะครับ ใช้ให้มันพอดี ^__^

Pattern มันเป็นอย่างไร – Class Diagram

  • Template
  • ตัวอย่าง

มุมมองตอน Runtime – Object Diagram

  • ลักษณะของ Object หลังถูก Create

มุมมองลำดับการทำงาน – Sequence Diagram

  • ตอนสร้าง Object
  • ตอนคำนวณราคา

Real World Example

  • Java.IO Class ไง มีการเพิ่มความสามารถจาก
    • FileInputStream
      • BufferedInputStream
        • UpperCaseInputStream – สร้างเอง
  • Code ของ Class UpperCaseInputStream เสริมความสามารถมาจาก FilterInputStream
  • มาดู Code กันดีว่า ว่าเพิ่มความสามารถอย่างไร ? – อ่าน TestFile ซึ่ง FileInputStream มันอ่านที่ได้ละ 1 byte / โดยให้อ่านมาเป็น Stream ที่ละ 8192 byte ใช้ BufferedInputStream ลด Operation ที่แสนหนักหน่วงไป และอ่านให้แปลงตัวอีกษรให้เป็นตัวพิมพ์ใหญ่ (UpperCase) จาก UpperCaseInputStream

[Design Pattern] Observer Pattern in Depth

คราวนี้มาเป็น Pattern ที่ 2 แล้วที่ผมเขียนในเรื่อง Design Pattern in Depth โดยตอนนี้ขอเขียนเกี่ยวกับ BNK48 แล้วกันครับ คามิโอชิน้องเณอปราง ^___^

ทำไมต้องใช้ Observer Pattern

  • ถ้า Design ด้านแนวคิดที่ว่า อยากรู้ให้มาถาม (Server) สิ่งที่เกิดขึ้น คือ Client ต้องคอยวิ่งมาถาม (Request) ตรวจสอบว่าข้อมูลที่ Server มัน Update ยัง … Update ยังงง
  • ถ้าเกิดข้อมูลที่ต้องกระจายเป็นข้อมูลของวง Girl Group อย่าง BNK48 กำหนดให้เป็น Class BNK48Data ซึ่งมีหน้าที่ (Operation)
    1. Method getMemberData() – ข้อมูลสมาชิก
    2. Method getVote() – ดูผลการโหวต
    3. Method BNKDataChange() – เอาไว้ Update Data ของกับหน้าจอของ User
  • แล้วถ้าต้องเพิ่ม Dashboard สรุป stat ที่งาน (มโนไปไกลเลยเรา 555)  คือ แก้ Code ใน Class BNK48VoteDataOld !!!!!!
  • มาดู Class Diagram แบบแรกกันครับ
  • !!!! เราทำอย่างไรให้ Class BNK48Data นั้น Clean ที่สุด แก้อะไรก็แล้วเพิ่มแล้ว ไม้ต้องไปสั่ง Update ให้ Client ด้วย ถ้ามีดูที่ Class BNKVoteDateOld Method BNK48DataChange() มันต้องไป Update Display ทั้ง 2 เอง ตาม Code ดังนี้

เมื่อไหร่ควรจะใช้

  • ตอนที่จำเป็นต้องกระจายข้อมูลเยอะให้กับผู้รับที่มีจำนวนเยอะมากๆ (ONE TO MANY) อาทิ และไม่อยากให้ Server รับภาระให้การ Push ข้อมูลไปที่ Client เมื่อมีการเปลี่ยนแปลง เช่น
    • ตลาดหุ้น ต้องการส่งการแจ้งเตือนของราคาตลาดที่เปลี่ยนแปลง ไปยังโปรแกรม Trade หุ้นที่ได้ลงะทะบียนไว้ (Subscribe)
    • วงไอดอล BNK48 ต้องการแจ้งเตือนข้อมูลการออก Event ในแต่ละวันให้กับเหล่าโอดะที่ติดตามอยู่
  • สิ่งที่ได้ –  ลด coupling ระหว่าง class เพราะไม่ต้องรู้ว่ามีตัว Observer ทั้งหมดกี่รูปแบบ

Pattern มันเป็นอย่างไร – Class Diagram

  • ใช้ Observer แล้วเป็นอย่างไร มาดูกัน ภาระของ Subject BNK48VoteData ลดลงไปครับ
  • ส่วนประกอบที่สำคัญกันบ้าง
    • Subject – แหล่งข่าว (ONE)
    • Observer – ผู้สังเกตุการณ์ (MANY)

มุมมองตอน Runtime – Object Diagram

  • อันนี้ไม่ขออธิบายเยอะครับ รูปมันบอกอยู่แล้ว

มุมมองลำดับการทำงาน – Sequence Diagram

  • ตอน Register Observer ถ้าดูจาก Code ด้านล่างเป็น Method registerObserver(Observer o)
  • ตอน Notify
  • ตอน Notify – อันนี้ใช้ Loop เพราะถ้าของจริง คงไม่มี Display แค่ 2 อันครับ ถ้าดูจาก Code ด้านล่างเป็น Method notifyObservers()

ปิดท้ายด้วย Source Code (อาจจะรันไม่ได้ Code เทพ No Complier 5555) เพื่อให้เห็นภาพรวมตาม Sequence Diagram

  • ส่วนของ Subject
  • ส่วนของ Observer

หมายเหตุ

  • ทำไปทำมา ไม่น่าตั้วชื่อ Class เป็น BNK48 เลย มันดูเฉพาะเจาะจงมาก น่าจะปรับเป็น Class MemberVoting แทน จะได้เอาไปใช้กับหลายๆกรณีที่คล้ายคลึงกันครับ

[Design Pattern] Strategy Pattern in Depth

วันนี้ Blog นี้มาเน้นทางสาย Pattern กันเยอะ เชื่อว่าหลายๆคน Copy & Paste Development มาใช้งาน แต่ก็ไม่รู้ว่า มัน คือ อะไรครับ โดย Pattern ที่ผมมาเขียนลง Blog ในวันนี้ คือ Strategy Pattern ซึ่งข้อมูลส่วนใหญ่ผมเอามาจากของ Head First นะครับ ตัวอย่างมันอธิบายได้ง่ายดีครับ

ทำไมต้องใช้ Strategy

  • ทุกปัญหามันไม่สามารถแก้ไขด้วยกับใช้เทคนิคเดิมของ OOP – Inheritance ได้ไง ? ตัวอย่าง เช่น นายเจมส์ได้รับหน้าที่ในการสร้าง Class ของ Duck (เป็ด)  โดยที่เป็ดแต่ละชนิดมีพฤติกรรมที่แตกต่างกับครับ โดยที่เรา Design ไว้ให้ใช้มีพฤติกรรมที่ Class แม่ แล้วให้ Class ลูกสืบทอด(Inheritance) ไปใช้ครับ
  • ซึ่งพอมีชนิดของเป็ดที่หลากหลายขึ้น ดันเกิดข้อขัดแย้งต้องมา Override แก้ไขพฤติกรรมมันซะงั้น จริงๆ มันควรทำอย่างนั้นเหรอ (ลูกดื้อ เปลี่ยนพฤติกรรมของแม่)
  • ในเมื่อ Inheritance (IS-A) มันไม่ Work ต้องเปลี่ยนมาเป็นการประกอบร่าง composition (HAS-A)

เมื่อไหร่ควรจะใช้

  • เมื่อต้องการเพิ่ม Maintainability – เลือกประกอบสิ่งที่สนใจได้ ตอน Runtime เช่น MullarDuck ตอนอายุน้อยกว่า 14 วัน ยังบินไม่ไม่ได้นะ แต่ถ้ามากกว่านั้น เราสามารถ Set ความสามารถบิน (FlyWithWings) เพิ่มเข้าไปได้
  • งานชิ้นเดียวกัน แต่มีวิธีการคิด (Algorithm/Behavior) ที่หลากหลาย เช่น
    • การจ่ายค่าโดยสารรถเมล์ ซึ่งแต่ละรุ่นมีวิธีคิดที่แแตกต่างกัน
    • การเดินหมากรุก ซึ่งหมากแต่ละตัวตอนเดิน กับการถูกกิน มันมีกฏที่แตกต่างกันไป
  • Keyword
    • Interface – เป็นสัญญาว่า เรารู้จักกันนะ
    • Delegation – สั่งงาน ใครคนอื่นททำต่อ เช่น
      • เดิม – Duck จัดการวิธีการบินเองหมด
      • ใหม่ – เพิ่มความสามารถ จาก Class FlyWithWings แล้วสั่งให้ Class FlyWithWings ไปจัดการต่อ

Pattern มันเป็นอย่างไร – Class Diagram

  • Duck เป็นผู้สั่งการ แต่ไม่ได้สั่งผ่าน Class โดยตรงนะ แต่ Duck รู้จักกันผ่าน Interface ตามเส้นสีแดงใน Class Diagram เลย
  • จาก Class Diagram แต่ละชิ้นคล้ายเป็นส่วนประกอบ (composition) ขึ้นมาแทน

มุมมองตอน Runtime – Object Diagram

  • Mallard Duck
  • Rubber Duck

มุมมองลำดับการทำงาน – Sequence Diagram

  • สร้างผ่าน Constructor มาดู Code เทียบกับ Sequence Diagram ไปกันเลย

  • Client มา Set พฤติกรรมลงไปเอง มาลุยกันครับ

  • ตอนลองสั่งให้บิน โดยแสดงให้เห็นถึง Delegation ถ้าสาย Dev ดู Code ดีกว่าครับ

[CodeMania100] Emergent Design with Code

ฺBlog  นี้สรุปมาจาก CodeMania 100 : Coding Defines Anything ลองดูแล้วมันน่าจะแยอะ เขียนแยกง่ายกว่า สำหรับเรื่องนี้เป็นเรื่อง Coding Defines Reality – Emergent Design with Code  โดยคุณ Varokas Panusuwan เข้าเรื่องเลยดีกว่า

หมายเหตุ: สรุปตามความเข้าใจของผม และอาจจะมีอารมณ์ร่วมแถม 5555

ย้อนไปถึงการ Design

  • ในการพัฒนา Software ถ้าไม่ลืมจากที่เรียนไปมันมีเรื่อง SDLC (Software Development Life Cycle) มันมีขั้นตอนรูปเลยครับ
  • มามองทุกจุดๆนึง Design เราออกแบบจากอะไร จากการมโน หรือจาก
    • Requirement
    • Desires Properties
  • เมื่อมองถึงการ Design ระบบที่ดีต้องการอะไรบ้าง
    • Available
    • Reliable
    • Performance
    • Maintainable
    • Reusable
    • Usable
  • จากอันที่แล้ว ถ้าถาม User ส่วนมากมักจะบอกว่าเอาหมด !!! แต่ความจริงมันไม่เป็นอย่างงั้น ทุกอย่างมี Trade off อยากให้ระบบ Performance ดี แต่มันอาจจะ Maintainable ยากกกก ให้มองถึงระบบ Stat ใน Game ไม่มีอะไรที่เก่งไปหมดทุกด้านครับ เราต้องเน้นเร็ว AGI สูง ค่า VIT ต้องลดลง

Design is very easy, Knowing what you want is very hard !!! 

Design with force

  • มาจากหนังสือของ Christopher Alexander ไม่ใช่คน IT แต่เป็นสถาปนิก
  • Contextual Force – ผมมองว่าเป็นแรงจากสภาพแวดล้อม เพื่อให้การ Design ออกมาไปในทางเดียวกัน (Feel the force – ทำไมเหมือนอารณ์พวกเจได วิถีแห่งหลัง) อาจจะมองว่าเป็น Requirement ก็ได้
    2016-11-06_234157
  • ถ้าดูจากตัวอย่างของ Speaker
    • พื้นที่แห่งนึง ถ้าเอาคนเดิมออกไป คนใหม่เข้ามา การออกแบบบ้านควรจะออกมาคล้ายกัน
    • Smart Phone ทำไมต้องเป็นสีเหลี่ยมหละ ออกมาหน้าตาคล้ายกัน
    • นาฟิกาข้อมือ ทำไมส่วนใหญ่ต้องทำเป็นวงกลม
    • ฝาท่อใน ตปท ทำไมต้องเป็นวงกลม – อันนี้พี่เค้าบอกว่าป้องกันฝามันหล่น ถ้าเป็นแบบอื่นสีเหลี่ยมผืนผ้า มันมีด้านที่จะลงไปในท่อได้
  • แต่ Contextual Force ถูกดัดแปลง ดัดไปตามเป็นตามสิ่งที่อยากได้แทน  มองว่าเป็นความผิดเพี้ยนของ Requirement จาก User หรือ SA ทำเอง
    2016-11-06_214727

    • Cassandra เป็น  key/value database เอามาทำงานของ RDBMS มันเหมาะเหรอ ?

Finding  the Pattern

  • Pattern is in the problem.
  • และ Don’t solve the problem, Discover the pattern

Emergent Design

  • ปรับแนวคิดจาก Create Solution ไปเป็น Discover Solution จนเจอ Pattern หรือเป็น design Pattern ที่เหมาะสมกันมัน

Discover Solution หาอย่างไร

  • ทาง Speaker มี 4 เทคนิค ดังนี้
    • Code Properties – พวกการดู Coupling, Cohesion, Line of Code, Depth of inheritance ไม่เหมาะสำหรับมือใหม่
    • Commonality Variability Analysis (CVA) – ผม Pattern ส่วนตัวทำไมไปนึกถึงพวก 80/20
    • Programming by Intention – มองภาพลงไปเป็น Top-Down ลงไปแต่ละขั้น
    • Tests/Testability – ในที่นี่น่าจะเป็น TDD (Test Driven Development)
  • *** เนื่องจากเวลาน้อย Speaker ลง Detail แค่ Commonality Variability Analysis กับ Programming by Intention ครับ

Commonality Variability Analysis (CVA)

  • Speaker บอกว่าเป็น Thesis จบปริญญาเอกเลยนะเรื่องนี้
  • ดึง Key ออกมาจากความต้อง ดังนี้
    • What is in common ? อะไรที่เหมือนกัน
    • What Varies ? – อะไรที่แตกต่างกัน
    • Under a certain of Context of Use – ใครเป็นคนเรียกใช้ ใช้งานยังไง
  • What is in common + What Varies = ดึง Domain หรือ Class ออกมา อะไรควรยกไปเป็นแม่ลูก จะเริ่มเห็นความสัมพันธ์ตรงนี้
  • Under a certain of Context of Use = เอามา Filter อะไรที่ไม่ใช้ออกไป
  • ตัวอย่าง รูปวงกลม กับ สีเหลี่ยม และ ปากกา กับ ดินสอต่างกันยังไง
  • มาสนใจที่ตัวอย่างปากกา กับ ดินสอ
    • ดึง Key ได้ภาพของ Strategy pattern มีการเปลี่ยนการทำงานตอน Runtime
      tempfileforshare_2016-11-06-22-51-24
    • มองเป็น Code
  • ต่อจากตัวอย่าง ปากกา กับ ดินสอ เอามา วาดรูป Shape – วงกลม สีเหลี่ยม เราก็ทำแบบเดิมครับ มาดูความสัมพันธ์ของมันกับตัวอย่างแรก

Programming by Intention

  • มองว่าเป็นหาหา Main Idea จาก Requirement และมองลึกลงไปในแต่ละชั้น Top >> Down ขุดหาความจริง
    • Conceptual
    • Specification
    • Implementation
  • ตัวอย่าง – Create a software for cashier and barista. A program accepts order from user.  Retrieve cost base on the order. A program shows the barista what to do.
    • Conceptual ระบบต้อง
      • A program accepts order from user.
      • Retrieve cost base on the order.
      • A program shows the barista what to do
    • Specification -ไปทำ CVA มาเกิดสิ่งที่ต้องดูเพิ่ม ขนาด ส่วนผสม Order
    • Implementation – ลง Code และ

  • ส่วนตัวมองว่า ถ้าภาษาไทยต้องติดความดีๆ มันกำกวมในตัวมันเอง ต่างจากภาษาอังกฤษ

When does design start / End ?

  • Requirement จบ หรือ มัน Design ตอน Code ด้วย ?
  • Design เป็นแค่ requirement ของ design ถัดไป มุมมองจะค่อยๆชัดเจนมากยิ่งขึ้น (Top-Down)

Design on Code

  • ทำได้ บางคนสามารถจินตนาการไว้ในหัว แต่ควรจะมี Note/Comment ไว้บ้างก็ดี โดย Speaker ก็ทำตัวอย่างของการ Encryption

Slide ของ Speaker

สำหรับวันนี้ได้ Idea ในการ Design เยอะเลย และรู้สึกว่าใช้ปากาของ Galaxy Tab A ได้เต็มที่ด้วย

 

Best Practices คำแนะนำที่เรียบง่าย แต่มีที่มาที่ล้ำลึก

Best Practices คำแนะนำที่เรียบง่าย แต่มีที่มาที่ล้ำลึก โดยเวลาที่เราเขียนโปรแกรม เราอาจจะโดนจำกัดการใช้ตัวแปร ให้เขียน Code ตามรูปแบบที่ SA กำหนดไว้ ต้องเขียน Code เป็นชั้นๆ อาทิ เช่น Presentor, Business Logic, Data Access และแต่ละชั้นต้องเชื่อมกันผ่าน Interface แต่ถ้าลองมาศึกษาลึกๆแล้ว

  • Best Practices ที่เราลองใช้อยู่อาจจะเป็น Design Pattern ก็ได้
  • เจ้า Design Pattern ที่เราใช้อยู่ประจำ อาจจะเป็นการทำให้เกิดขึ้น(Implement) จาก Design Principle
  • และ Design Principle พื้นฐานมันเกิดจาก Object Oriented Concept ด้วย

ทุกอย่างมีที่มาที่ไป แต่ถ้าจะลงลึกไป อธิบายผลี ผลเสียมันอาจจะต้องใช้เวลา มันก็เลยกลายเป็น Best Practices เรียบง่ายที่ ห่อหุ้ม(Encapsulate) ความซับซ้อนต่างๆเอาไว้ข้างในครับ ตัว Developer เองจะได้เวลาไปสนใจเรื่องอื่นมากขึ้น เช่น Business หรือ การ Test ครับ 😀

Design Principle กับ Design Pattern

ก่อนจะมาเข้าเรื่องที่ลึกลงไป ผมอยากแนะนำ 2 คำนี้ก่อนครับ
Principle

  • แปลเป็นไทย คือ “หลักการ”
  • แปลไทยเป็นไทย คือ สาระสำคัญที่ยึดถือเป็นแนวปฏิบัติ (ข้อมูลจากราชบัณฑิตยสถาน)

Pattern

  • แปลเป็นไทย คือ “รูปแบบ”
  • แปลไทยเป็นไทย คือ แบบ, แผน, ตัวอย่าง, ทำแบบ, แบบอย่างอันดี, เอาแบบอย่าง

กลับมาที่ Design Principle คือ หลักการออกแบบ Software โดยมีชุดแนวคิด หรือคำแนะนำ เพื่อป้องกันการออกแบบ Software ที่แย่ ที่ส่งผลทำให้มีการปรับแก้ไข (Customize) หรือ การดูแลรักษา (Maintenance) ยาก เช่น SOLID (หลักการพื้นฐาน 5 ข้อ ถูกคิดและเผยแพร่โดย Uncle Bob ครับ )

จากนั้นอีกคำ Design Pattern คือ รูปแบบการออกแบบที่ดี อ่านแล้วดูแปลก เปลี่ยนใหม่ดีกว่าเป็นแบบแผนที่ดี ที่สามารถใช้กับปัญหาทั่วไปได้ (Reusable Solution) เช่น Singleton (Pattern ช่วยจัดการจำนวน Object เพื่อให้ระบบงานมีระสิทธิภาพสูงสุด)

แถมให้อีกคำ เนื่องจากมี Design Pattern แล้ว ก็ต้องมี Anti-Pattern คู่กันครับ เจ้า Anti-Pattern ตรงข้าม Design Pattern คือ แบบแผนที่ไม่ดี แก้ปัญหาเฉพาะหน้าครับ มันเป็นการ Workaround ครับ ตัวอย่างที่คุ้นๆกัน น่าจะเป็น GodClass, GodMethod, Circular Dependency ครับ

ปูมาซะนาน ตอนแรกจะเขียน Blog เกี่ยวกับ IoC(Inversion of Control) แต่ศึกษาไป ศึกมาก็มาลงเอยที่ Blog นี้ครับ ฮ่าๆ