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


20

มีเหตุผลมากมายว่าทำไมคนรอบข้างจึงชั่วร้ายใน OOP

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

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

ตัวอย่าง (ตัวย่อที่เรียบง่ายเพื่อแสดงจุดโดยทั่วไปโดยไม่ต้องเจาะลึกในแอปพลิเคชันเฉพาะ)

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

วิธีการแก้ปัญหาที่ไร้เดียงสาคือการสร้างภาชนะใส่ของโลกเช่น

vector<Vehicle> vehicles;

ซึ่งสามารถเข้าถึงได้จากทุกที่

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

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

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


6
รอสักครู่คุณพูดถึงวงกลมที่ไม่เปลี่ยนแปลงและใช้ลิงก์เพื่อ "ทำไมสถานะโลกไม่ดี" เพื่อให้เหตุผล WTF?
Telastyn

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

9
แต่มีความแตกต่างระหว่างการตัดสินใจเท่านั้นอ่าน globals และรัฐทั่วโลก
Telastyn

1

1
@ vsz ไม่จริง - คำถามเกี่ยวกับการบริการโรงงานที่ตั้งเป็นวิธีแก้ไขปัญหาของวัตถุที่แตกต่างกัน แต่คำตอบของมันยังตอบคำถามของคุณในการอนุญาตให้คลาสเข้าถึงข้อมูลทั่วโลกมากกว่าข้อมูลทั่วโลกที่ถูกส่งผ่านไปยังคลาส
gbjbaanb

คำตอบ:


37

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

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

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

จุดของการฉีดพึ่งพาคือ:

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

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

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

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

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

จากนั้นคุณต้องพิจารณา: นักแสดงทุกคนต้องการเข้าถึงทรัพยากรนั้นจริง ๆ หรือไม่? จริงๆ?

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

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

  • Refactor ซึ่งเป็นแหล่งพระเจ้าขนาดใหญ่ที่ยิ่งใหญ่ในแหล่งย่อยที่เล็กกว่าดังนั้นนักแสดงที่แตกต่างกันจึงต้องการเข้าถึงชิ้นส่วนต่าง ๆ ของมัน แต่ไม่ค่อยนักแสดงต้องการชิ้นส่วนทั้งหมดหรือ

  • Refactor นักแสดงของคุณในทางกลับกันยอมรับเป็นพารามิเตอร์เฉพาะส่วนย่อยของปัญหาที่พวกเขาต้องทำงานดังนั้นพวกเขาจึงไม่จำเป็นต้องปรึกษาแหล่งกลางขนาดใหญ่ขนาดใหญ่ที่ยิ่งใหญ่ตลอดเวลา


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

3
@gbjbaanb สมมติว่าทรัพยากรเป็น Zork OP บอกว่าไม่เพียง แต่วัตถุทุกชิ้นในระบบของเขาต้องการ Zork เพื่อทำงานด้วย แต่ยังมี Zork เพียงหนึ่งเดียวเท่านั้นที่จะมีอยู่และวัตถุทั้งหมดของเขาจะต้องเข้าถึง Zork หนึ่งตัวอย่างเท่านั้น ฉันกำลังบอกว่าทั้งสองข้อสันนิษฐานนั้นไม่มีเหตุผล: มันอาจจะไม่จริงที่วัตถุทั้งหมดของเขาต้องการ Zork และจะมีบางครั้งที่วัตถุบางอย่างจะต้องการตัวอย่างของ Zork ในขณะที่วัตถุอื่นจะต้องมี อินสแตนซ์ที่แตกต่างกันของ Zork
Mike Nakis

2
@gbjbaanb ฉันไม่คิดว่าคุณจะขอให้ฉันอธิบายว่าทำไมมันจึงโง่ที่จะมีอินสแตนซ์ทั่วโลกสองแห่งของ Zork ชื่อ ZorkA และ ZorkB และรหัสยากในวัตถุที่จะใช้ ZorkA และอันไหนจะใช้ ZorkB ขวา?
Mike Nakis

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

1
@gbjbaanb ฉันเชื่อว่าความคิดคือการมีชั้นเรียนลูกค้าหนึ่งสามารถทำงานได้ทั้งบน ZorkA หรือ ZorkB ตามที่ระบุไว้ไม่ให้ชั้นลูกค้าตัดสินใจว่าจะคว้าชั้นไหน
Eugene Ryabtsev

39

มีเหตุผลมากมายว่าทำไมรูปทรงกลมที่ไม่ผันแปรเป็นสิ่งชั่วร้ายใน OOP

นั่นคือการเรียกร้องที่น่าสงสัย ลิงก์ที่คุณใช้เป็นหลักฐานหมายถึงรัฐ - ไม่แน่นอน Globals พวกเขาชั่วร้ายอย่างแน่นอน อ่านอย่างเดียวคือค่าคงที่ ค่าคงที่มีสติค่อนข้าง ฉันหมายความว่าคุณจะไม่ใส่คุณค่าของไพเข้าไปในทุกชั้นเรียนใช่มั้ย

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

ไม่พวกเขาทำไม่ได้

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

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

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

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

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

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

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


ขออภัยในความสับสนด้วย "ไม่เปลี่ยนแปลง" ฉันต้องการที่จะพูดว่าไม่แน่นอนและอย่างใดไม่รู้จักความผิดพลาดของฉัน
vsz

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

2
แอปพลิเคชันที่มีวัตถุจำนวนมากที่เข้าถึงฐานข้อมูลบางอย่างเป็นประจำนั้นไม่เคยมีมาก่อน
Robert Harvey

@RobertHarvey - แน่นอน แต่อินเตอร์เฟสนั้นขึ้นอยู่กับ "สามารถเข้าถึงฐานข้อมูล" หรือ "ที่เก็บข้อมูลถาวรสำหรับfoos" ได้หรือไม่?
Telastyn

1
เตือนฉันถึง Dilbert ที่ PHB ถามถึงฟีเจอร์ 500 รายการและ Dilbert บอกว่าไม่ ดังนั้น PHB จึงขอคุณลักษณะ 1 อย่างและดิลเบิร์ตบอกว่าแน่นอน วันถัดไป Dilbert ได้รับ 500 คำขอต่อ 1 คุณสมบัติ หากบางสิ่งบางอย่างไม่ได้ปรับขนาดมันก็ไม่ได้ปรับขนาดไม่ว่าคุณจะแต่งตัวอย่างไร
corsiKa

16

มีสามเหตุผลหลักที่คุณควรพิจารณา

  1. การอ่าน หากทุกหน่วยของโค้ดมีทุกสิ่งที่จำเป็นต้องใช้ในการฉีดหรือส่งเป็นพารามิเตอร์มันจะง่ายต่อการดูโค้ดและดูทันทีว่ามันกำลังทำอะไรอยู่ สิ่งนี้ช่วยให้คุณทราบตำแหน่งของฟังก์ชันซึ่งช่วยให้คุณสามารถแยกความกังวลได้ดียิ่งขึ้นและบังคับให้คุณคิดถึง ...
  2. modularity เหตุใดตัวแยกวิเคราะห์จึงควรรู้เกี่ยวกับรายการยานพาหนะทั้งหมดและคุณสมบัติทั้งหมดของยานพาหนะ มันอาจจะไม่ อาจจำเป็นต้องสอบถามว่ามีรหัสยานพาหนะหรือ X ยานพาหนะมีคุณสมบัติ Y ยอดเยี่ยมนั่นหมายความว่าคุณสามารถเขียนบริการที่ทำเช่นนั้นและฉีดเฉพาะบริการนั้นลงในโปรแกรมวิเคราะห์คำ ทันใดนั้นคุณก็จบลงด้วยการออกแบบที่สมเหตุสมผลมากขึ้นด้วยโค้ดทุกบิตเท่านั้นที่จัดการข้อมูลที่เกี่ยวข้อง ซึ่งนำเราไปสู่ ​​...
  3. การตรวจสอบได้ สำหรับการทดสอบหน่วยทั่วไปคุณต้องการตั้งค่าสภาพแวดล้อมของคุณสำหรับสถานการณ์ที่แตกต่างกันและการฉีดทำให้ง่ายต่อการใช้งาน อีกครั้งเมื่อกลับไปที่ตัวอย่าง parser คุณต้องการทำรายการยานพาหนะที่มีอุปกรณ์ครบครันสำหรับการทดสอบทุกครั้งที่คุณเขียนโปรแกรมวิเคราะห์คำหรือไม่ หรือคุณเพียงแค่สร้างการประยุกต์ใช้การเยาะเย้ยของออบเจ็กต์บริการดังกล่าวส่งคืนหมายเลขรหัสที่แตกต่างกัน? ฉันรู้ว่าฉันจะเลือกอันไหน

ดังนั้นเพื่อสรุป: DI ไม่ใช่เป้าหมายมันเป็นเพียงเครื่องมือที่ช่วยให้บรรลุเป้าหมาย หากคุณใช้มันในทางที่ผิด (เหมือนที่ปรากฏในตัวอย่างของคุณ) คุณจะไม่เข้าใกล้เป้าหมายมากขึ้นไม่มีทรัพย์สินวิเศษของ DI ที่จะทำให้การออกแบบไม่ดี


+1 สำหรับคำตอบที่เน้นไปที่ปัญหาการบำรุงรักษา More P: SE คำตอบควรเป็นเช่นนี้
dodgethesteamroller

1
สรุปของคุณดีมาก ดีมาก หากคุณคิดว่า [รูปแบบการออกแบบของเดือน] หรือ [buzzword ของเดือน] จะช่วยแก้ปัญหาของคุณได้อย่างน่าอัศจรรย์คุณจะมีเวลาไม่ดี
corsiKa

@corsiKa ฉันเกลียด DI (หรือ Spring เพื่อความแม่นยำมากขึ้น) เป็นเวลานานเพราะฉันไม่เห็นจุดของมัน ดูเหมือนจะเป็นเรื่องยุ่งยากอย่างมากโดยไม่มีผลตอบแทนเป็นรูปธรรม (ย้อนกลับไปในวันกำหนดค่า XML) ฉันหวังว่าฉันได้พบเอกสารบางอย่างเกี่ยวกับสิ่งที่ DI ซื้อให้คุณจริงๆในตอนนั้น แต่ฉันไม่ได้ดังนั้นฉันจึงต้องคิดออกเอง มันใช้เวลานาน :)
biziclop

3

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

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

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

ไม่ว่าจะเป็นเรื่องใดก็ตามตัวอย่างของ 'หางกระดิกหางสุนัข' ความต้องการในการทดสอบคือการขับรถว่าโค๊ดเบสเป็นแบบ architected หรือไม่ (ปัญหาที่คล้ายกันเกิดขึ้นกับรายการเช่นคลาสแบบสแตติกเช่น datetime ปัจจุบัน)

โดยส่วนตัวฉันชอบที่จะติดข้อมูลทั่วโลกทั้งหมดของฉันในวัตถุทั่วโลก (หรือหลาย ๆ ) แต่ให้ accessors เพื่อรับบิตเรียนของฉันต้องการ จากนั้นฉันสามารถเยาะเย้ยเหล่านั้นเพื่อส่งคืนข้อมูลที่ฉันต้องการเมื่อมันมาถึงการทดสอบโดยไม่ต้องเพิ่มความซับซ้อนของ DI


"โดยปกติวัตถุทั่วโลกสามารถบำรุงรักษาได้มาก" - ไม่ใช่ถ้ามันไม่แน่นอน จากประสบการณ์ของฉันการมีสภาวะทั่วโลกที่เปลี่ยนแปลงไม่ได้อย่างมากอาจเป็นฝันร้าย
sleske

3

นอกจากคำตอบที่คุณมีอยู่แล้ว

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

หนึ่งในคุณสมบัติของการเขียนโปรแกรม OOP คือการรักษาคุณสมบัติที่คุณต้องการสำหรับวัตถุเฉพาะเท่านั้น

ตอนนี้ถ้าวัตถุของคุณมีคุณสมบัติมากเกินไป - คุณควรแยกวัตถุของคุณออกเป็นวัตถุย่อย

แก้ไข

พูดถึงแล้วว่าทำไมวัตถุทั่วโลกไม่ดีฉันจะเพิ่มตัวอย่างหนึ่งตัวอย่าง

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


จริง แต่ตัวอย่างเช่น parser จะต้องรู้ทุกอย่างเพราะคำสั่งใด ๆ ที่อาจได้รับซึ่งสามารถทำการเปลี่ยนแปลงอะไร
vsz

1
"ก่อนที่ฉันจะมาถึงคำถามที่แท้จริงของคุณ" ... คุณจะตอบคำถามของเขาหรือไม่?
gbjbaanb

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