การผกผันของการควบคุมการสร้างวัตถุใหม่

ฉันกำลังเข้าสู่ Inversion of Control โดยเฉพาะการใช้ Guice และ RoboGuice สำหรับ Android และฉันมีคำถาม

ฉันมีการเรียกเมธอดที่ส่งคืนทรัพยากร (ซึ่งโดยพื้นฐานแล้วคือสตริง XML หรือ JSON)

public Resource getResource(){
// Some implementation details that call a web service and throw the result in a string...
String resource = ........
}

จริงๆ แล้วคลาส Resource เป็นเพียงการรวม String ไว้ ดังนั้นฉันคิดว่ามันสมเหตุสมผลที่จะส่งต่อมันไปในตัวสร้าง เนื่องจากมันเป็นส่วนสำคัญของวัตถุ Resource

public class Resource{
   Resource(String theXMLorJSON){
   ...
   }
}

คำถามสองสามข้อ:

  1. ฉันจะสร้าง Resource ใหม่ในการเรียก getResource ได้อย่างไร ฉันคิดว่าฉันต้องการใช้ IoC และไม่โทร new ในวิธีการ
  2. หากคลาสอื่นใช้ Resource ในตัวสร้าง ฉันจะใช้คอนเทนเนอร์ Guice เพื่อสร้างมันได้อย่างไร เมื่อฉันต้องการไดนามิก String ในเวลาก่อสร้าง ฉันเพิ่งถามคำถามที่คล้ายกัน และเชื่อว่าอาจมีวิธีเฉพาะในการจัดการกับสิ่งนี้โดยใช้ Guice.

ขอบคุณมาก!




คำตอบ (1)


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

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

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

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

person ColinD    schedule 19.11.2011
comment
ขอบคุณมากสำหรับคำตอบ ฉันยังอยู่ในอาร์ลิงตัน รัฐเวอร์จิเนีย เหมือนกัน - person skaz; 20.11.2011
comment
อีกสองสามคำถามถ้าคุณไม่รังเกียจ 1) เหตุใดตัวอย่างในส่วน Factory by Hand ของหน้าเว็บที่คุณลิงก์จึงใช้ Provider แทนที่จะเป็นเพียง CreditService ไม่สามารถฉีด CreditService ได้ใช่ไหม 2) ถ้าฉันมีคลาสอื่น ResourceUser ที่รับ Resource ในตัวสร้าง และตัวสร้าง Resource รับ String ฉันจะตั้งค่า ResourceUser ด้วย Guice ได้อย่างไร ขออภัยถ้านี่ไร้สาระ... - person skaz; 20.11.2011
comment
ซึ่งทำเพื่อให้แน่ใจว่าโรงงานจะไม่เปลี่ยนขอบเขตของ CreditService ตัวอย่างเช่น CreditService สามารถกำหนดขอบเขตคำขอในเว็บแอปพลิเคชันได้ ดังนั้นคุณต้องแน่ใจว่าคุณได้รับอินสแตนซ์ที่ถูกต้องทุกครั้งที่มีการเรียกแฟคทอรี หากการขึ้นต่อกันทั้งหมดเป็นแบบซิงเกิลตัน คุณสามารถฉีดมันโดยตรงได้... แต่คุณไม่ควรคิดอย่างนั้นในโรงงาน ดู Injecting Providers - person ColinD; 20.11.2011