Home : แนวความคิดเรื่องของ abstract factory pattern
Q10100 - INFO: แนวความคิดเรื่องของ abstract factory pattern

Summary

abstract factory จะใช้ในกรณีที่เราต้องการสร้าง object หลายชนิดที่มีความเกี่ยวเนื่องกัน โดยที่ผู้ใช้ code นั้นไม่ต้องรู้ว่ากำลังใช้คลาสตัวไหนในการสร้าง object เหล่านั้นขึ้นมา ข้อดีก็คือทำให้ผู้ใช้สามารถเลือกเปลี่ยนการใช้งานชุด object กลุ่มนึง ไปเป็นอีกชุดหนึ่งได้โดยง่าย เพียงแค่เปลี่ยนตัว factory ที่ใช้สร้าง object เหล่านั้นนั่นเอง

ถ้าใช้ตัวอย่างเกี่ยวกับรถในการยกตัวอย่าง ปัญหาของผู้ใช้ก็คือ ต้องการใช้รถหลายแบบ อย่างเช่น รถเก๋ง รถบรรทุก โดยรถเก๋งมีความสามารถที่จะ เร่งความเร็ว เบรค ส่วนรถบรรทุกสามารถ เร่งความเร็ว เบรค และบรรทุกของได้ คราวนี้ผู้ใช้ก็ต้องการใช้รถสองแบบนี้ แต่ไม่ต้องการยึดติดว่าจะใช้รถยี่ห้อไหน อาจจะใช้ toyoto ก็ได้ หรือจะใช้ honda ก็ได้ แต่มีข้อแม้ว่า ถ้าเลือกใช้ยี่ห้อให้ยี่ห้อหนึ่ง ก็ต้องเปลี่ยนใช้รถทั้งสองแบบให้เป็นยี่ห้อเดียวกันด้วย สมมุติว่าผู้ใช้เอารถสองแบบนี้ไปใช้กิจการของตัวเอง โดยมีสองแผนก ผู้ใช้ก็มีทางเลือกสองแบบคือ จะบอกพนักงานว่ามีรถให้ใช้ กับ บอกพนักงานว่ามีรถ toyota ให้ใช้ จะเห็นว่าแบบหลังนี่จะผูกติดกับยี่ห้อมากไป ถ้าเกิดเปลี่ยนยี่ห้อ ก็ต้องมาบอกพนักงานใหม่อีกว่า เปลี่ยนเป็น honda แล้วนะ ซึ่งลำบากยุ่งยาก วิธีงานที่สุดก็คือบอกว่ามีรถให้ใช้เฉย ๆ ทั้งหมดนี่ก็เป็นเหตุผลว่าทำไม เราถึงจำเป็นต้องใช้ abstract factory ในการแก้ปัญหา

คราวนี้มาดูว่า ถ้าเราเปลี่ยนแนวคิดข้างต้น มาเป็นเขียนเป็นจาวาบ้าง จะเป็นยังไง  abstract factory บอกไว้ว่า เราต้องมีหนึ่งโรงงานที่ไว้ใช้สร้างกลุ่มของ object ในที่นี้ก็คือโรงงานที่สามารถสร้างรถได้ทั้งสองแบบ สมมุตให้ชื่อว่า VehicleFactory เมื่อมีโรงงานแล้ว เราก็ต้องมีรถด้วย โดยสร้างเป็น abstract class ที่ชื่อว่า Car สำหรับรถเก๋ง และ Truck สำหรับรถบรรทุก ที่มีสร้างคลาสนี้ขึ้นมาก็เพื่อให้ผู้ใช้สามารถใช้รถทั้งสองแบบได้ โดยอ้างอิงเป็น Car และ Truck แทนการระบุคลาสจริง ๆ ที่ใช้สร้างรถเหล่านั้น ถ้าดูแผนผังคลาสจะเป็นดังนี้

{abstract}
Car {
  ไป();
   เร่งความเร็ว();
  เบรค();
}

{abstract}
Truck {
 ไป();
 เร่งความเร็ว();
 เบรค();
 บรรทุก();
}

{abstract}
VechcleFactory {
  สร้างรถเก๋ง();
  สร้างรถบรรทุก();

 static getInstance(); // เรียก method นี้เพื่อให้ได้ที่อยู่ของโรงงานมา แล้วจะได้สั่งสร้างรถได้
}

จะเห็นว่าทั้งสามคลาสเป็น abstract ก็จะใช้สร้าง object อะไรไม่ได้ เราก็ต้องมีคลาสที่ไม่ใช่ abstract คลาสด้วยเพื่อจะได้ทำงานได้ เนื่องจากรถมีอยู่สองยี่ห้อ toyota กับ honda แบบนี้เราก็ต้องมีโรงงานสองแห่ง คือ ToyotaFactory กับ HondaFactory โดยเป็นคลาสลูกของ VehicleFactory การที่เป็นคลาสลูกก็เพื่อที่จะกำหนดว่าทั้งสองโรงงานนี้ต้องสร้างรถได้ทั้งสองแบบคือรถเก๋งและรถบรรทุก

คราวนี้เวลาที่ผู้ใช้จะเลือกว่าจะใช้รถเก๋งกับรถบรรทุกยี่ห้อไหนดี ก็เลือกได้ง่าย ๆ โดยเลือกเอาว่าจะเลือกใช้โรงงานไหนในการสร้างรถเก๋งและรถบรรทุก วิธีการเลือกก็ทำโดยเลือกเอาว่าจะ new instance ของตัวโรงงานไหนขึ้นมา เวลาที่ผู้ใช้เรียก method getInstance()

ในส่วนของตัวโรงงานเอง ในแต่ล่ะแบบ ก็จะสร้าง object ของรถเก๋งและรถบรรทุกตามแบบของโรงงานตัวเอง คือ ToyotaFactory ก็จะสร้าง ToyotaCar และ ToyotaTruck ในขณะที่ HondaFatory ก็จะสร้าง HondaCar และ HondaTruck สังเกตุว่าโรงงานทั้งสองจะเป็นคนสร้าง object ตัวจริงที่ผู้ใช้สามารถนำไปใช้ได้ ถ้าดูแผนผังคลาสจะเป็นดังนี้

{abstract}
class Car{}
^^
||
||
|class ToyotaCar {}
class HondaCar{}

{abstract}
class Truck{}
^^
||
||
|class ToyotaTruck{}
class HondaTruck{}

{abstract}
class VehicleFactory
^^
||
||
|class ToyotaFactory{}
class HondaFactory{}

ถ้าดูการใช้งานจริง จะเป็นแบบนี้ ถ้าผู้ใช้ต้องการมีรถทั้งสองแบบไว้ใช้ ก็เรียก VehicleFactory.getInstance() เพื่อให้ได้โรงงานมา แล้ว เรียก สร้างรถเก๋ง() กับ สร้างรถบรรทุก() ก็จะได้ object ของ Car กับ Truck มา (ไม่ได้ระบุว่าเป็นยี่ห้ออะไรเลย)

VehicleFactory factory = VehicleFactory.getInstance();
Car car = factory.สร้างรถเก๋ง();
Truck truck = factory.สร้างรถบรรทุก();

เมื่อผู้ใช้มีรถทั้งสองแบบแล้วก็เอาไปให้พนักงานใช้ต่อได้ พนักงานไหนที่นี้ก็คือพวก code ส่วนอื่น ๆ หรือ method อื่นๆ ในโปรแกรมนั่นเอง อย่างเช่น

class MarketingDept {
 ไปหาลูกค้า(Car c) {
  c.ไป(บางเขน);
  c.เร่งความเร็ว();
 }
}

class TransportDept {
 ไปส่งของ(Truck t) {
  t.บรรทุก(ผลไม้);
  t.ไป(ตลาดไท);
  t.เร่งความเร็ว();
 }
}

จะเห็นว่าผู้ใช้แค่บอกกับคนอื่น ๆ ว่ามี Car กับ Truck ให้ใช้เท่านั้น โดยไม่ได้ระบุว่ายี่ห้อไหน (ถ้าระบุยี่ห้อจะต้องใช้เป็น ToyotaCar หรือ ToyotaTruck ไปเลย) ในเมื่อผู้ใช้ไม่ได้ระบุยี่ห้อ ก็สามารถเปลี่ยนยี่ห้อรถได้ง่าย ๆ แค่เปลี่ยนโรงงานที่สร้างเท่านั้นเอง  เมื่อมีการเปลี่ยนยี่ห้อ code ในส่วน MarketingDept กับ TransportDept ก็ทำงานได้เหมือนเดิม ไม่ต้องแก้อะไร

สรุป: abstract factory ช่วยให้ผู้ใช้สามารถสร้างกลุ่มของ object ที่เกี่ยวข้องกันขึ้นมาใช้ได้ โดยไม่ผูกติดว่ากำลังใช้คลาสตัวจริงอันไหนอยู่ ทำให้สามารถเปลี่ยนไปใช้กลุ่มของ object อีกกลุ่มหนึ่งที่ทำงานได้เหมือนกัน ได้โดยง่าย (ไม่ต้องแก้ code เยอะ แก้แค่บรรทัดเดียว)

 

Related Articles
No Related Articles Available.

Article Attachments
No Attachments Available.

Related External Links
No Related Links Available.
Help us improve this article...
What did you think of this article?

poor 
1
2
3
4
5
6
7
8
9
10

 excellent
Tell us why you rated the content this way. (optional)
 
Approved Comments...
No user comments available for this article.
Created on 8/26/2009 11:06 PM.
Last Modified on 8/26/2009 11:06 PM.
Last Modified by Administrator.
Skill Level: Intermediate.
Article has been viewed 1036 times.
Rated 0 out of 10 based on 0 votes.
Print Article
Email Article