[Algorithm]Factory Method Design Pattern

ในบทความนี้เราจะมาพูดถึงเรื่อง Factory Method Pattern  หรือบางครั่งเป็นที่รู้จักในชื่อ  Virtual Constructor ซึ่งอยู่ในโหมดของ creational pattern เป็นการแก้ปัญหาในการสร้าง Object วิธีนี้เป็นการเรียกใช้ subclass ซึ่งเป็น Class ที่มากจาก superclass โดยส่วนใหญ่แล้วจะเป็นการ Design เพื่อใช้ในการสร้าง Object สำหรับ Class และในการทำงานของ Factory Method Patterns ส่วนใหญ่มักจะใช้ร่วมกับ Template Method Patterns

หลักการทำงานของการ Design แบบนี้จะเหมือนกับโรงงานที่ผลิตสินค้า ซึ่งผลิตสินค้าได้เพียงชนิดเดียวเท่านั้น และมันจึึงไปเข้าหลัการของ Factory Method Pattern ตอนนี้ผมจะมาสอนวิธีการเขียนโดยที่ผมจะใช้ภาษา Java ในการยกตัวอย่างให้ดูเพราะมันง่ายและเข้าใจง่ายมากสำหรับการเรียน OOP 

Factory Method Pattern โดยส่วนใหญ่คนจะลงลืมเอาไปรวมกับ  Abstract Factory Pattern ซึ่งจะต่างกันตรงที่ Factory Method Pattern จะมี superclass เป็น Interface แต่ ใช้หลักการสืบทอด (inheritance) , สร้าง Object ชนิดเดียว แต่  The Abstract Factory Pattern นั้นจะเป็นการส้ราง Object เป็นกลุ่ม ๆ ซึ่งเกี่ยวข้องกัน , ให้ Interface สำหรับการส้รางกลุ่มของ Object และ  ใช้หลักการ object composition(Factory associate กับ connection, command)

จาก UML Class Diagram จะแสดงให้เห็นว่า Creator นั้นจะให้ Interface ในการสร้าง Object ซึ่งในทั่งหมดจากถูกสร้างขึ้นมาจาก Product เช่น ConcreteCreator และตัว Creator หากจากจะสร้างผลิตภัณฑ์นั้นจะต้องผ่าน Subclass อย่าง  ConcreteCreator เท่านั้นไม่สามารถสร้างเองได้ด้วยตัวเอง ยกตัวอย่างเช่นพนักงานโรงงานจะทำสินค้าโดยไม่ผ่านเครื่องจักไม่ได้ เพราะเขาไม่สามารถทำสินค้าได้ด้วยมือตัวเองครับ 

ที่นี่เรามาดูเพื่อให้เห็นกระบวนการทำงานแบบชัดๆ จาก UML Sequence Diagram

เมือมีลูกค้าต้องการสินค้าตัว Creator ก็ตะทำการเรียกไป ConcreteProduct คำร้างก็จะส่งจาก factorMethod() และก็จะนำคำสั่งไป ConcreteProduct และเลือกว่าสิ่งที่ส่งมานั้นคืออะไรและดำเนินการตามขั่นตอน จากนั้นส่ง Object นั้นออกมาให้

ที่นี่เรามาดูกันว่าจะเขียนโค้ดกันยังไง

สร้าง Class Interface ขึ้นมาโดยจะใช้เรื่องของ Logger เข้ามาช่วนในเรื่องการสร้างสินค้า

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//interface (Product)
public interface Logger {
public void log(String message);
}[/sourcecode]

implement ตัว Interface ของเราสร้าง Class ชื่อ XMLLogger

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//concrete implementation of the Logger (Product)
public class XMLLogger implements Logger {
public void log(String message) {
//log to xml
System.err.println(“logging”);
}
}
[/sourcecode]

จากนั้นเราจะมาสร้างตัว Creator โดยเราจะให้มันเป็น Abstract Class

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//the abstract Creator
public abstract class AbstractLoggerCreator{
//the factory method
public abstract Logger createLogger();

//the operations that are implemented for all LoggerCreators
//like anOperation() in our diagram
public Logger getLogger(){
//depending on the subclass, we’ll get a particular logger.
Logger logger = createLogger();

//could do other operations on the logger here
return logger;
}
}
[/sourcecode]

สร้าง ConcreteCreator ขึ้นมาให้เหมือนกับ Class Diagram

[sourcecode language=”java” wraplines=”false” collapse=”false”]
//ConcreteCreator
public class XMLLoggerCreator extends AbstractLoggerCreator{
@Override
public Logger createLogger() {
XMLLogger logger = new XMLLogger();
return logger;
}
}
[/sourcecode]

สุดท้ายก็สร้าง Class สำหรับเรียกใช้งานขึ้นมาซึ่ง Client จะเป็นคนเรียกใช้

[sourcecode language=”java” wraplines=”false” collapse=”false”]
public class Client {
private void someMethodThatLogs(AbstractLoggerCreator logCreator){
Logger logger = logCreator.createLogger();
logger.log(“message”);
}
public static void main(String[] args){
//for the purposes of this example, create an XMLLoggerCreator directly,
//but this would normally be passed to constructor for use.
AbstractLoggerCreator creator = new XMLLoggerCreator();

Client client = new Client();
client.someMethodThatLogs(creator);
}
}
[/sourcecode]

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

Credit: java.dzone.com , javarevisited.blogspot.com , sourcemaking.com , oodesign.com

Facebook Comments