วันนี้ 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 ไปกันเลย
public class MallardDuck extends Duck { public MallardDuck() { flyBehavior = new FlyWithWings(); quackBehavior = new Quack(); } public void display() { System.out.println(“I’m a model duck”); } }
- Client มา Set พฤติกรรมลงไปเอง มาลุยกันครับ
====================================================== /* CLASS */ public class MallardDuck extends Duck { public MallardDuck() { //DO Nothing } public void display() { System.out.println(“I’m a Mallard Duck”); } } ====================================================== /* CLIENT */ public class DuckSimulator { public static void main(String[] args) { //Client Do Anything Duck model = new MallardDuck(); model.setFlyBehavior(new FlyWithWings()); model.setFlyBehavior(new Quack()); } }
- ตอนลองสั่งให้บิน โดยแสดงให้เห็นถึง Delegation ถ้าสาย Dev ดู Code ดีกว่าครับ
====================================================== /* CLASS */ public abstract class Duck { FlyBehavior flyBehavior; //Some Code public void performFly() { flyBehavior.fly(); } } ====================================================== /* CLIENT */ public class DuckSimulator { public static void main(String[] args) { //Client Do Anything Duck model = new MallardDuck(); model.performFly(); } }
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.