แบบแผนโรงงานนามธรรม

**แบบแผนโรงงานนามธรรม** () เป็นแบบแผนการออกแบบซอฟต์แวร์ที่ใช้วิธีการรวมกลุ่ม Factory ที่ไม่เกี่ยวข้องกันที่มีรูปแบบเดียวกันไว้ด้วยกัน ทำให้สามารถ Encapsulate กลุ่มของ Factory ที่ไม่เกี่ยวข้องกันที่มีรูปแบบเดียวกันไว้ด้วยกันโดยผู้ใช้จะเรียกใช้งาน Factory ผ่าน Abstract Interface ซึ่งจะทำหน้าที่สร้าง Object ที่เหมาะสมให้แก่ผู้ใช้ได้เองอัตโนมัติหรืออาจให้ผู้ใช้กำหนด Factory Object ที่ต้องการสร้างได้ด้วยตัวเอง ใน Abstract Factory Design Pattern นี้จะแยกรายละเอียดการ Implement ของ Object ออกจากการเรียกใช้

## วิธีการใช้
การสร้าง Abstract Factory จะต้องประกอบด้วยคุณสมบัติต่อไปนี้ก็คือ

**ในระดับ Abstract Factory (Abstract Class) **
* Abstract Factory เป็นตัวตัดสินใจว่าจะสร้าง Factory Object ใดขึ้นมาผ่าน Static Method ของ Abstract Factory (static method สามารถเรียกผ่าน Abstract Factory ได้)
* ในการเลือกว่าจะสร้าง Factory Object ใดขึ้นมาเราอาจใช้การอ่าน Configuration File หรือว่ากำหนดเองโดยผู้ใช้ หรืออาจจะตรวจดูสภาวะแวดล้อมของระบบ
* เมื่อสร้าง Factory Object แล้วจะใช้การ return ออกมาเป็น Pointer หรือ Object ID ของ Factory Object นั้นโดย type จะเป็นชนิด Abstract Factory นั้น ๆ
* ในการเรียกใช้เพื่อให้การเรียกใช้ไม่ขึ้นต่อความแตกต่างของ Factory Object ต่าง ๆ ที่ถูกสร้างขึ้นมาจะอนุญาตให้ผู้ใช้เรียกผ่านส่วนที่เป็น Abstract Interface เท่านั้น

**ในระดับ Factory Object (Concrete Class) **
* ชนิดของ Object ที่สร้างมาจะตัดสินใจที่ตัว Factory เอง
* Object ที่ Factory สร้างจะต้องเป็น Object ที่ Derive มาจาก Abstract Class ที่ผู้ใช้งานสามารถเรียกใช้ได้
* เมื่อ Factory Object สร้าง Object ภายใน Factory Object  จะ type ที่ return จะต้อง return ออกมาเป็น Abstract Class แม่ของ Object นั้น
* เช่นเดียวกับ Factory Object ที่ต้องเรียกผ่าน Abstract Interface ในการเรียก Object ที่สร้างโดย Factory ก็ต้องเรียกผ่านส่วนที่เป็น Abstract Interface ของ Object นั้นด้วย

## ข้อได้เปรียบ
เพราะว่า Abstract Factory Design Pattern ได้ใช้ประโยชน์ของ Information Hiding ทำให้ผู้ใช้ไม่ต้องสนใจเรื่องเลือก Factory Class ที่เหมาะสมด้วยตนเอง สิ่งที่ทำก็เพียงแค่เรียกใช้งานผ่าน Abstract Interface แล้ว Object ที่เหมาะสมก็จะถูกสร้างให้โดยอัตโนมัติ
เพิ่มความสามารถในการ Reuse เนื่องจาก Factory Class เป็น Concrete Class ที่ Derive มาจาก Abstract Factory Class ซึ่งในการเรียกใช้เราสามารถเรียกผ่าน Abstract Factory ได้ทันทีทำให้เมื่อเราต้องการที่จะเพิ่ม Factory ใหม่ลงไปสามารถทำได้โดยการสร้างคลาสใหม่ที่ Derive มาจาก Abstract Factory Class แล้ว Implement ใหม่ ซึ่งจะไม่ส่งผลต่อการเรียกใช้ของผู้ใช้ที่เรียกผ่าน Abstract Factory Class

## ข้อเสียเปรียบ
เช่นเดียวกันกับแบบแผนการออกแบบซอฟต์แวร์อื่น ๆ แบบแผนโรงงานนามธรรมมีรูปแบบการออกแบบที่ค่อนข้างซับซ้อน อาจเป็นการเพิ่มความซับซ้อนโดยไม่จำเป็น เป็นการเพิ่มความสะดวกในการ design แต่เพิ่มความซับซ้อนในการทำงานของคอมพิวเตอร์ทำให้แบบแผนโรงงานนามธรรมไม่เหมาะสำหรับงานที่ต้องการความเร็วสูง ๆ ในคอมพิวเตอร์ที่ทรัพยากรค่อนข้างจำกัด และแบบแผนโรงงานนามธรรมจะต้องทำงานเพิ่มในขั้นตอนแรก ๆ ของการออกแบบด้วย

## Class Diagram
ไฟล์:Abstract factory.svg

## ตัวอย่าง
### Java

```java
/*
 * GUIFactory example
 */
abstract class GUIFactory {
    public static GUIFactory getFactory () {
        int sys = readFromConfigFile ("OS_TYPE") ;
        if (sys == 0) {
            return new WinFactory () ;
        } else {
            return new OSXFactory () ;
        }
    }

    public abstract Button createButton () ;
}


class WinFactory extends GUIFactory {
    public Button createButton () {
        return new WinButton () ;
    }
}


class OSXFactory extends GUIFactory {
    public Button createButton () {
        return new OSXButton () ;
    }
}


 
abstract class Button {
    public abstract void paint () ;
}


class WinButton extends Button {
    public void paint () {
        System.out.println ("I'm a WinButton") ;
    }
}

 
class OSXButton extends Button {
    public void paint () {
        System.out.println ("I'm an OSXButton") ;
    }
}

 
public class Application{
    public static void main (String[] args) {
        GUIFactory factory = GUIFactory.getFactory () ;
        Button button = factory.createButton () ;
        button.paint () ;
    }
    // Output is either:
    //   "I'm a WinButton"
    // or:
    //   "I'm an OSXButton"
}
```


## อ้างอิง

หมวดหมู่:ซอฟต์แวร์