รูปแบบการออกแบบ: บทคัดย่อจากโรงงานเทียบกับวิธีการของโรงงาน


141

หมายเหตุ: คำถามอยู่ท้ายของโพสต์

ฉันได้อ่านกระทู้ StackOverflow อื่น ๆ เกี่ยวกับโรงงานบทคัดย่อ VS โรงงานวิธี ฉันเข้าใจเจตนาของแต่ละรูปแบบ อย่างไรก็ตามฉันไม่ชัดเจนในคำจำกัดความ

วิธีการจากโรงงานกำหนดอินเทอร์เฟซสำหรับการสร้างวัตถุ แต่ให้คลาสย่อยตัดสินใจว่าจะสร้างอินสแตนซ์ใด เมธอดจากโรงงานอนุญาตให้คลาสเลื่อนการอินสแตนซ์ไปที่คลาสย่อย

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

- John Feminella

โรงงานบทคัดย่อมีลักษณะคล้ายกันมากกับโรงงานวิธี ฉันวาดคลาส UML สองสามเพื่อแสดงจุดของฉัน

บันทึก:

  • แผนภาพนี้มาจากwww.yuml.comดังนั้นจึงไม่ได้เน้นอย่างสมบูรณ์แบบ แต่มันเป็นบริการฟรี :)
  • ไดอะแกรมอาจไม่สมบูรณ์แบบ ฉันยังคงเรียนรู้รูปแบบการออกแบบของGoF

วิธีการโรงงาน:

วิธีการโรงงาน

Abstract Factory (เฉพาะสมาชิก 1 คน):

Abstract Factory (เฉพาะสมาชิก 1 คน)

บทคัดย่อจากโรงงาน (มีสมาชิกเพิ่ม):

ข้อความแสดงแทน

คำถาม:

  1. หากAbstract Factoryมีผู้สร้างเพียงคนเดียวและหนึ่งผลิตภัณฑ์มันยังคงเป็นรูปแบบAbstract Factoryหรือไม่ (อินเทอร์เฟซสำหรับสร้าง familes)
  2. สามารถโรงงานวิธีสร้างคอนกรีตถูกสร้างขึ้นจากการเชื่อมต่อหรือไม่ก็จะต้องมีการออกจากชั้นเรียน? (คลาสเลื่อนการอินสแตนซ์ไปที่คลาสย่อย)
  3. หากโรงงานนามธรรมสามารถมีผู้สร้างเพียงคนเดียวและหนึ่งผลิตภัณฑ์ความแตกต่างเพียงอย่างเดียวระหว่างโรงงานนามธรรมและวิธีการโรงงานที่ผู้สร้างสำหรับอดีตคืออินเทอร์เฟซและผู้สร้างสำหรับหลังเป็นระดับหรือไม่

1
หมายเหตุ: เมื่อฉันอ้างถึงส่วนติดต่อฉันคิดมากขึ้นในแง่ของส่วนต่อประสาน Java (คลาสนามธรรมด้วยวิธีเสมือนจริงแบบนามธรรม) อย่าลังเลที่จะชี้แจงหากมีความแตกต่างระหว่าง Abstract Factory และ Method Factory ในภาษาต่าง ๆ

ความแตกต่างขั้นพื้นฐานที่นี่: stackoverflow.com/questions/1001767แม้ว่าจะไม่ได้เป็นเฉพาะที่คุณถาม ..
Nawfal

คำตอบ:


134

หวังว่านี่จะช่วยได้ มันอธิบายประเภทของโรงงานต่างๆ ฉันใช้รูปแบบการออกแบบ Head Firstเป็นข้อมูลอ้างอิง ฉันใช้yuml.meกับไดอะแกรม

โรงงานคงที่

เป็นคลาสที่มีวิธีการแบบคงที่กับผลิตภัณฑ์ประเภทย่อยต่างๆของผลิตภัณฑ์

โรงงานคงที่

โรงงานที่เรียบง่าย

เป็นคลาสที่สามารถผลิตสินค้าประเภทย่อยต่างๆ (ดีกว่าโรงงานแบบคงที่เมื่อมีการเพิ่มประเภทใหม่ระดับผลิตภัณฑ์พื้นฐานไม่จำเป็นต้องเปลี่ยนเฉพาะคลาสโรงงานแบบง่าย)

Simple Factoryt

วิธีการโรงงาน

มีวิธีการหนึ่งในการผลิตผลิตภัณฑ์ประเภทหนึ่งที่เกี่ยวข้องกับประเภทของมัน (ดีกว่า Simple Factory เนื่องจากประเภทถูกเลื่อนไปที่คลาสย่อย)

วิธีการโรงงาน

โรงงานบทคัดย่อ

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

โรงงานบทคัดย่อ

ตัวอย่างจาก. NET Framework

DbFactoriesProvider เป็น Simple Factory เนื่องจากไม่มีประเภทย่อย DbFactoryProvider เป็นโรงงานนามธรรมซึ่งสามารถสร้างวัตถุฐานข้อมูลต่าง ๆ ที่เกี่ยวข้องเช่นการเชื่อมต่อและวัตถุคำสั่ง

บทคัดย่อโรงงานจาก. NET Framework


ความแตกต่างระหว่างโรงงานคงที่และโรงงานที่เรียบง่ายอย่างแท้จริงว่าวิธีการ CreateProduct อยู่ในชั้นเรียนที่แตกต่างกัน?
Peter O'Callaghan

4
มันจะไม่ชัดเจนกว่านี้หากในกรณีของวิธีการของโรงงานมีเพียงProduct(เป็นนามธรรม) จากนั้นProduct1และProduct2ในฐานะบุตรชาย นั่นจะช่วยชี้ให้เห็นว่าวิธีการของโรงงานเป็นเพียงการสร้างหนึ่งผลิตภัณฑ์ในขณะที่ Abstract Factory นั้นมีวิธีการรวมกันเป็นครอบครัวมากหรือน้อย
lllllll

79

รูปแบบทั้งสองเกี่ยวข้องกันอย่างแน่นอน!

ความแตกต่างระหว่างรูปแบบโดยทั่วไปมีเจตนา

เจตนาของโรงงานวิธีคือ "กำหนดอินเตอร์เฟซสำหรับการสร้างวัตถุ แต่ให้ subclasses ตัดสินใจที่ระดับอินสแตนซ์. โรงงานวิธีช่วยให้ instantiation ชั้นเลื่อนไป subclasses."

เจตนาของโรงงานบทคัดย่อคือ "ให้อินเตอร์เฟซสำหรับการสร้างครอบครัวของวัตถุที่เกี่ยวข้องหรือขึ้นอยู่กับการเรียนโดยไม่ต้องระบุคอนกรีตของพวกเขา."

จากคำแถลงเจตนา (อ้างอิงจาก GoF) ฉันจะบอกว่าจริง ๆ แล้ววิธีการของโรงงานในบางแง่ก็คือ "เสื่อม" โรงงานบทคัดย่อกับครอบครัวหนึ่ง

พวกเขามักมีแนวโน้มที่จะแตกต่างกันในการดำเนินการเป็นโรงงานวิธีคือการจัดการที่ดีง่ายกว่าโรงงานบทคัดย่อ

พวกเขามีความเกี่ยวข้องในการดำเนินการอย่างไรก็ตาม ตามที่ระบุไว้ในหนังสือ GoF

AbstractFactory ประกาศอินเตอร์เฟสสำหรับการสร้างผลิตภัณฑ์เท่านั้น ขึ้นอยู่กับคลาสย่อยของ ConcreteProduct เพื่อสร้างมันขึ้นมา วิธีที่พบมากที่สุดในการทำเช่นนี้คือการกำหนดวิธีการจากโรงงานสำหรับแต่ละผลิตภัณฑ์

นี้วิกิพีเดีย c2นอกจากนี้ยังมีบางสนทนาที่น่าสนใจในหัวข้อนี้


7
ฉันเข้าใจทั้งความคิดเห็นและ downvote คุณสามารถทำอย่างละเอียด?
Don Roby

ดีคำตอบดูเหมือนว่าฉันวาทศิลป์ ... ไม่มีตัวอย่างจริง ๆ ... กว้างเกินไป ...
Novalis

14

ดูเหมือนว่ารายการคำถาม (ยอดเยี่ยม) ของ OP ได้ถูกข้ามไป คำตอบปัจจุบันเพียงเสนอคำจำกัดความ rehashed ดังนั้นฉันจะพยายามตอบคำถามต้นฉบับให้รัดกุม

  1. หากAbstract Factoryมีผู้สร้างเพียงคนเดียวและหนึ่งผลิตภัณฑ์มันยังคงเป็นรูปแบบAbstract Factoryหรือไม่ (อินเทอร์เฟซสำหรับสร้าง familes)

ไม่ โรงงานบทคัดย่อจะต้องสร้างผลิตภัณฑ์มากกว่าหนึ่งรายการเพื่อสร้าง "ตระกูลผลิตภัณฑ์ที่เกี่ยวข้อง" บัญญัติ GoF ตัวอย่างเช่นสร้างและScrollBar() Window()ข้อได้เปรียบ (และวัตถุประสงค์) คือ Abstract Factory สามารถบังคับใช้ชุดรูปแบบทั่วไปในผลิตภัณฑ์ที่หลากหลาย

  1. สามารถโรงงานวิธีสร้างคอนกรีตถูกสร้างขึ้นจากการเชื่อมต่อหรือไม่ก็จะต้องมีการออกจากชั้นเรียน? (คลาสเลื่อนการอินสแตนซ์ไปที่คลาสย่อย)

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

  1. หากโรงงานนามธรรมสามารถมีผู้สร้างเพียงคนเดียวและหนึ่งผลิตภัณฑ์ความแตกต่างเพียงอย่างเดียวระหว่างโรงงานนามธรรมและ วิธีการโรงงานที่ผู้สร้างสำหรับอดีตคืออินเทอร์เฟซและผู้สร้างสำหรับหลังเป็นระดับหรือไม่

คำถามนี้ไม่ถูกต้องอีกต่อไปแล้วทำตามคำตอบข้างต้น อย่างไรก็ตามหากคุณคิดว่ามีความแตกต่างเพียงอย่างเดียวระหว่าง Abstract Factory และ Factory Method คือจำนวนผลิตภัณฑ์ที่สร้างขึ้นให้พิจารณาว่าลูกค้าใช้รูปแบบเหล่านี้อย่างไร โดยทั่วไปโรงงานนามธรรมจะถูกส่งเข้าไปในไคลเอนต์และเรียกใช้ผ่านองค์ประกอบ / การมอบหมาย วิธีการจากโรงงานจะต้องได้รับการสืบทอด ดังนั้นมันจึงกลับมาเป็นองค์ประกอบเก่ากับการถกเถียงกันเรื่องมรดก

แต่คำตอบเหล่านี้ทำให้เกิดคำถามที่สี่!

  1. เนื่องจากอินเตอร์เฟซที่มีเพียงวิธีการหนึ่งไม่สามารถเป็นโรงงานวิธีใด ๆ มากกว่าที่จะสามารถโรงงานบทคัดย่อ ,เราทำในสิ่งที่เรียกว่าอินเตอร์เฟซ Creational มีเพียงวิธีการหนึ่ง?

หากวิธีการเป็นแบบคงที่ก็มักจะเรียกว่าโรงงานแบบคงที่ หากวิธีการที่ไม่คงที่ก็มักจะเรียกว่าง่ายโรงงาน ทั้งสองอย่างนี้เป็นรูปแบบ GoF แต่ในทางปฏิบัติแล้วพวกเขามักใช้กันอย่างแพร่หลาย!


1
เกี่ยวกับการจัดวางองค์ประกอบและการสืบทอดฉันมักจะสงสัยว่า: มันเป็นไปไม่ได้ที่จะทำการจัดวางองค์ประกอบด้วยรูปแบบวิธีการของโรงงานหรือไม่ สิ่งใดที่จะป้องกันไม่ให้โรงงานผลิตหรือฉีดคอนกรีตที่เหมาะสมเข้าสู่ลูกค้า หรือสิ่งนี้อยู่นอกขอบเขตของรูปแบบแล้ว
georaldc

1
@georaldc จาก GoF (หน้า 107) " วิธีการจากโรงงานช่วยให้การเลื่อนคลาสเป็นคลาสย่อยได้ " กล่าวอีกนัยหนึ่งวิธีการจากโรงงานใช้การสืบทอดตามนิยาม
jaco0646

4

ในความคิดของฉันแตกต่างกันเล็กน้อยระหว่างทั้งสองรูปแบบอยู่ในการบังคับใช้และเพื่อให้เป็นแล้วกล่าวว่าในเจตนา

เรามาสรุปคำนิยาม (ทั้งจาก Wikipedia)

โรงงานบทคัดย่อ

จัดเตรียมส่วนต่อประสานสำหรับการสร้างตระกูลของวัตถุที่เกี่ยวข้องหรือวัตถุที่ต้องพึ่งพาโดยไม่ต้องระบุคลาสที่เป็นรูปธรรม

วิธีการโรงงาน

กำหนดอินเตอร์เฟซสำหรับการสร้างวัตถุแต่ให้เรียนที่ใช้อินเตอร์เฟซตัดสินใจที่ระดับอินสแตนซ์ เมธอด Factory อนุญาตให้คลาสเลื่อนการอินสแตนซ์ไปที่คลาสย่อย

ทั้งสองรูปแบบอนุญาตให้แยกวัตถุผู้ใช้จากการสร้างอินสแตนซ์ที่ต้องการ (decoupling แบบรันไทม์) และนี่คือลักษณะทั่วไป ทั้งสองรูปแบบอนุญาตให้สร้างลำดับชั้นของโรงงานตามความต้องการเฉพาะและนี่เป็นอีกมุมมองทั่วไป

บทคัดย่อโรงงานอนุญาตให้สร้างอินสแตนซ์หลายประเภทที่แตกต่างกันในหนึ่งคลาสย่อยและเพื่อระบุพฤติกรรมการสร้างในคลาสย่อยที่แตกต่างกัน ตามปกติแล้ววิธีการจากโรงงานจะประกาศการสร้างวัตถุประเภทเดียวเท่านั้นที่สามารถระบุได้ตามกลไกการจัดกลุ่มย่อย นั่นคือความแตกต่าง

โดยสรุป สมมติว่าผลิตภัณฑ์เป็นตัวกำหนดซุปเปอร์คลาสของวัตถุสร้างและ ProductA และ ProductB เป็นคลาสย่อยที่แตกต่างกันสองคลาส ดังนั้นเมธอด Abstract Factory จะมีสองวิธีคือ createProductA () และ createProductB () ซึ่งจะถูกเจาะจง (ในแง่ของขั้นตอนการสร้าง) ในคลาสย่อยเฉพาะ: คลาสย่อยจากโรงงานจะกำหนดขั้นตอนการสร้างสำหรับคลาสที่กำหนดไว้สองคลาส ของวัตถุภายใต้การสร้าง

จากตัวอย่างข้างต้นวิธีการของโรงงานจะถูกนำไปปฏิบัติต่างกันโดยสรุปการสร้าง ProductA และ ProductB ในโรงงานจำนวนมาก (หนึ่งวิธีต่อโรงงาน) และความเชี่ยวชาญเพิ่มเติมของขั้นตอนการสร้างจะได้รับการมอบหมายให้เป็นลำดับชั้นตามที่สร้างขึ้น .


2

ถ้าฉันสร้างใจลอย(อ้างอิงผ่านทางอินเตอร์เฟซหรือชั้นฐานนามธรรม)โรงงานชั้นที่สร้างวัตถุที่มีเพียงหนึ่งวิธีในการสร้างวัตถุแล้วมันจะเป็นวิธีที่โรงงาน

หากใจลอยโรงงานมีมากกว่า 1 วิธีในการสร้างวัตถุแล้วมันจะเป็นโรงงานบทคัดย่อ

สมมติว่าฉันสร้างผู้จัดการที่จะจัดการกับความต้องการของวิธีการดำเนินการสำหรับตัวควบคุม MVC ถ้ามีวิธีหนึ่งให้บอกเพื่อสร้างวัตถุเครื่องยนต์ที่จะใช้ในการสร้างแบบจำลองการดูมันจะเป็นรูปแบบวิธีการจากโรงงาน ในทางกลับกันถ้ามันมีสองวิธี: วิธีหนึ่งในการสร้างเอ็นจิ้นโมเดลวิวและอีกอันเพื่อสร้างเอ็นจิ้นโมเดลแอ็คชั่น (หรืออะไรก็ตามที่คุณต้องการเรียกรูปแบบที่วิธีการกระทำนั้นบรรจุผู้บริโภค)

public ActionResult DoSomething(SpecificActionModel model)
{
    var actionModelEngine = manager.GetActionModelEngine<SpecificActionModel>();
    actionModelEngine.Execute(SpecificActionModelEnum.Value);

    var viewModelEngine = manager.GetViewModelEngine<SpecificViewModel>();
    return View(viewModelEngine.GetViewModel(SpecificViewModelEnum.Value);
}

1

แม้ว่าเป็นเวลาหลายปีแล้วที่ผู้คนจาก StackOverflow ตั้งคำถามเกี่ยวกับปัญหานี้ในโพสต์อื่น ๆ (ที่เก่าแก่ที่สุดไปถึงปี 2009) ฉันยังไม่สามารถหาคำตอบที่ฉันต้องการได้


ดังนั้นฉันจึงทำการค้นคว้าทางเว็บสองสามชั่วโมงทบทวนตัวอย่างและมาถึงข้อสรุปนี้ความแตกต่างที่สำคัญของ Abstract Factory จากวิธีการของโรงงานคือ

  • ความตั้งใจ: การเชื่อมโยงกันหรือ "รูปลักษณ์และความรู้สึก" : ความตั้งใจของบทคัดย่อจากโรงงานคือการจัดกลุ่มตระกูลของวัตถุที่มีสไตล์เดียวกัน (เช่นวิดเจ็ต UI รูปลักษณ์และความรู้สึกเดียวกันชิ้นส่วนรถยนต์สไตล์เดียวกันวัตถุจากระบบปฏิบัติการเดียวกัน เป็นต้น) ตัวอย่างจาก Abstract Factory กล่าวถึงวลีสำคัญ "รูปลักษณ์และความรู้สึก" ที่เหมือนกัน
  • วัตถุที่สร้างวัตถุกลุ่มที่ใหญ่กว่า : บทคัดย่อโรงงานสร้างตระกูลของวัตถุที่สร้างวัตถุกลุ่มที่ใหญ่กว่าไม่ใช่วัตถุชิ้นเดียว
  • เพิ่มสไตล์ใหม่ในภายหลัง : หากเรายังคงใช้วิธีการจากโรงงานและลองเพิ่มชุดรูปแบบใหม่ให้กับโครงสร้างพื้นฐานที่มีอยู่มันจะเจ็บปวด ด้วยโรงงานที่เป็นนามธรรมสิ่งที่เราต้องทำคือเพียงสร้างโรงงานคอนกรีตใหม่ที่ใช้คลาสโรงงานที่เป็นนามธรรม

ตัวอย่างเคาน์เตอร์จะเป็น

  • ชิ้นส่วนรถยนต์สำหรับรถสปอร์ตที่ใช้ในซีดาน ความไม่สอดคล้องกันนี้อาจนำไปสู่อุบัติเหตุ
  • ปุ่มสไตล์ Windows ในวิดเจ็ต OS GUI ที่แตกต่างกัน มันจะไม่ทำลายอะไรเลย แต่ทำให้ประสบการณ์การใช้งานของผู้ใช้งานลำบากสำหรับบางคนเช่นฉัน
  • ต่อมาเราพบว่าซอฟต์แวร์ของเราจำเป็นต้องทำงานในการอัพเกรดระบบปฏิบัติการครั้งต่อไปซึ่งต้องการชุดของระบบวัตถุที่เข้ากันได้ที่แตกต่างกันในขณะที่รักษาซอฟต์แวร์ที่เข้ากันได้ย้อนหลัง

ดังนั้นเมื่อกลุ่มวัตถุสุดท้ายควรมีสไตล์เดียวกันโดยไม่มีข้อยกเว้นของวัตถุและคุณต้องการซ่อนรายละเอียด "รักษาสไตล์เดียวกัน" ไว้เราควรใช้ Abstract Factory


0

เท่าที่ฉันเข้าใจความหมาย o คำจำกัดความจากโรงงานบทคัดย่อและคำจำกัดความวิธีการของโรงงานมีการนำมาใช้ครั้งแรกในบริบทแบบคงที่และให้วัตถุตามพารามิเตอร์อินพุต

อันที่สองใช้วัตถุที่สร้างขึ้นแล้ว (ตระกูล) ซึ่งใช้อินเตอร์เฟสวิธีการของโรงงาน จากนั้นวิธีการจากโรงงานจะสร้างอินสแตนซ์เฉพาะที่เกี่ยวข้องกับวัตถุดั้งเดิมไม่ว่าจะเป็นวัตถุใด

ดังนั้นสิ่งนี้มักจะนำไปสู่การใช้ทั้งสองรูปแบบเข้าด้วยกันโดยที่ในขั้นตอนแรกคุณจะสร้างวัตถุทั่วไปซึ่งอธิบายตระกูลของวัตถุที่เกี่ยวข้อง มันถูกเรียกโดยวิธีการคงที่วิธี getInstance ("ชื่อสกุลของฉัน") การใช้งานเมธอด getInstance ดังกล่าวจะตัดสินใจว่าจะสร้างอ็อบเจ็กต์ตระกูลใด

จากนั้นฉันเรียกใช้เมธอด createProduct () บนอ็อบเจ็กต์ตระกูลที่สร้างขึ้นใหม่และขึ้นอยู่กับอ็อบเจ็กต์ตระกูลผลิตภัณฑ์ใหม่จะถูกส่งคืน

ดูเหมือนว่ารูปแบบเหล่านี้ให้ความร่วมมือกับแต่ละคน

กล่าวอีกนัยหนึ่ง Abstract Factory จะเน้นที่ "WHAT" จะถูกสร้างขึ้นและวิธีการของโรงงาน "HOW" จะถูกสร้างขึ้น


0

สิ่งที่คุณต้องจำไว้ก็คือโรงงานนามธรรมเป็นโรงงานที่สามารถคืนโรงงานหลายแห่งได้ ดังนั้นหากคุณมี AnimalSpeciesFactory ก็สามารถคืนโรงงานเช่นนี้ได้:

Mamalfactory, BirdFactory, Fishfactory, ReptileFactory ตอนนี้คุณมีโรงงานหนึ่งแห่งจาก AnimalSpeciesFactory แล้วพวกเขาใช้รูปแบบโรงงานเพื่อสร้าง objexts เฉพาะ ตัวอย่างเช่นสมมติว่าคุณได้รับ ReptileFactory จาก AnimalFactory นี้จากนั้นคุณสามารถเสนอให้สร้างวัตถุสัตว์เลื้อยคลานเช่น: งูเต่าวัตถุจิ้งจก


0
/*
//Factory methods:

//1. Factory Method - Abstract Creator Class



#include <iostream>
#include <string.h>
using namespace std;

const std::string nineNintyCC = std::string("990CC");
const std::string thousandTwoHundredCC = std::string("1200CC");
const std::string ThousandFiveHundredCC = std::string("1500CC");
const std::string fiveThousandCC = std::string("5000CC");

// Product
class Engine
{
    public:
    virtual void packEngine() = 0;  
};

// Concrete products
// concrete product class one
class C990CCEngine: public Engine
{

    public:
    void packEngine()
    {
       cout << "Pack 990CC engine" << endl;   
    }
};

// concrete class Two
class C1200CCEngine: public Engine
{   public:
    void packEngine()
    {
        cout << "pack 1200CC engine" << endl;
    }

};

// Concrete class Three
class C1500CCEngine: public Engine
{
    public:
    void packEngine()
    {
        cout << "Pack 1500CC engine" << endl;
    }

};


// Car Factory:
class CarFactory{
    public:

    virtual Engine* createEngine(const std::string& type) = 0;
};
class Factory: public CarFactory
{
    public:
     Engine *createEngine(const std::string& type)
     {

          if(0 == nineNintyCC.compare(type))
          {    
             return new C990CCEngine;
          }
          else if(0 == thousandTwoHundredCC.compare(type))
          {
             return new C1200CCEngine;
          }
          else if(0 == ThousandFiveHundredCC.compare(type))
          {
             return new C1500CCEngine;
          } 
          else
           {
                 cout << "Invalid factory input" << endl;
             return NULL;
           }
           return NULL;
     }
};

int main()
{

    CarFactory* ptr = new Factory;
    Engine*pEngine =  ptr->createEngine(nineNintyCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    pEngine =  ptr->createEngine(ThousandFiveHundredCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    pEngine =  ptr->createEngine(thousandTwoHundredCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    pEngine = ptr-> createEngine(fiveThousandCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    return 0;
}

*/
/*
//
// interface product
#include <iostream>
#include <string>
using namespace std;

class Engine
{
 public:
 virtual void EngineType() = 0;

};

// concrte product
class AltoEngine: public Engine
{
  public:
  void EngineType()
  {
      cout << "Alto Engine" << endl;
  }
};

//Concrte product
class SwiftEngine : public Engine
{
    public:
    void EngineType()
    {
        cout << "Swift Engine" << endl;    
    }
};

class Body
{
   public:
    virtual void bodyType() = 0;

};

class AltoBody: public Body
{
  public:  
    virtual void bodyType()
    {
        cout << "Alto Car Body" << endl;
    }
};

class SwiftBody : public Body
{
    public:
    void bodyType()
    {
        cout << "SwiftCar Body" << endl;
    }

};


class CarFactory
{
   public:
   virtual Engine* createEngineProduct() = 0;
   virtual Body*   createBodyPoduct() = 0;
};
class AltoCarFactory: public CarFactory
{
    public:
    Engine * createEngineProduct()
    {
        return new AltoEngine;
    }
    Body* createBodyPoduct()
    {
        return new AltoBody;
    }

};

class SwiftCarFactory: public CarFactory
{
    public:
    Engine * createEngineProduct()
    {
        return new SwiftEngine;
    }
    Body* createBodyPoduct()
    {
        return new SwiftBody;
    }

};

int main()
{

    CarFactory* pAltoFactory = new AltoCarFactory;
    Engine* pAltoEngine = pAltoFactory->createEngineProduct();
    pAltoEngine->EngineType();
    Body* pAltoBody = pAltoFactory->createBodyPoduct();
    pAltoBody->bodyType();



    CarFactory* pSwiftFactory = NULL;
    pSwiftFactory = new SwiftCarFactory;
    Engine* pSwiftEngine = pSwiftFactory->createEngineProduct();
    pSwiftEngine->EngineType();
    Body* pSwfitBody = pSwiftFactory->createBodyPoduct();
    pSwfitBody->bodyType();
    delete pAltoBody;
    delete pAltoFactory;
    delete pSwfitBody;
    delete pSwiftFactory;
    return 0;
}
*/

/*

// One more Factory example;

#include <iostream>
#include <string>
using namespace std;

const std::string maruthi = std::string("Maruthi");
const std::string fiat = std::string("Fiat");
const std::string renault = std::string("Renault");
// Interface
class CarEngine
{
 public:
    virtual void engineType() = 0;
};

// Concrete class
class FiatEngine: public CarEngine
{
  public:
  void engineType()
  {
      cout << "Fait Engine Engine" << endl;
  }

};
// ConcreteClass
class RenaultEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Renault Engine" << endl;
    }

};
// Concrete class
class MaruthiEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Maruthi Engine" << endl;
    }
};


// Factory
class CarFactory
{
    public:
    virtual CarEngine* createFactory(const std::string&) = 0;
};

// EngineFactory
class CarEngineFactory : public CarFactory
{
     public:
     CarEngine* createFactory(const std::string&  type)
     {
          if(0 == maruthi.compare(type))
          {
              return new MaruthiEngine;

          }
          else if(0 == fiat.compare(type))
          {
              return  new FiatEngine;
          }
          else if(0 == renault.compare(type))
          {
              return new RenaultEngine;
          }
          else
          {
              cout << "Invalid Engine type" << endl;
              return NULL;
          }
     }

  };

int main()
{
    CarFactory* pCarFactory = new CarEngineFactory;
    CarEngine* pMaruthiCarEngine = pCarFactory->createFactory(maruthi);
    pMaruthiCarEngine->engineType();

    CarEngine* pFiatCarEngine = pCarFactory->createFactory(fiat);
    pFiatCarEngine->engineType();


    CarEngine* pRenaultCarEngine = pCarFactory->createFactory(renault);
    pRenaultCarEngine->engineType();

    return 0;
}


*/


/*

// One more Factory example;

#include <iostream>
#include <string>
using namespace std;

const std::string maruthi = std::string("Maruthi");
const std::string fiat = std::string("Fiat");
const std::string renault = std::string("Renault");


// Interface
class CarEngine
{
 public:
    virtual void engineType() = 0;
};

// Concrete class
class FiatEngine: public CarEngine
{
  public:
  void engineType()
  {
      cout << "Fait Car Engine" << endl;
  }

};

// ConcreteClass
class RenaultEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Renault Car Engine" << endl;
    }

};

// Concrete class
class MaruthiEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Maruthi Car Engine" << endl;
    }
};

// Interface
class CarBody
{
 public:
    virtual void bodyType() = 0;
};

// Concrete class
class FiatBody: public CarBody
{
  public:
  void bodyType()
  {
      cout << "Fait car Body" << endl;
  }

};

// ConcreteClass
class RenaultBody : public CarBody
{
    public:
    void bodyType()
    {
        cout << "Renault Body" << endl;
    }

};

// Concrete class
class MaruthiBody : public CarBody
{
    public:
    void bodyType()
    {
        cout << "Maruthi body" << endl;
    }
};


// Factory
class CarFactory
{
    public:
    virtual CarEngine* createCarEngineProduct() = 0;
    virtual CarBody* createCarBodyProduct() = 0;
};

// FiatFactory
class FaitCarFactory : public CarFactory
{
     public:
     CarEngine* createCarEngineProduct()
     {
        return new FiatEngine; 
     }
     CarBody* createCarBodyProduct()
     {
         return new FiatBody;
     }
};

// Maruthi Factory
class MaruthiCarFactory : public CarFactory
{
     public:
     CarEngine* createCarEngineProduct()
     {
         return new MaruthiEngine;
     }
     CarBody* createCarBodyProduct()
     {
         return new MaruthiBody;
     }

};

// Renault Factory
class RenaultCarFactory : public CarFactory
{
     public:
    CarEngine* createCarEngineProduct()
    {
        return new RenaultEngine;
    }

    CarBody* createCarBodyProduct()
    {
        return new RenaultBody;
    }

};


int main()
{

   // Fiat Factory
   CarFactory* pFiatCarFactory = new FaitCarFactory;
   CarEngine* pFiatEngine = pFiatCarFactory->createCarEngineProduct();
   CarBody*  pFiatBody = pFiatCarFactory->createCarBodyProduct();
   pFiatEngine->engineType();
   pFiatBody->bodyType();

   // Renault Car Factory
    return 0;
}

*/

-1

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

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

ในขณะที่ค้นหาบน google ฉันมาบล็อกต่อไปนี้ซึ่งอธิบายรูปแบบการออกแบบทั้งสองอย่างยอดเยี่ยม มาดูสิ่งเหล่านี้กัน

http://simpletechtalks.com/factory-design-pattern/

http://simpletechtalks.com/abstract-factory-design-pattern/

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.