ทำไมรูปแบบการออกแบบวิธีการจากโรงงานจึงมีประโยชน์มากกว่าการมีคลาสและเรียกพวกมันทีละรายการ


32

จากรูปแบบการออกแบบ "Gang of Four" มีวิธี Factory:

class Factory(product)
  case product
  when a
    new A
  when b
    new B
  when c
    new C
end

new Factory(a)

นี่คือเหตุผลที่มีประโยชน์มากขึ้นกว่าที่มีสามชั้นa, bและcและเรียกพวกเขาที?


1
คุณหมายถึงอะไรอย่างแม่นยำ? ทำไมไม่ยกตัวอย่างทั้งสาม นั่นคือสิ่งที่คุณหมายถึงอะไร
Neil

1
@ ไม่มีในรูปแบบของโรงงานมีคลาสทั้งหมดเป็นพี่น้อง เหตุใดจึงเรียกร้องให้โรงงานเข้าถึงคลาส a, b, c โดยอ้อม
alt

3
นี่ไม่ได้ดูเหมือนรูปแบบวิธีการของโรงงานสำหรับฉันถ้ามีสิ่งใดที่ใกล้เคียงกับโรงงานแบบนามธรรม
jk

2
เพราะในเวลาออกแบบคุณไม่ทราบว่าคุณต้องการยกตัวอย่างใดใน 3 คลาส
MrWhite

คำตอบ:


54

เพราะตัวอย่างของคุณไม่ซับซ้อนพอ สำหรับสถานการณ์อย่างง่าย ๆ มันไม่สมเหตุสมผลเลยที่จะใช้รูปแบบขั้นสูง

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

บางทีวัตถุเหล่านั้นต้องการการอ้างอิงถึงวัตถุ X บางอย่างซึ่งโรงงานสามารถให้ได้ แต่รหัสของคุณในสถานที่ที่คุณต้องการสร้าง A, B หรือ C ไม่สามารถหรือไม่ควรเข้าถึง X บางทีเมื่อคุณมี X คุณสร้าง A และ B แต่ถ้าคุณมี Y พิมพ์คุณก็จะสร้าง C

นอกจากนี้ให้พิจารณาว่าวัตถุบางอย่างอาจต้องมีการพึ่งพา 20 เพื่อสร้าง; ถ้าเช่นนั้นจะเป็นอย่างไร การตามล่าหาการพึ่งพาเหล่านั้นในสถานที่ที่ไม่ควรเข้าถึงอาจเป็นปัญหาได้


13
+1 ที่ทำให้ชัดเจนว่ารูปแบบโรงงานไม่ใช่วิธีที่ดีที่สุดเสมอไป
Neil

1
เพราะตัวอย่างของคุณไม่ซับซ้อนพอ สำหรับสถานการณ์อย่างง่าย ๆ มันไม่สมเหตุสมผลเลยที่จะใช้รูปแบบขั้นสูง แล้วคุณจะทำอะไรในกรณีนี้ Inline การก่อสร้างตามเงื่อนไข?
pdr

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

รูปแบบที่เรียกว่าวิธีการโรงงานด้วยเหตุผล วิธีนี้ไม่จำเป็นต้องอยู่ในคลาสที่แตกต่างกันเพื่อเป็นวิธีการจากโรงงาน
pdr

ฉันพลาด "วิธี" ในนั้นแล้วคุณเป็นคนดี
Mateusz

23

ลวดลายโรงงานมักจะซับซ้อนกว่านั้น โรงงานตัดสินใจตามเกณฑ์ที่กำหนดซึ่งอินสแตนซ์ในการสร้าง / ส่งคืน แต่เมื่อคุณไม่ได้ใช้โรงงานคุณจะต้องใช้รหัสนั้นซ้ำ ๆ ในหลาย ๆ ที่ในรหัสของคุณ

เป็นตัวอย่างให้พิจารณาสิ่งต่อไปนี้: คุณจำเป็นต้องโหลดข้อมูลจากฐานข้อมูล แต่คุณมีหนึ่งฐานข้อมูลกลางสำหรับการรวมเข้ากับข้อมูลจำนวนมากและอีกอันหนึ่งมีขนาดเล็กลงในหน่วยความจำในแต่ละ dev-PC ในรหัสของคุณคุณถามโรงงานที่จะได้รับDB-จับและโรงงานผลตอบแทนที่เป็นหนึ่งในบรรดาขึ้นอยู่กับเช่นแฟ้มการกำหนดค่า


20

รูปแบบวิธีการของโรงงานเป็นนามธรรมกระบวนการตัดสินใจจากระดับการเรียก นี่มีข้อดีหลายประการ:

นำมาใช้ใหม่ ถ้าฉันต้องการยกตัวอย่างในหลาย ๆ ที่ฉันไม่ต้องทำซ้ำเงื่อนไขของฉันดังนั้นเมื่อฉันมาเพื่อเพิ่มคลาสใหม่ฉันจะไม่เสี่ยงกับการขาดเรียน

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

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

คุณสามารถสร้างคลาสโรงงานใหม่และทำให้เปลี่ยนเป็น hot-swap ได้หากสถานการณ์ต้องการ - ตัวอย่างเช่นถ้าคุณต้องการเปิดและปิดคลาส D ในขณะที่ทำการทดสอบ ฉันพบกับสถานการณ์นี้เพียงครั้งเดียว แต่มันมีประโยชน์มาก

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


14

ข้อดีที่สำคัญของรูปแบบของโรงงานมีสองประการ:

  1. สถานที่ที่ต้องการการนำไปใช้งานของผลิตภัณฑ์ไม่จำเป็นต้องรู้วิธีการสร้าง โรงงานเก็บข้อมูลดังกล่าว

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

  2. สถานที่ที่ต้องการการนำไปใช้งานของผลิตภัณฑ์ไม่จำเป็นต้องรู้ในเวลาของคำอธิบายโมดูล (เช่น ณ เวลารวบรวม) สิ่งที่ชื่อของชั้นเรียนการใช้งานคืออะไร

    ดังนั้นaไม่จำเป็นต้องมีอะไรเกี่ยวข้องกับA; "สิ่งที่จะสร้าง" สามารถอธิบายได้ในแง่ของคุณสมบัติที่ไม่ใช่หน้าที่การใช้งานที่ต้องการและไม่ใช่แค่ชื่อ นี่คือความยืดหยุ่นมากขึ้น

ข้อเสียคือที่ที่คุณรู้ว่าต้องทำอะไรและทำอย่างไรคุณจะมีความซับซ้อนมากขึ้นเมื่อคุณใช้โรงงาน การแก้ไขนั้นง่าย แต่อย่าใช้โรงงานเมื่อไม่สมเหตุสมผล!


2

ฉันอยากจะคิดถึงรูปแบบการออกแบบในแง่ของการเป็น 'คน' และรูปแบบเป็นวิธีที่ผู้คนพูดคุยกัน

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

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

ในทำนองเดียวกันการใช้ Factory ช่วยให้ผู้บริโภคสามารถสร้างวัตถุใหม่โดยไม่ต้องรู้รายละเอียดว่าพวกเขาสร้างขึ้นมาหรือพึ่งพาอะไร - พวกเขาเพียงแค่ให้ข้อมูลที่ต้องการ

มารยาท


1

รูปแบบจากโรงงานเป็นรูปแบบการออกแบบที่ใช้มากเกินไปและถูกทารุณกรรม

ฉันเจอหลายกรณีที่มีการเข้ารหัสคลาสโรงงานเมื่อตัวสร้างแบบง่ายจะเพียงพอ

อย่าใช้คลาสโรงงานยกเว้น: -

  • คุณขึ้นอยู่กับแหล่งข้อมูลภายนอก แต่คุณยังไม่รู้อย่างแน่นอน
  • การก่อสร้างมีราคาแพงและคุณต้องการสร้างครั้งเดียวและนำมาใช้ซ้ำหลายครั้ง
  • การสร้างอินสแตนซ์ใหม่ขึ้นอยู่กับอินสแตนซ์ที่สร้างขึ้นแล้ว (เช่นคุณสามารถมีการเชื่อมต่อได้ห้าครั้งเท่านั้นหรือคุณควรใช้หมายเลข ID การเชื่อมต่อหนึ่งหมายเลขมากกว่าหมายเลขสุดท้ายที่ใช้)

0

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

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

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

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

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