อะไรคือความแตกต่างพื้นฐานระหว่างรูปแบบโรงงานและรูปแบบนามธรรม?
createThing()
) และบทคัดย่อจากโรงงานใช้การจัดองค์ประกอบ (โดยอ้อมเป็นแนวนอนเช่นgetFactory().createThing()
)
อะไรคือความแตกต่างพื้นฐานระหว่างรูปแบบโรงงานและรูปแบบนามธรรม?
createThing()
) และบทคัดย่อจากโรงงานใช้การจัดองค์ประกอบ (โดยอ้อมเป็นแนวนอนเช่นgetFactory().createThing()
)
คำตอบ:
ด้วยรูปแบบโรงงานคุณผลิตกรณีของการใช้งาน ( Apple
, Banana
, Cherry
ฯลฯ ) ของอินเตอร์เฟซที่โดยเฉพาะอย่างยิ่ง - IFruit
พูด
ด้วยรูปแบบบทคัดย่อจากโรงงานคุณให้วิธีการสำหรับทุกคนในการจัดหาโรงงานของตนเอง วิธีนี้ช่วยให้คลังสินค้าของคุณเป็นแบบใดแบบหนึ่งIFruitFactory
หรือแบบIJuiceFactory
โดยไม่ต้องให้คลังสินค้าของคุณรู้อะไรเกี่ยวกับผลไม้หรือน้ำผลไม้
IFruit
- มัน instantiates IFruit
สิ่งที่ดำเนินการ แน่นอนว่าไม่จำเป็นต้องสร้างอินสแตนซ์ของสิ่งต่าง ๆ ที่ใช้อินเทอร์เฟซเฉพาะ แต่อาจเป็นกลิ่นรหัสหากคุณมี Factory ที่สร้างสิ่งที่ไม่เกี่ยวข้องกันโดยสิ้นเชิง
แหล่งข้อมูลนี้นำมาจาก: http://java.dzone.com/news/intro-design-patterns-abstract
วิธีการของโรงงานบทคัดย่อจะดำเนินการตามวิธีการของโรงงาน ทั้งรูปแบบนามธรรมจากโรงงานและรูปแบบวิธีการของโรงงานจะแยกระบบไคลเอนต์ออกจากคลาสการใช้งานจริงผ่านประเภทนามธรรมและโรงงาน วิธีการจากโรงงานสร้างวัตถุผ่านการสืบทอดที่โรงงานนามธรรมสร้างวัตถุผ่านองค์ประกอบ
รูปแบบโรงงานนามธรรมประกอบด้วย AbstractFactory, ConcreteFactory, AbstractProduct, ConcreteProduct และลูกค้า
รูปแบบนามธรรมจากโรงงานสามารถนำมาใช้โดยใช้รูปแบบวิธีการโรงงานรูปแบบต้นแบบหรือรูปแบบซิงเกิล วัตถุ ConcreteFactory สามารถนำมาใช้เป็น Singleton เป็นเพียงหนึ่งอินสแตนซ์ของวัตถุ ConcreteFactory ที่จำเป็น
รูปแบบวิธีการจากโรงงานเป็นรูปแบบย่อของรูปแบบนามธรรมจากโรงงาน รูปแบบวิธีการของโรงงานมีหน้าที่รับผิดชอบในการสร้างผลิตภัณฑ์ที่เป็นของตระกูลเดียวกันในขณะที่รูปแบบนามธรรมจากโรงงานเกี่ยวข้องกับผลิตภัณฑ์หลายตระกูล
วิธีการโรงงานใช้อินเทอร์เฟซและคลาสนามธรรมเพื่อแยกไคลเอนต์จากคลาสตัวสร้างและผลิตภัณฑ์ที่เป็นผลลัพธ์ บทคัดย่อโรงงานมีเครื่องกำเนิดไฟฟ้าที่เป็นภาชนะบรรจุสำหรับวิธีการต่าง ๆ ของโรงงานพร้อมกับอินเทอร์เฟซ decoupling ไคลเอนต์จากเครื่องกำเนิดไฟฟ้าและผลิตภัณฑ์
ใช้รูปแบบวิธีการจากโรงงานเมื่อมีความต้องการที่จะแยกลูกค้าจากผลิตภัณฑ์เฉพาะที่ใช้ ใช้วิธีการจากโรงงานเพื่อบรรเทาความรับผิดชอบของลูกค้าในการสร้างและกำหนดค่าอินสแตนซ์ของผลิตภัณฑ์
ใช้รูปแบบ Abstract Factory เมื่อลูกค้าต้องแยกส่วนประกอบออกจากคลาสผลิตภัณฑ์ มีประโยชน์อย่างยิ่งสำหรับการกำหนดค่าและการปรับเปลี่ยนโปรแกรม รูปแบบ Abstract Factory ยังสามารถบังคับใช้ข้อ จำกัด เกี่ยวกับคลาสที่ต้องใช้กับผู้อื่น มันอาจจะเป็นงานมากที่จะสร้างโรงงานคอนกรีตใหม่
ข้อกำหนดนี้สำหรับดิสก์เพื่อเตรียมพาสต้าชนิดต่าง ๆ ในเครื่องทำพาสต้าคือ Abstract Factory และดิสก์เฉพาะแต่ละรายการเป็น Factory โรงงานทั้งหมด (เครื่องทำพาสต้า) สืบทอดคุณสมบัติจากโรงงานที่เป็นนามธรรม แต่ละดิสก์มีข้อมูลวิธีสร้างพาสต้าและผู้ผลิตพาสต้าไม่มี
อุปกรณ์ปั๊มที่สอดคล้องกับโรงงานนามธรรมเนื่องจากเป็นอินเตอร์เฟสสำหรับการดำเนินการที่สร้างวัตถุผลิตภัณฑ์นามธรรม แม่พิมพ์นั้นสอดคล้องกับโรงงานคอนกรีตในขณะที่พวกเขาสร้างผลิตภัณฑ์คอนกรีต หมวดชิ้นส่วนแต่ละชิ้น (ฮูด, ประตู ฯลฯ ) สอดคล้องกับผลิตภัณฑ์นามธรรม ชิ้นส่วนเฉพาะ (เช่นประตูด้านคนขับสำหรับ 99 คัมรี่) สอดคล้องกับผลิตภัณฑ์คอนกรีต
บริษัท ของเล่นสอดคล้องกับผู้สร้างเนื่องจากอาจใช้โรงงานเพื่อสร้างวัตถุผลิตภัณฑ์ แผนกของ บริษัท ของเล่นที่ผลิตของเล่นเฉพาะประเภท (ม้าหรือรถยนต์) สอดคล้องกับ ConcreteCreator
รูปแบบของโรงงาน: โรงงานผลิต IProduct-implementations
บทคัดย่อรูปแบบโรงงาน: โรงงาน - โรงงานผลิต IFactories ซึ่งจะผลิต IProducts :)
[อัพเดตตามความคิดเห็น]
สิ่งที่ฉันเขียนไว้ก่อนหน้านี้ไม่ถูกต้องตามWikipediaอย่างน้อย โรงงานนามธรรมเป็นเพียงส่วนต่อประสานจากโรงงาน ด้วยคุณสามารถเปลี่ยนโรงงานของคุณเป็นรันไทม์เพื่ออนุญาตโรงงานที่แตกต่างกันในบริบทที่แตกต่างกัน ตัวอย่างอาจเป็นโรงงานที่แตกต่างกันสำหรับระบบปฏิบัติการที่แตกต่างกันผู้ให้บริการ SQL มิดเดิลแวร์ไดรเวอร์เป็นต้น
จัดเตรียมส่วนต่อประสานสำหรับการสร้างตระกูลของวัตถุที่เกี่ยวข้องหรือวัตถุที่ต้องพึ่งพาโดยไม่ต้องระบุคลาสที่เป็นรูปธรรม
รูปแบบบทคัดย่อจากโรงงานมีความคล้ายคลึงกับรูปแบบวิธีการของโรงงาน ความแตกต่างอย่างหนึ่งระหว่างทั้งสองคือด้วยรูปแบบนามธรรมจากโรงงานชั้นเรียนได้มอบหมายความรับผิดชอบของการสร้างอินสแตนซ์ของวัตถุให้กับวัตถุอื่นผ่านการจัดองค์ประกอบในขณะที่รูปแบบวิธีการของโรงงานใช้การสืบทอดและอาศัยคลาสย่อยเพื่อจัดการ
ที่จริงแล้ววัตถุที่ได้รับการแต่งตั้งมักใช้วิธีการจากโรงงานเพื่อทำอินสแตนซ์!
รูปแบบของโรงงานเป็นตัวอย่างของรูปแบบการสร้างสรรค์
รูปแบบการสร้างนามธรรมกระบวนการ instantiation วัตถุ พวกเขาซ่อนวิธีการสร้างวัตถุและช่วยให้ระบบโดยรวมเป็นอิสระจากวิธีการสร้างและเขียนวัตถุ
รูปแบบการสร้างสรรค์ระดับมุ่งเน้นไปที่การใช้การสืบทอดเพื่อตัดสินใจวัตถุที่จะยกตัวอย่างวิธีโรงงาน
รูปแบบการสร้างวัตถุมุ่งเน้นไปที่การมอบหมายการสร้างอินสแตนซ์ไปยังวัตถุอื่นบทคัดย่อโรงงาน
อ้างอิง: Factory vs Abstract Factory
วิธีการจากโรงงาน:คุณมีโรงงานที่สร้างวัตถุที่ได้มาจากคลาสพื้นฐานเฉพาะ
บทคัดย่อจากโรงงาน:คุณมีโรงงานที่สร้างโรงงานอื่นและโรงงานเหล่านี้จะสร้างวัตถุที่ได้มาจากคลาสพื้นฐาน คุณทำเช่นนี้เพราะคุณมักจะไม่เพียงต้องการสร้างวัตถุเดียว (เช่นเดียวกับวิธีโรงงาน) แต่คุณต้องการสร้างคอลเลกชันของวัตถุที่เกี่ยวข้อง
Abstract factory เป็นอินเตอร์เฟสสำหรับการสร้างวัตถุที่เกี่ยวข้อง แต่วิธีโรงงานเป็นวิธีการ บทคัดย่อโรงงานจะดำเนินการโดยวิธีโรงงาน
ความแตกต่างพื้นฐาน:
โรงงาน:สร้างวัตถุโดยไม่ต้องเปิดเผยตรรกะการสร้างอินสแตนซ์ให้กับลูกค้า
วิธีการโรงงาน : กำหนดอินเทอร์เฟซสำหรับการสร้างวัตถุ แต่ให้คลาสย่อยตัดสินใจว่าคลาสใดจะสร้างอินสแตนซ์ เมธอด Factory อนุญาตให้คลาสเลื่อนการอินสแตนซ์ไปที่คลาสย่อย
โรงงานบทคัดย่อ : เป็นอินเทอร์เฟซสำหรับการสร้างตระกูลของวัตถุที่เกี่ยวข้องหรือขึ้นอยู่กับโดยไม่ต้องระบุคลาสที่เป็นรูปธรรม
AbstractFactoryรูปแบบใช้การจัดองค์ประกอบเพื่อมอบหมายความรับผิดชอบในการสร้างวัตถุไปยังคลาสอื่นในขณะที่รูปแบบวิธีการของโรงงานใช้การสืบทอดและอาศัยคลาสที่ได้รับหรือคลาสย่อยเพื่อสร้างวัตถุ
จาก บทความoodesign :
แผนภาพระดับโรงงาน :
ตัวอย่าง: StaticFactory
public class ShapeFactory {
//use getShape method to get object of type shape
public static Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
โรงงานแบบคงที่การใช้งาน FactoryMethod ตัวอย่างมีให้ในโพสต์นี้:
รูปแบบการออกแบบ: โรงงานกับวิธีการของโรงงานเทียบกับบทคัดย่อจากโรงงาน
ควรใช้เมื่อใด:ลูกค้าเพียงแค่ต้องการเรียนและไม่สนใจว่าการใช้งานที่เป็นรูปธรรมนั้นจะได้รับ
ควรใช้เมื่อใด:ไคลเอนต์ไม่ทราบว่าจะต้องมีคลาสรูปธรรมใดในการสร้างที่รันไทม์ แต่ต้องการรับคลาสที่จะทำงาน
บทคัดย่อแผนภาพระดับโรงงานจาก dzone
ควรใช้เมื่อใด:เมื่อใดเมื่อระบบของคุณต้องสร้างหลายตระกูลของผลิตภัณฑ์หรือคุณต้องการจัดหาไลบรารีของผลิตภัณฑ์โดยไม่ต้องเปิดเผยรายละเอียดการใช้งาน
ตัวอย่างซอร์สโค้ดในบทความด้านบนนั้นดีมากที่จะเข้าใจแนวคิดอย่างชัดเจน
คำถาม SE ที่เกี่ยวข้องพร้อมตัวอย่างรหัส:
รูปแบบโรงงาน จะใช้วิธีการจากโรงงานเมื่อใด
แตกต่าง:
บทความที่มีประโยชน์อื่น ๆ :
factory_methodจากการสร้างแหล่งที่มา
abstract_factoryจากแหล่งที่มาทำ
รูปแบบนามธรรมการออกแบบโรงงานจาก journaldev
ตัวอย่าง / สถานการณ์สำหรับ Abstract Factory
ฉันอาศัยอยู่ในสถานที่ที่ฝนตกในฤดูฝนหิมะในฤดูหนาวและมีแดดจัดในฤดูร้อน ฉันต้องการเสื้อผ้าประเภทต่าง ๆ เพื่อปกป้องตัวเองจากองค์ประกอบ เมื่อต้องการทำเช่นนั้นฉันไปที่ร้านใกล้บ้านของฉันและขอเสื้อผ้า / รายการเพื่อป้องกันตัวเอง ผู้ดูแลร้านให้ฉันรายการที่เหมาะสมตามสภาพแวดล้อมและความลึกของกระเป๋าของฉัน สินค้าที่เขาให้ฉันมีคุณภาพและระดับราคาเท่ากัน เนื่องจากเขาตระหนักถึงมาตรฐานของฉันมันง่ายสำหรับเขาที่จะทำ แต่เมื่อคนรวยจากฝั่งตรงข้ามมาด้วยข้อกำหนดเดียวกันเขาจะได้รับของมีราคาแพงและเป็นแบรนด์ สิ่งหนึ่งที่เห็นได้ชัดเจนคือสิ่งของทุกชิ้นที่เขามอบให้กับฉันเพื่อเสริมซึ่งกันและกันในด้านคุณภาพมาตรฐานและค่าใช้จ่าย หนึ่งสามารถพูดได้ว่าพวกเขาไปด้วยกัน เป็นกรณีเดียวกันกับรายการที่คนรวยคนนี้ได้รับ
ดังนั้นจากการดูสถานการณ์ข้างต้นตอนนี้ฉันขอขอบคุณประสิทธิภาพของผู้ดูแลร้าน ฉันสามารถแทนที่เจ้าของร้านนี้ด้วย Abstract Shop รายการที่เราได้รับด้วยรายการนามธรรมและฉันและอุดมไปด้วยลูกค้ามุมมอง ทั้งหมดที่เราต้องการคือผลิตภัณฑ์ / รายการที่เหมาะสมกับความต้องการของเรา
ตอนนี้ฉันสามารถเห็นตัวเองได้อย่างง่ายดายเมื่อพิจารณาจากร้านค้าออนไลน์ที่ให้บริการแก่ลูกค้าจำนวนมาก ลูกค้าแต่ละคนเป็นสมาชิกหนึ่งในสามกลุ่ม เมื่อผู้ใช้กลุ่มพรีเมี่ยมเปิดเว็บไซต์เขาจะได้รับ UI ที่ยอดเยี่ยมบานหน้าต่างโฆษณาที่ปรับแต่งได้สูงตัวเลือกเพิ่มเติมในเมนู ฯลฯ คุณสมบัติชุดเดียวกันนี้จะถูกนำเสนอให้กับผู้ใช้ระดับทอง แต่ฟังก์ชั่นในเมนูนั้นน้อยลง และ UI ที่น้อยลงเล็กน้อยของ UI สุดท้ายคือผู้ใช้ของฉันซึ่งเป็นผู้ใช้ 'กลุ่มฟรี' ฉันแค่รับใช้มากพอที่จะไม่โกรธเคือง UI เป็นขั้นต่ำเปล่าโฆษณามีวิธีออกติดตามมากดังนั้นฉันไม่ทราบว่ามีอะไรเข้ามาในที่สุดเมนูมีเพียงออกจากระบบ
ถ้าฉันมีโอกาสสร้างบางอย่างเช่นเว็บไซต์นี้ฉันจะพิจารณารูปแบบนามธรรมจากโรงงานแน่นอน
ผลิตภัณฑ์ที่เป็นนามธรรม: บานหน้าต่างโฆษณา, เมนู, จิตรกร UI
บทคัดย่อจากโรงงาน: ประสบการณ์ผู้ใช้เว็บสโตร์
เชื่อมโยงโรงงาน: ประสบการณ์ผู้ใช้ระดับพรีเมียมประสบการณ์ผู้ใช้ทองคำประสบการณ์ผู้ใช้ทั่วไป
หลายคนจะรู้สึกประหลาดใจบางที แต่คำถามนี้ไม่ถูกต้อง หากคุณได้ยินคำถามนี้ในระหว่างการสัมภาษณ์คุณต้องช่วยผู้สัมภาษณ์ให้เข้าใจว่าความสับสนนั้นอยู่ที่ไหน
เริ่มจากข้อเท็จจริงที่ว่าไม่มีรูปแบบที่เป็นรูปธรรมที่เรียกว่า "โรงงาน" มีรูปแบบที่เรียกว่า "Abstract Factory" และมีรูปแบบที่เรียกว่า "Factory Method"
ดังนั้น "โรงงาน" หมายความว่าอย่างไร ข้อใดข้อหนึ่งต่อไปนี้ (ทั้งหมดสามารถพิจารณาได้ว่าถูกต้องขึ้นอยู่กับขอบเขตของการอ้างอิง):
และน่าเสียดายที่หลายคนใช้ "โรงงาน" เพื่อแสดงว่าเป็นโรงงานประเภทอื่นที่สร้างโรงงานหรือโรงงาน (หรืออินเทอร์เฟซ) ตามทฤษฎีของพวกเขา:
ผลิตภัณฑ์ใช้ IProduct ซึ่งสร้างโดยโรงงานซึ่งใช้ IFactory ซึ่งสร้างโดย AbstractFactory
เพื่อให้เข้าใจว่าสิ่งนี้โง่แค่ไหนลองทำสมการของเราต่อไป:
AbstractFactory ดำเนินการ IAbstractFactory ซึ่งสร้างโดย ... AbstractAbstractFactory ???
ฉันหวังว่าคุณจะเห็นประเด็น อย่าสับสนและโปรดอย่าประดิษฐ์สิ่งที่ไม่มีเหตุผล
-
PS : โรงงานสำหรับผลิตภัณฑ์คือ AbstractFactory และโรงงานสำหรับโรงงานบทคัดย่อก็เป็นอีกตัวอย่างหนึ่งของ AbstractFactory เช่นกัน
//Abstract factory - Provides interface to create factory of related products
interface PizzaIngredientsFactory{
public Dough createDough(); //Will return you family of Dough
public Clam createClam(); //Will return you family of Clam
public Sauce createSauce(); //Will return you family of Sauce
}
class NYPizzaIngredientsFactory implements PizzaIngredientsFactory{
@Override
public Dough createDough(){
//create the concrete dough instance that NY uses
return doughInstance;
}
//override other methods
}
คำตอบอื่น ๆ มีคำจำกัดความของหนังสือตำราเรียนอยู่แล้ว ฉันคิดว่าฉันจะให้ตัวอย่างมันด้วย
ดังนั้นที่นี่PizzaIngredientsFactory
เป็นโรงงานนามธรรมเพราะมีวิธีการสร้างตระกูลของผลิตภัณฑ์ที่เกี่ยวข้อง
โปรดทราบว่าแต่ละวิธีในโรงงานนามธรรมเป็นวิธีโรงงานในตัวเอง เหมือนcreateDough()
อยู่ในตัวเองเป็นวิธีการที่โรงงานที่มีการใช้งานคอนกรีตจะให้ subclasses NYPizzaIngredientsFactory
เช่น ดังนั้นการใช้สถานที่ที่แตกต่างกันแต่ละแห่งสามารถสร้างอินสแตนซ์ของส่วนผสมที่เป็นรูปธรรมซึ่งเป็นของที่ตั้งของพวกเขาได้
แสดงตัวอย่างการใช้งานที่เป็นรูปธรรม
ในตัวอย่าง:
- createDough()
- ให้การใช้งานที่เป็นรูปธรรมสำหรับแป้ง นี่คือวิธีการของโรงงาน
จัดเตรียมส่วนต่อประสานเพื่อสร้างตระกูลของวัตถุที่เกี่ยวข้อง
ในตัวอย่าง:
- PizzaIngredientsFactory
เป็นโรงงานที่เป็นนามธรรมที่มันช่วยให้การสร้างชุดที่เกี่ยวข้องของวัตถุที่ชอบDough
, ,Clams
Sauce
สำหรับการสร้างวัตถุแต่ละตระกูลมันมีวิธีการจากโรงงาน
ตัวอย่างจากรูปแบบการออกแบบ Head First
ฉันมีบางจุดที่จะมีส่วนร่วมกับคำตอบของจอห์นดังนี้:
กับ "โรงงานวิธี" (เพราะเพียงแค่ "โรงงาน" ไม่ชัดเจน), คุณผลิตการใช้งาน ( Lemon
, Orange
ฯลฯ ) ของอินเตอร์เฟซที่โดยเฉพาะอย่างยิ่ง - IFruit
พูด CitricFruitFactory
โรงงานนี้อาจจะเรียกว่า
แต่ตอนนี้คุณต้องการสร้างผลไม้ชนิดอื่นที่ CitricFruitFactory ไม่สามารถสร้างได้ บางทีรหัสของCitricFruitFactory
จะไม่สมเหตุสมผลถ้าคุณสร้างStrawberry
ในนั้น (สตรอเบอร์รี่ไม่ได้เป็นผลไม้มะนาว!)
เพื่อให้คุณสามารถสร้างโรงงานใหม่ที่เรียกว่าRedFruitFactory
ที่ผลิตStrawberry
, Raspberry
ฯลฯ
เช่นเดียวกับ John Feminella กล่าวว่า:
"ด้วยรูปแบบนามธรรมจากโรงงานคุณสามารถสร้างการใช้งานอินเทอร์เฟซของโรงงานเฉพาะ - เช่นIFruitFactory
แต่ละคนรู้วิธีสร้างผลไม้ชนิดต่าง ๆ "
การใช้งานของที่IFruitFactory
มีCitricFruitFactory
และRedFruitFactory
!
แหล่งที่มาของฉัน: StackOverflow
, tutorialspoint.com
, และprogrammers.stackexchange.com
CodeProject.com
Factory Method
(เรียกอีกอย่างว่าFactory
) มีไว้สำหรับลูกค้าที่แยกกลุ่มInterface
การใช้งาน สำหรับตัวอย่างเรามีShape
อินเตอร์เฟสที่มีสองตัวCircle
และSquare
การใช้งาน เราได้กำหนดคลาสโรงงานด้วยวิธีโรงงานพร้อมพารามิเตอร์ดีเทอร์เนอร์เช่นType
และการใช้Shape
อินเทอร์เฟซใหม่ที่เกี่ยวข้อง
Abstract Factory
มีวิธีการที่โรงงานหลายแห่งหรืออินเตอร์เฟซที่โรงงานโดยการใช้งานหลายโรงงาน สำหรับตัวอย่างข้างต้นถัดไปเรามีColor
ส่วนต่อประสานที่มีสองตัวRed
และYellow
การใช้งาน เรามีกำหนดShapeColorFactory
อินเตอร์เฟซกับสองและRedCircleFactory
YellowSquareFactory
รหัสต่อไปนี้เพื่ออธิบายแนวคิดนี้:
interface ShapeColorFactory
{
public Shape getShape();
public Color getColor();
}
class RedCircleFactory implements ShapeColorFactory
{
@Override
public Shape getShape() {
return new Circle();
}
@Override
public Color getColor() {
return new Red();
}
}
class YellowSquareFactory implements ShapeColorFactory
{
@Override
public Shape getShape() {
return new Square();
}
@Override
public Color getColor() {
return new Yellow();
}
}
ที่นี่แตกต่างระหว่างและFactoryMethod
เพียงแค่ส่งคืนคลาสคอนกรีตของอินเทอร์เฟซ แต่คืนค่า กล่าวอีกนัยหนึ่งคือการรวมชุดของอินเตอร์เฟสที่ต่างกันAbstractFactory
Factory Method
Abstract Factory
factory of factory
Abstract Factory
ฉันหวังว่าคำอธิบายของฉันจะเป็นประโยชน์
ความแตกต่างที่สำคัญในโรงงานเหล่านั้นคือเมื่อคุณต้องการทำอะไรกับโรงงานและเมื่อคุณต้องการใช้
บางครั้งเมื่อคุณกำลังทำ IOC (การผกผันของการควบคุมเช่นการฉีดคอนสตรัคเตอร์) คุณรู้ว่าคุณสามารถสร้างวัตถุที่เป็นของแข็ง ดังที่กล่าวไว้ในตัวอย่างด้านบนของผลไม้ถ้าคุณพร้อมที่จะสร้างวัตถุผลไม้คุณสามารถใช้รูปแบบโรงงานที่เรียบง่ายรูปแบบโรงงาน
แต่หลายครั้งคุณไม่ต้องการที่จะสร้างวัตถุที่เป็นของแข็งพวกเขาจะมาในภายหลังในการไหลของโปรแกรม แต่การกำหนดค่าจะบอกให้คุณทราบถึงประเภทของโรงงานที่คุณต้องการใช้ตั้งแต่เริ่มต้นแทนที่จะสร้างวัตถุคุณสามารถส่งต่อโรงงานที่ได้รับจากคลาสโรงงานทั่วไปไปยังผู้สร้างใน IOC
ดังนั้นฉันคิดว่ามันยังเกี่ยวกับอายุการใช้งานและการสร้างวัตถุด้วย
ทั้งสองFactory Method
และAbstract Factory
ทำให้ลูกค้าแยกตัวออกจากประเภทคอนกรีต ทั้งสร้างวัตถุ แต่Factory
วิธีใช้มรดกในขณะที่Abstract Factory
ใช้องค์ประกอบ
Factory Method
คือการสืบทอดใน subclasses ในการสร้างวัตถุคอนกรีต (ผลิตภัณฑ์) ในขณะที่Abstract Factory
ให้อินเตอร์เฟซสำหรับการสร้างครอบครัวของผลิตภัณฑ์ที่เกี่ยวข้องและ subclass ของอินเตอร์เฟซเหล่านี้กำหนดวิธีการที่จะสร้างผลิตภัณฑ์ที่เกี่ยวข้อง
จากนั้นคลาสย่อยเหล่านี้เมื่ออินสแตนซ์ถูกส่งผ่านไปยังคลาสผลิตภัณฑ์ซึ่งใช้เป็นประเภทนามธรรม ผลิตภัณฑ์ที่เกี่ยวข้องในมักจะดำเนินการโดยใช้Abstract Factory
Factory Method
คำตอบที่ขยายจาก John Feminella:
Apple
, Banana
, Cherry
การดำเนินการFruitFactory
และที่มีวิธีการที่เรียกว่าCreate
ซึ่งเป็นผู้รับผิดชอบ แต่เพียงผู้เดียวในการสร้างแอปเปิ้ลหรือกล้วยหรือเชอร์รี่ คุณทำเสร็จแล้วด้วยFactory
วิธีการของคุณ
ตอนนี้คุณต้องการCreate
สลัดพิเศษจากผลไม้ของคุณและมีบทคัดย่อจากโรงงานของคุณ Abstract Factory รู้วิธีสร้างสลัดพิเศษของคุณจาก Apple, Banana และ Cherry
public class Apple implements Fruit, FruitFactory {
public Fruit Create() {
// Apple creation logic goes here
}
}
public class Banana implements Fruit, FruitFactory {
public Fruit Create() {
// Banana creation logic goes here
}
}
public class Cherry implements Fruit, FruitFactory {
public Fruit Create() {
// Cherry creation logic goes here
}
}
public class SpecialSalad implements Salad, SaladFactory {
public static Salad Create(FruitFactory[] fruits) {
// loop through the factory and create the fruits.
// then you're ready to cut and slice your fruits
// to create your special salad.
}
}
ตามคำจำกัดความเราสามารถลากความแตกต่างของสอง:
Factory: อินเตอร์เฟสใช้สำหรับสร้างวัตถุ แต่คลาสย่อยตัดสินใจว่าคลาสใดที่จะยกตัวอย่าง การสร้างวัตถุเสร็จสิ้นเมื่อจำเป็น
บทคัดย่อโรงงาน: บทคัดย่อรูปแบบโรงงานทำหน้าที่เป็นโรงงานระดับสูงที่สร้างโรงงานอื่น ในรูปแบบ Abstract Factory อินเตอร์เฟสมีหน้าที่สร้างชุดของวัตถุที่เกี่ยวข้องหรือวัตถุที่ต้องพึ่งพาโดยไม่ต้องระบุคลาสที่เป็นรูปธรรม
ดังนั้นในคำจำกัดความข้างต้นเราสามารถเน้นความแตกต่างเฉพาะ นั่นคือรูปแบบของโรงงานรับผิดชอบในการสร้างวัตถุและบทคัดย่อจากโรงงานมีหน้าที่สร้างชุดของวัตถุที่เกี่ยวข้อง เห็นได้ชัดทั้งผ่านอินเทอร์เฟซ
รูปแบบโรงงาน:
public interface IFactory{
void VehicleType(string n);
}
public class Scooter : IFactory{
public void VehicleType(string n){
Console.WriteLine("Vehicle type: " + n);
}
}
public class Bike : IFactory{
public void VehicleType(string n) {
Console.WriteLine("Vehicle type: " + n);
}
}
public interface IVehicleFactory{
IFactory GetVehicleType(string Vehicle);
}
public class ConcreteVehicleFactory : IVehicleFactory{
public IFactory GetVehicleType(string Vehicle){
switch (Vehicle){
case "Scooter":
return new Scooter();
case "Bike":
return new Bike();
default:
return new Scooter();
}
}
class Program{
static void Main(string[] args){
IVehicleFactory factory = new ConcreteVehicleFactory();
IFactory scooter = factory.GetVehicleType("Scooter");
scooter.VehicleType("Scooter");
IFactory bike = factory.GetVehicleType("Bike");
bike.VehicleType("Bike");
Console.ReadKey();
}
}
รูปแบบโรงงานนามธรรม:
interface IVehicleFactory{
IBike GetBike();
IScooter GetScooter();
}
class HondaFactory : IVehicleFactory{
public IBike GetBike(){
return new FZS();
}
public IScooter GetScooter(){
return new FZscooter();
}
}
class HeroFactory: IVehicleFactory{
public IBike GetBike(){
return new Pulsur();
}
public IScooter GetScooter(){
return new PulsurScooter();
}
}
interface IBike
{
string Name();
}
interface IScooter
{
string Name();
}
class FZS:IBike{
public string Name(){
return "FZS";
}
}
class Pulsur:IBike{
public string Name(){
return "Pulsur";
}
}
class FZscooter:IScooter {
public string Name(){
return "FZscooter";
}
}
class PulsurScooter:IScooter{
public string Name(){
return "PulsurScooter";
}
}
enum MANUFACTURERS
{
HONDA,
HERO
}
class VehicleTypeCheck{
IBike bike;
IScooter scooter;
IVehicleFactory factory;
MANUFACTURERS manu;
public VehicleTypeCheck(MANUFACTURERS m){
manu = m;
}
public void CheckProducts()
{
switch (manu){
case MANUFACTURERS.HONDA:
factory = new HondaFactory();
break;
case MANUFACTURERS.HERO:
factory = new HeroFactory();
break;
}
Console.WriteLine("Bike: " + factory.GetBike().Name() + "\nScooter: " + factory.GetScooter().Name());
}
}
class Program
{
static void Main(string[] args)
{
VehicleTypeCheck chk = new VehicleTypeCheck(MANUFACTURERS.HONDA);
chk.CheckProducts();
chk= new VehicleTypeCheck(MANUFACTURERS.HERO);
chk.CheckProducts();
Console.Read();
}
}
ตรวจสอบที่นี่: http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm ดูเหมือนว่าวิธี Factory ใช้คลาสเฉพาะ (ไม่ใช่นามธรรม) เป็นคลาสพื้นฐานในขณะที่ Abstract Factory ใช้คลาสนามธรรมสำหรับสิ่งนี้ นอกจากนี้หากใช้อินเทอร์เฟซแทนคลาสนามธรรมผลลัพธ์จะเป็นการใช้รูปแบบ Abstract Factory ที่แตกต่างกัน
: D
Abstract Factory เป็นเทมเพลตสำหรับสร้างอินเตอร์เฟสประเภทต่าง ๆ สมมติว่าคุณมีโครงการที่ต้องการให้คุณแยกวิเคราะห์ไฟล์ csv ประเภทต่างๆที่มีข้อมูลเฉพาะราคาราคาและรายการเช่นบางรายการมีข้อมูลเกี่ยวกับผลไม้อื่น ๆ เกี่ยวกับช็อคโกแลตแล้วหลังจากแยกวิเคราะห์คุณจำเป็นต้องอัปเดตข้อมูลนี้ในฐานข้อมูลที่เกี่ยวข้อง โรงงานนามธรรมหนึ่งที่ส่งคืนคุณตัวแยกวิเคราะห์และโรงงานตัวดัดแปลงแล้วโรงงานตัวแยกวิเคราะห์นี้สามารถคืนคุณวัตถุแยกวิเคราะห์ช็อคโกแลตผลไม้แยกวิเคราะห์วัตถุ ฯลฯ และในทำนองเดียวกันโรงงานปรับปรุงแก้ไขสามารถกลับวัตถุช็อคโกแลตปรับปรุงแก้ไขวัตถุผลไม้ดัดแปลง ฯลฯ
ฉันคิดว่าเราสามารถเข้าใจความแตกต่างระหว่างสองสิ่งนี้ด้วยการดูโค้ดตัวอย่าง Java8:
interface Something{}
interface OneWhoCanProvideSomething {
Something getSomething();
}
interface OneWhoCanProvideCreatorsOfSomething{
OneWhoCanProvideSomething getCreator();
}
public class AbstractFactoryExample {
public static void main(String[] args) {
//I need something
//Let's create one
Something something = new Something() {};
//Or ask someone (FACTORY pattern)
OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeA = () -> null;
OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeB = () -> null;
//Or ask someone who knows soemone who can create something (ABSTRACT FACTORY pattern)
OneWhoCanProvideCreatorsOfSomething oneWhoCanProvideCreatorsOfSomething = () -> null;
//Same thing, but you don't need to write you own interfaces
Supplier<Something> supplierOfSomething = () -> null;
Supplier<Supplier<Something>> supplierOfSupplier = () -> null;
}
}
ตอนนี้คำถามคือวิธีการสร้างที่คุณควรใช้และทำไม: วิธีแรก (ไม่มีรูปแบบเพียงแค่ตัวสร้างธรรมดา): การสร้างด้วยตัวเองไม่ใช่ความคิดที่ดีคุณต้องทำงานทั้งหมดและรหัสลูกค้าของคุณเชื่อมโยงกับ การดำเนินการเฉพาะ
วิธีที่สอง (ใช้รูปแบบจากโรงงาน): ให้ประโยชน์ที่คุณสามารถใช้งานได้ทุกประเภทซึ่งสามารถให้ประเภทที่แตกต่างกันของบางอย่างตามเงื่อนไขบางอย่าง (อาจพารามิเตอร์ผ่านไปยังวิธีการสร้าง)
วิธีที่สาม (ใช้รูปแบบบทคัดย่อจากโรงงาน): วิธีนี้ให้ความยืดหยุ่นมากกว่า คุณสามารถค้นหาผู้สร้างประเภทต่าง ๆ ตามเงื่อนไข (อาจผ่านพารามิเตอร์)
โปรดทราบว่าคุณสามารถหลีกหนีจากรูปแบบของโรงงานโดยรวมสองเงื่อนไขเข้าด้วยกัน (ซึ่งเพิ่มความซับซ้อนของรหัสและการมีเพศสัมพันธ์เล็กน้อย) ฉันคิดว่านั่นเป็นเหตุผลที่เราไม่ค่อยเห็นกรณีการใช้งานจริงของรูปแบบนามธรรมจากโรงงาน