[Algorithm] Abstract Factory Design Pattern

สวัสดีครับหลังจากที่ผมห่างหายไปนานไม่ได้เขียนบทความเลยเพราะงานยุ่งมาก วันนี้ว่างๆ ก็เลยมาเขียนเกี่ยวกับ Design Pattern ต่อโดยผมจะเขียนเรื่อง Abstract Factory ซึ่งอยู่ในโหมดของ creational pattern หลายๆ ซึ่งก็ตามเคยผมก็เอาเว็บต่างประเทศที่หน้าสนใจมาแปลให้ทุกคนอ่านกัน ก่อนอื่นเรามาทำความรู้จักกับ Pattern ตัวนี้ก่อนว่ามันคืออะไร

ที่นี้เรามาดูโครงส้รางของ Pattern ตัวนี้ซึ่งแสดงผ่าน UML Diagram
null

โดยถ้ามองจากภาพแล้วเราจะเห็นว่า Class ที่ใช้สร้างวัถตุจะเป็นการเอา interface (AbstractFactory) มาใช้งานและให้ Sub Class เข้ามา implement ( ConcreteFactory1 , ConcreteFactory2) เพื่อไปใช้งาน และสร้างวัตถุของตนเองขึ้นมาหากมีการเรียกใช้จากผุ้ใช้งาน ซึ่งผมจะไม่ขออธิบายว่าทำไมต้อง interface คาดว่าคงรู้กันอยู่แล้วในหลักการนี้ผมจึงขอข้ามไปสอนส่วนอื่นเลย

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

ตัวอย่างการนำไปใช้ก็คล้ายกับการเรียกใช้ AWT ของ java ซึ่งเป็นการเรียก UI พื้นฐานของ OS นั้นๆ ที่เรานำโปแกรม java ไปรันออกมาทำงาน ด้วยความสามารถของ Pattern มันคล้ายกับเราส้ราง Lib มาชุดนึงแล้วก็เลือกว่าจะทำงานแบบไหนตามแต่บริบทของการนำไปใช้นั้นแหละครับ 

สุดท้ายนี้เรามาดูโค้ดกันเลยครับ ซึ่งจะเป็นการจำลองแนวคิดการสร้าง UI Toolkit คล้่ายๆกับ AWT ครับ

ก่อนอื่นเราก็ทำสร้าง Interface Class ที่ชื่อว่า AbstractProduct

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//Our AbstractProduct
public interface Window
{

public void setTitle(String text);

public void repaint();
}
[/sourcecode]

จากนั้นก็มา implement interface ตามขั้นตอนของมันโดยจะจำลองว่าเป็นการสร้าง UI ของ Windows และ Mac

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//ConcreteProductA1
public class MSWindow implements Window
{
public void setTitle()
{
//MS Windows specific behaviour
}

public void repaint()
{
//MS Windows specific behaviour
}
}
[/sourcecode]

และก็ของ Mac

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//ConcreteProductA2
public class MacOSXWindow implements Window
{
public void setTitle()
{
//Mac OSX specific behaviour
}

public void repaint()
{
//Mac OSX specific behaviour
}
}
[/sourcecode]

ที่นี่เราก็ implement หมดละเราจะมาสร้าง Factory กันซึ่งขั่นตอนที่ผ่านเป็นแค่การสร้าง interface class ทั่วไปเท่านั้นนะครับยังไม่ได้เริ่มการทำ Abstract Factory

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//AbstractFactory
public interface AbstractWidgetFactory
{
public Window createWindow();
}
[/sourcecode]

จากนั้นเมื่อมี interface ก็ต้องมี implement เราก็สร้าง class สำหรับ UI จำลองขึ้นมาโดยที่เราจะไว้สร้างวัตถุจาก class ก่อนหน้านี้คือ ConcreteProducts(MSWindow, MacOSXWindow)

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//ConcreteFactory1
public class MsWindowsWidgetFactory
{
//create an MSWindow
public Window createWindow()
{
MSWindow window = new MSWindow();
return window;
}
}
[/sourcecode]

และก็ของ Mac

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//ConcreteFactory2
public class MacOSXWidgetFactory
{
//create a MacOSXWindow
public Window createWindow()
{
MacOSXWindow window = new MacOSXWindow();
return window;
}
}
[/sourcecode]

เราจะสร้างตัวเรียกใช้งาน WidgetFactory ที่ทำไปข้างบน

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//Client
public class GUIBuilder
{
public void buildWindow(AbstractWidgetFactory widgetFactory)
{
Window window = widgetFactory.createWindow();
window.setTitle(“New Window”);
}
}
[/sourcecode]

สุดท้ายก็สร้าง main() สำหรับรันโปรแกรมของเรา

[sourcecode language=”java” wraplines=”false” collapse=”false”]
public class Main{
public static void main(String[] args)
{
GUIBuilder builder = new GUIBuilder();
AbstractWidgetFactory widgetFactory = null;
//check what platform we’re on
if(Platform.currentPlatform()==”MACOSX”)
{
widgetFactory = new MacOSXWidgetFactory();
}
else
{
widgetFactory = new MsWindowsWidgetFactory();
}
builder.buildWindow(widgetFactory);
}
}
[/sourcecode]

เสร็จแล้วครับ Abstract Factory Design Pattern หวังว่าคงเข้าใจนะครับที่ผมสอนไป อาขขะแปลมั่วบ้างพอดีผมก็อังกฤายังไม่แข็งเท่าไรบวกกันตอนนี้ก็เกือบเช้าแล้วเบลอๆ นิดหน่อยถ้าหากไม่เข้าใจยังไงก็ถามมาได้หรือเข้าไปอ่านในอ้างอิงท้ายบทความนะครับ

อ้างอิง: java.dzone.comsourcemaking.comoodesign.com

Facebook Comments