การผกผันของการควบคุมคืออะไรและฉันควรใช้เมื่อใด


64

ฉันกำลังออกแบบระบบใหม่และฉันต้องการทราบว่าการควบคุมกลับกัน (IOC) คืออะไรและที่สำคัญเมื่อใช้

จะต้องมีการใช้งานกับอินเตอร์เฟสหรือสามารถทำได้กับคลาส?


คำตอบ:


62

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

ตัวอย่างที่ง่ายที่สุดของรูปแบบIoCจะเป็นฟังก์ชันการโทรกลับใน C ตัวอย่างเช่นคุณสามารถประกาศฟังก์ชัน:

void Iterator(void *list, Func* f)

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

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

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

นี่คือตัวอย่างในรหัสเทียม:

class Foo 
{ 
   <Require Boo>Constructor(Boo boo){ boo.DoSomething } 
}

ในคลาสตัวอย่างนี้Fooมีตัวสร้างที่ต้องการอาร์กิวเมนต์ชนิดBooเพื่อดำเนินการบางอย่าง

คุณสามารถสร้างตัวอย่างของคลาสFooโดยใช้รหัสที่คล้ายกับสิ่งนี้:

MyContainer.Create(typeof Foo)

MyContainer- เป็นคอนเทนเนอร์ IoCซึ่งดูแลการรับอินสแตนซ์Booและส่งต่อไปยังตัวFooสร้าง

โดยสรุปแล้วIoCช่วยให้คุณสามารถแยกโปรแกรมออกเป็นส่วนต่างๆได้ นี่เป็นสิ่งที่ดีเพราะ:

  • ส่วนประกอบสามารถทดสอบได้อย่างอิสระอย่างอิสระ
  • ความซับซ้อนของโปรแกรมสามารถลดลงได้
  • คุณสามารถสลับส่วนประกอบเป็นการใช้งานอื่น

อย่างไรก็ตามในบางกรณีIoCสามารถสร้างรหัสให้เข้าใจได้ยากขึ้น

หากคุณต้องการเห็นตัวอย่างที่ดีของการใช้งานIoC ในโลกแห่งความเป็นจริงลองดูที่ Mircosoft Composite UI Application BlockและCompositeWPF

ฉันหวังว่าคำอธิบายของฉันจะช่วยคุณ

ขอแสดงความนับถือ
aku


1
ห้าปีต่อมา แต่ก็ยัง .... นั่นเป็นคำอธิบายที่ยอดเยี่ยม ขอบคุณ
Nick Hodges

4
ไม่ได้กล่าวถึงมากเกี่ยวกับ IoC เนื่องจากข้อเท็จจริงที่ว่ารหัสจะอ่านยากขึ้น การอ่านเป็นสิ่งสำคัญอันดับหนึ่งหากคุณต้องการเขียนซอฟต์แวร์ที่ยอดเยี่ยม มันยังเต้นเต้นได้ คุณสามารถแยกรหัสได้อย่างมีประสิทธิภาพ
Arne Evertsson

ดังนั้นรหัสที่ใช้โซลูชันที่อิงกับอินเตอร์เฟสสำหรับการอ้างอิงทั้งหมดจะขึ้นอยู่กับการออกแบบ IoC
nikel

18

เมื่อไม่นานมานี้ฉันเพิ่งขุดลงไปเองและเก็บบุ๊กมาร์กทั้งหมดต่อไปนี้ฉันจึงพบว่ามีค่ายิ่งสำหรับการเรียนรู้เกี่ยวกับ IOC / DI

บทความต้นฉบับของ Martin Fowlers เกี่ยวกับ IOC / DI

แนวคิดบางอย่างที่ต้องรู้ก่อน

คอลเลกชันที่ยอดเยี่ยมของการสอน IOC / DI

หนังสือเกี่ยวกับ IOC / DI จาก Manning Press

แหล่งที่มาและคำอธิบายวิธีสร้าง IOC ของคุณเอง - สาเหตุที่ทำให้การอ่านซอร์สโค้ดเป็นวิธีที่ดีที่สุดในการทำความเข้าใจแนวคิด


4

สวัสดี JMS โดยทั่วไปแล้ว IoC / DI จะช่วยให้คุณกำหนดว่าการใช้งานแบบใดที่คุณใช้เพียงครั้งเดียวและเก็บสำเนาของคอนเทนเนอร์ของคุณไว้อ้างอิงทุกครั้งที่คุณต้องการอ้างอิง

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

IE กล่าวว่าคุณมีอินเทอร์เฟซสำหรับอ่านกระแสข้อมูลและคุณมี XMLStreamReader และการใช้งาน SQLStreamReader จากนั้นคุณสามารถส่งการอ้างอิงไปยังอินเทอร์เฟซไปยังวิธีการของคุณและจากนั้นในคอนเทนเนอร์ IoC ของคุณบอกว่าจะใช้อันไหน

ดังนั้นคุณสามารถมี Public List ReadPeople (ตัวอ่าน IStreamReader) และในการตั้งค่าสำหรับคอนเทนเนอร์ IoC ของคุณจะบอกทุกครั้งที่คุณคาดหวังว่า IStreamReader จะใช้ SQLStreamReader

จากนั้นหากคุณเปลี่ยนใจในภายหลังคุณจะต้องเปลี่ยนมันในที่เดียว (การตั้งค่าของคอนเทนเนอร์ของคุณ) และมันจะไม่สำคัญว่ามีวิธีการมากมายถาม IStreamReader มันจะได้รับค่าเริ่มต้นที่คุณบอกว่าภาชนะของคุณ ให้บริการขึ้น


3

สมมติว่าคุณมีตัวตรวจสอบความถูกต้องสำหรับการตรวจสอบว่าธุรกิจมีความถูกต้องในระบบของคุณหรือไม่ "BusinessValidator" ของคุณอาจมีฟิลด์ประเภท AddressValidator ซึ่งตรวจสอบความถูกต้องของส่วนที่อยู่ของธุรกิจ หากคุณต้องการทดสอบ BusinessValidator โดยไม่ต้องใช้โค้ดภายนอก (เช่นรหัส addressValidator) หากคุณใช้ IoC / DI ในกรอบงานของคุณคุณสามารถ easliy "inject" mock addressValidator ในที่นั้นได้โดยไม่ต้องกังวลเกี่ยวกับการทดสอบ รหัสนอกขอบเขตของชั้นเรียนภายใต้การทดสอบ

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