Inversi Kontrol Pembuatan Objek Baru

Saya masuk ke Inversion of Control, khususnya menggunakan Guice dan RoboGuice untuk Android dan saya punya pertanyaan.

Saya memiliki pemanggilan metode yang mengembalikan Sumber Daya (yang pada dasarnya adalah String XML atau JSON).

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

Kelas Resource sebenarnya hanyalah String yang dibungkus, jadi menurut saya masuk akal untuk meneruskannya ke dalam konstruktor, karena ini adalah bagian penting dari objek Resource.

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

Beberapa pertanyaan:

  1. Bagaimana cara membuat Resource baru di panggilan getResource? Saya akan berpikir bahwa saya ingin menggunakan IoC dan tidak memanggil new dalam metode ini.
  2. Jika kelas lain mengambil Resource di konstruktor, bagaimana saya bisa menggunakan wadah Guice untuk membangunnya ketika saya membutuhkan String dinamis pada waktu konstruksi? Saya baru saja menanyakan pertanyaan serupa dan yakin mungkin ada cara khusus untuk menangani ini menggunakan Guice.

Terima kasih banyak!


person skaz    schedule 19.11.2011    source sumber


Jawaban (1)


Saya pikir Anda mungkin salah memahami sesuatu tentang injeksi ketergantungan. Anda tidak perlu mencoba menghindari penggunaan new dalam semua kasus... Anda terutama ingin menghindari penggunaan new untuk membuat apa pun yang mungkin ingin Anda tiru untuk pengujian, dan itu umumnya yang terbaik adalah mengizinkan container menghubungkan kelas apa pun yang bergantung pada objek tersebut.

Namun, kelas Resource Anda terdengar seperti objek nilai sederhana yang dapat Anda buat dengan mudah secara manual dalam pengujian apa pun yang Anda lakukan. Itu juga tidak bergantung pada layanan apa pun... itu hanya berisi String. Jadi tidak ada alasan untuk mencoba membuat wadah itu membuatnya.

Kelas yang berisi metode getResource(), di sisi lain, Anda pasti ingin wadahnya dibuat, karena Anda ingin dapat menggunakan sesuatu yang bergantung pada kelas tersebut dalam pengujian tanpa harus benar-benar memanggil layanan web.

Perhatikan bahwa jika Anda memiliki kelas dengan konstruktor yang mengambil dependensi yang ingin Anda masukkan oleh kontainer dan parameter yang hanya diketahui saat runtime, Anda perlu membuat semacam pabrik perantara dengan metode yang hanya mengambil parameter runtime. Dengan Guice Anda dapat secara otomatis membuat pabrik seperti itu dari antarmuka menggunakan Assisted Inject (tidak yakin apakah itu berfungsi dengan RoboGuice, tetapi implementasi pabrik seperti itu juga mudah dibuat secara manual).

person ColinD    schedule 19.11.2011
comment
Terima kasih banyak atas jawabannya. Saya juga di Arlington, VA, btw. - person skaz; 20.11.2011
comment
Beberapa pertanyaan lagi jika Anda tidak keberatan. 1) Mengapa contoh di bagian Pabrik dengan Tangan pada halaman yang Anda tautkan mengambil Provider dan bukan hanya CreditService? Tidak bisakah CreditService saja yang disuntik? 2) Jika saya memiliki kelas lain, ResourceUser yang menggunakan Resource di konstruktor, dan konstruktor Resource mengambil String, bagaimana cara menyiapkan ResourceUser dengan Guice? Maaf jika ini naif... - person skaz; 20.11.2011
comment
Hal ini dilakukan untuk memastikan bahwa pabrik tidak mengubah cakupan CreditService. Misalnya, CreditService dapat mencakup permintaan dalam aplikasi web, jadi Anda perlu memastikan bahwa Anda mendapatkan instance yang benar setiap kali pabrik dipanggil. Jika semua dependensi adalah singleton, Anda bisa memasukkannya secara langsung... tetapi Anda tidak boleh berasumsi demikian di pabrik. Lihat Penyedia Suntikan. - person ColinD; 20.11.2011