ศัพท์เทคนิคที่ใช้แทนการฉีดแบบพึ่งพา?


12

นี่เป็นศัพท์เฉพาะ (การเขียนเชิงเทคนิค) มากกว่าคำถามทางเทคนิคอย่างแท้จริง ฉันกำลังพยายามเขียนข้อเสนอการปรับโครงสร้างใหม่ (และให้สิทธิ์ตัวเอง) โดยมีศูนย์กลางที่การขยายการฉีดที่ต้องพึ่งพาในแอปพลิเคชันของเรา ในขณะที่เราใช้Springในการเรียกถั่วอัตโนมัติยังคงมีกรณีที่ยกตัวอย่างถั่วที่ใช้MyClass obj = new MyClass(...)ซึ่งสามารถฉีดได้ทั้งหมด ฉันต้องการทำให้ข้อเสนอของฉันใช้ระบบการตั้งชื่อที่สง่างามและอ้างอิงถึงรูปแบบการออกแบบตรงข้ามกับ DI ด้วยคำที่เหมาะสม

คำว่า "คับคัปปลิ้ง" เป็นคำที่เพียงพอหรือไม่ที่ตรงกันข้ามกับ DI?


1
ใช่การแต่งงานกันอธิบายทั้งการกระทำของการใช้ชื่อคลาสที่ชัดเจนในคลาสอื่น ๆ และสถานะผลลัพธ์ของฐานรหัส
Kilian Foth

11
ไม่การมีเพศสัมพันธ์อย่างแน่นหนาจะอธิบายคุณสมบัติของรหัสผลลัพธ์เท่านั้นไม่ใช่ตรงข้ามกับ DI คุณสามารถใช้ DI และยังคงมีเพศสัมพันธ์อย่างแน่นหนาด้วยเหตุผลที่แตกต่างกันโดยสิ้นเชิง
Doc Brown

1
เห็นพ้องกันว่าDI และการมีเพศสัมพันธ์แน่นไม่ได้ตรงข้าม
Eric King

@EricKing อวด +1 ตามวิธี
candied_orange

1
"พึ่งพาดูด"
SeldomNeedy

คำตอบ:


30

ไม่การมีเพศสัมพันธ์อย่างแน่นหนานั้นมากกว่าการฉีดที่ต้องพึ่งพา

การพึ่งพาการฉีดเป็นการตัดสินใจของการใช้งานภายนอก นี่เป็นหนทางไกลในการแยกออก แต่การมีเพศสัมพันธ์เป็นมากกว่าแค่นี้

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

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

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


ใช่การเข้ารหัสยาก (พึ่งพา) ตรงข้ามกับการฉีด (ที่รันไทม์) เป็นสิ่งที่ฉันจะแนะนำเช่นกันคุณก็เร็วกว่าฉันนิดหน่อย
Doc Brown

7
@DocBrown บางครั้งฉันหวังว่าสถานที่แห่งนี้จะไม่ได้เน้นที่ความรวดเร็ว ฉันอยากได้ยินว่าคุณจะใส่มันอย่างไร
candied_orange

คำตอบที่ดี - การพึ่งพาการฉีดไม่ได้หมายความถึงการแยกตัว ความเชื่อเป็นอย่างอื่นที่นำไปสู่ถนนที่ไม่ดี
Ant P

1
@CandiedOrange บางทีใครบางคนควรแนะนำในเมตาว่าคำตอบยังคงซ่อนอยู่เป็นระยะเวลาหนึ่ง และ / หรือโหวตนั้นถูกซ่อนจากมุมมองสาธารณะเป็นNเวลาหลายชั่วโมง ... หรือจนกว่าจะมีการเลือกคำตอบ ฉันรู้ว่าฉันไม่ได้มีวัตถุประสงค์ทั้งหมดเมื่อคำตอบเดียวมี 10 คะแนนและอีก 5 คำตอบไม่มี!
svidgen

1
@svidgen ค้นหา "ปืนที่เร็วที่สุดในฝั่งตะวันตก" บน meta ปัญหานี้มีประวัติยาวนานแล้ว
candied_orange

6

พูดอย่างเคร่งครัดการพึ่งพาการฉีดจะไม่ต่อต้านการพึ่งพาการฉีดเท่านั้นและดังนั้นกลยุทธ์การจัดการการพึ่งพาใด ๆ ที่ไม่ใช่การฉีดการพึ่งพา

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

public DependencyInjectedConstructor(DependencyClass dep) {
  dep.do();
}

public DependencyLookupConstructor() {
  var dep = new DependencyClass();
  dep.do();
}

DependencyLookupConstructorเป็นคู่กับเฉพาะDependencyClassในกรณีนี้ แต่พวกเขากำลังทั้งDependencyClassคู่ ความชั่วร้ายจริงถ้ามีคนที่นี่ไม่ได้มีเพศสัมพันธ์จำเป็นก็ว่าDependencyLookupConstructorต้องการที่จะเปลี่ยนถ้าDependencyClassจู่ ๆ ก็ต้องการพึ่งพาตัวเองฉีด1

อย่างไรก็ตามคอนสตรัคเตอร์ / คลาสนี้มีการเชื่อมโยงกันอย่างหลวม ๆมากขึ้น :

public DependencyLocatingConstructor() {
  var dep = ServiceLocator.GetMyDoer();
  dep.do();
}

หากคุณทำงานใน C # ข้อมูลด้านบนจะอนุญาตให้คุณServiceLocatorส่งคืนสิ่งใดก็ตามเมื่อGetMyDoer()มีการเรียกใช้ตราบใดที่มีdo()สิ่งที่DependencyLocatingConstructorมีdo()อยู่ คุณจะได้รับประโยชน์ในการตรวจสอบลายเซ็นเวลารวบรวมโดยไม่ได้ถูกคู่กับอินเตอร์เฟซที่สมบูรณ์2

ดังนั้นเลือกพิษของคุณ

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

  • รูปแบบตัวระบุบริการ
  • ที่ตั้งการพึ่งพา / ที่อยู่
  • การสร้างวัตถุ / การอ้างอิงโดยตรง
  • การพึ่งพาที่ซ่อนอยู่
  • "ไม่พึ่งพาการฉีด"

1. แดกดันปัญหาบางอย่างที่ DI แก้ในระดับที่สูงกว่านั้นเป็นผลมาจาก [over-] ใช้ DI ในระดับต่ำกว่า ฉันมีความสุขที่ได้ทำงานกับฐานโค้ดที่มีความซับซ้อนที่ไม่จำเป็นไปทั่วเนื่องจากการรองรับสถานที่ที่ความซับซ้อนนั้นช่วยได้จริง ...

2. การใช้ตำแหน่งบริการยังช่วยให้คุณสามารถระบุการพึ่งพาที่แตกต่างกันของประเภทเดียวกันโดยบทบาทหน้าที่ของพวกเขาจากโค้ดที่เรียกใช้ในขณะที่ยังคงไม่เชื่อเรื่องพระเจ้าเกี่ยวกับวิธีการสร้างการพึ่งพา สมมติว่าคุณต้องแก้ไขUserหรือIUserเพื่อจุดประสงค์ที่แตกต่าง: เช่นLocator.GetAdministrator()กับLocator.GetAuthor()- หรืออะไรก็ตาม รหัสของฉันสามารถถามสิ่งที่ต้องการใช้งานได้โดยไม่ต้องรู้ว่าอินเตอร์เฟสรองรับอะไร


2
ความรอดDependencyInjectedConstructor(DependencyClass dep)คือ DependencyClass อาจเป็นส่วนต่อประสานหรือระดับนามธรรม นี่คือเหตุผลที่มันทำให้ฉันเศร้าที่ C # IDependencyโคดใช้คำนำหน้าอินเตอร์เฟซในขณะที่ ในฐานะลูกค้ามันไม่ใช่ธุรกิจของฉันว่าสิ่งที่พึ่งพานี้คืออะไร ตราบใดที่ฉันไม่ได้สร้างมันขึ้นมาสิ่งที่ฉันต้องรู้ก็คือวิธีพูดกับมัน มันคืออะไรปัญหาของคนอื่น
candied_orange

จุดที่ถูก DI ยังคงคู่คุณอินเตอร์เฟซที่และมันไม่จำเป็นต้องที่DependencyClassจะเป็นอินเตอร์เฟซที่เป็นนามธรรมที่ทั้งหมด มันต้องการเพียงแค่ตรรกะการก่อสร้าง / การกำหนดค่า / ตำแหน่งที่มีอยู่ "ที่อื่น" ... ดีและอื่น ๆ กับเรื่องคำถามที่ประเด็นก็คือว่า DI ไม่ได้ "ตรงข้ามของการมีเพศสัมพันธ์แน่น" :)
svidgen

ที่จริง ... ฉันอาจจะไม่ได้พูดอะไรเล็กน้อย DI จำเป็นต้องจับคู่คุณเข้ากับอินเทอร์เฟซแม้ใน C # แม้ว่าฉันจะหลีกเลี่ยงพวกเขาใน C # ฉันอยู่ภายใต้การแสดงผลที่ฉันสามารถยอมรับdynamicพารามิเตอร์ได้ (แต่ไม่ใช่varพารามิเตอร์ถ้าหน่วยความจำทำหน้าที่) ดังนั้นด้วย DI ใน C # ฉันคิดว่าฉันต้องโค้ดกับอินเทอร์เฟซหรือฉันต้องยกเลิกการตรวจสอบเวลาคอมไพล์ทั้งหมด
svidgen

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

ฉันไม่แน่ใจว่าเรากำลังขัดแย้งกันทั้งหมด แต่เพื่อให้ชัดเจนขึ้น ... ออบเจกต์มีการเชื่อมต่อภายในกับอินเทอร์เฟซของตนเองภายในใช่ แต่อินเทอร์เฟซของตัวเองเท่านั้นกำหนดการมีเพศสัมพันธ์ถ้าอินเทอร์เฟซที่มีชื่อชัดเจน ใน C # การใช้dynamicหรือvarรับวัตถุจาก locator ให้คุณเพิกเฉยต่ออินเตอร์เฟสและใช้คลาสใดก็ได้ที่do()คุณต้องการโดยไม่คำนึงว่าคลาสนั้นใช้IDoerอินเทอร์เฟซบางตัวหรือไม่ ในคำอื่น ๆ ถ้าเรามี A-> B <-C, DI decouples จาก C แต่มันต้องใช้ทั้ง A และ C จะต้องคู่กับ B และป้องกันการใช้ D do()แม้ว่าจะ
svidgen

2

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


2
ฉันชอบinstance creationแต่มันไม่เจาะจงพอ DI สร้างอินสแตนซ์ แต่โดยวิธีการของตัวควบคุมและไม่อยู่ในระดับแอปพลิเคชัน อาจเป็นinternal instance creation
สัตว์สะเทินน้ำสะเทินบก

1

ฉันจะไปกับการพึ่งพา encapsulation นี่เป็นการแสดงออกถึงการพึ่งพาที่ถูกล็อคมากกว่าที่จะไปและออกจากอีกครั้ง

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