Mengapa Inversion of Control dinamai demikian?


98

Kata-kata invertatau controltidak digunakan sama sekali untuk mendefinisikan Pembalikan Kontrol dalam definisi yang saya lihat.

Definisi

Wikipedia

inversion of control (IoC) adalah teknik pemrograman, diekspresikan di sini dalam hal pemrograman berorientasi objek, di mana kopling objek terikat pada saat dijalankan oleh objek assembler dan biasanya tidak dikenal pada waktu kompilasi menggunakan analisis statis. ~ http://en.wikipedia.org/wiki/Inversion_of_control

Martin Fowler

Inversion of Control adalah pola umum dalam komunitas Jawa yang membantu menyambungkan kontainer ringan atau merakit komponen dari berbagai proyek ke dalam aplikasi yang kohesif. ~ berdasarkan http://www.martinfowler.com/articles/injection.html (ditulis ulang)


Jadi mengapa Inversion of Control bernama Inversion of Control? Kontrol apa yang dibalik dan oleh apa? Apakah ada cara untuk mendefinisikan Inversion of Control menggunakan terminologi: invert and control ?


22
Alat peraga untuk orang yang dapat menjelaskan ini dalam bahasa Inggris yang sederhana.
Robert Harvey

2
Jika definisi menggunakan kata yang didefinisikan, itu akan menjadi kegagalan kamus. Logika serupa berlaku di sini.
Izkata

2
Lihat juga di StackOverflow: Apa itu Pembalikan Kontrol?
Izkata

2
@Izkata, sangat umum bagi kamus untuk mendefinisikan frasa dalam istilah frasa itu sendiri atau frasa sinonim. yaitu: force of nature definition menggunakan kata force dan nature dalam definisinya atau ketentuan definisi layanan menggunakan kata-kata aturan dan layanan di mana aturan bersinonim dengan istilah.
Korey Hinton

3
Saya lebih suka menggunakan istilah "injeksi ketergantungan otomatis" atau ADI daripada IoC, untuk alasan ini; Fowler sendiri menyebutkan bahwa sebagian besar paradigma saat ini dalam pemrograman memiliki semacam "inversi kontrol", di mana istilah itu didefinisikan secara umum sebagai "pelepasan penentuan kode yang akan dieksekusi dan waktu di mana ia harus dieksekusi ke eksternal mengendalikan sistem, ketika penentuan seperti itu secara tradisional dibuat oleh program itu sendiri ". Semuanya mulai dari gangguan perangkat keras hingga pemrograman yang dipandu acara hingga mesin virtual dan multitasking terjadi dengan IoC.
KeithS

Jawaban:


67

Katakanlah Anda memiliki semacam kelas "repositori", dan repositori itu bertanggung jawab untuk memberikan data kepada Anda dari sumber data.

Repositori dapat membuat koneksi ke sumber data dengan sendirinya. Tetapi bagaimana jika itu memungkinkan Anda untuk mengirim koneksi ke sumber data melalui konstruktor repositori?

Dengan mengizinkan pemanggil menyediakan koneksi, Anda telah memisahkan ketergantungan koneksi sumber data dari kelas repositori, yang memungkinkan sumber data apa pun bekerja dengan repositori, bukan hanya yang ditentukan repositori.

Anda memiliki kontrol terbalik dengan menyerahkan tanggung jawab untuk membuat koneksi dari kelas repositori ke pemanggil.

Martin Fowler menyarankan menggunakan istilah "Injeksi Ketergantungan" untuk menggambarkan jenis Pembalikan Kontrol ini, karena Pembalikan Kontrol sebagai konsep dapat diterapkan secara lebih luas daripada hanya menyuntikkan dependensi dalam metode konstruktor.


3
Ini adalah contoh injeksi ketergantungan, tetapi injeksi ketergantungan hanya bagian dari inversi kontrol. Ada hal-hal lain yang sama sekali tidak terkait dengan injeksi ketergantungan yang mempraktikkan inversi kontrol.
dsw88

1
@ mustang2009cobra: Terima kasih. Contohnya adalah apa yang saya kejar, bukan katalog contoh yang komprehensif di mana itu terjadi, dan istilah "Inversion of Control" yang paling dekat dikaitkan dengan DI, bukan pesan yang lewat atau konsep serupa lainnya.
Robert Harvey

Benar, injeksi ketergantungan adalah contoh paling umum dari IoC, jadi contoh DI paling masuk akal. Mungkin perubahan kecil pada jawaban Anda yang menyatakan bahwa ini adalah contoh DI, yang merupakan jenis IoC yang paling menonjol?
dsw88

1
Ini persis apa yang saya cari! Banyak contoh dan definisi IoC tidak secara jelas menentukan kontrol apa yang sedang dibalik. Saya menyadari bahwa mungkin ada lebih banyak untuk IOC daripada injeksi ketergantungan, tetapi sekarang sesuatu akhirnya diklik di otak saya. Terima kasih!
Korey Hinton

79

Saya tidak berpikir ada yang bisa menjelaskannya lebih baik daripada Martin Fowler, lebih jauh ke bawah artikel yang Anda tautkan .

Untuk jenis wadah yang baru ini, inversinya adalah tentang bagaimana mereka mencari implementasi plugin. Dalam contoh naif saya lister melihat implementasi finder dengan langsung instantiate. Ini menghentikan finder dari menjadi plugin. Pendekatan yang digunakan oleh wadah ini adalah untuk memastikan bahwa setiap pengguna plugin mengikuti beberapa konvensi yang memungkinkan modul assembler terpisah untuk menyuntikkan implementasi ke dalam lister.

Ketika dia menjelaskan dalam paragraf di atas bahwa, ini tidak persis sama dengan alasan istilah "Pembalikan Kontrol" berasal.

Ketika wadah ini berbicara tentang bagaimana mereka sangat berguna karena mereka menerapkan "Inversion of Control" saya akhirnya sangat bingung. Pembalikan kontrol adalah karakteristik umum dari kerangka kerja, sehingga mengatakan bahwa kontainer ringan ini istimewa karena mereka menggunakan inversi kontrol seperti mengatakan mobil saya istimewa karena memiliki roda.

Pertanyaannya, apakah aspek kontrol apa yang mereka inverting? Ketika saya pertama kali berlari ke inversi kontrol, itu di kontrol utama antarmuka pengguna. Antarmuka pengguna awal dikendalikan oleh program aplikasi. Anda akan memiliki urutan perintah seperti "Masukkan nama", "masukkan alamat"; program Anda akan mengarahkan perintah dan mengambil respons untuk masing-masing. Dengan antarmuka grafis (atau bahkan berbasis layar), kerangka UI akan berisi loop utama ini dan program Anda akan menyediakan event handler untuk berbagai bidang pada layar. Kontrol utama program terbalik, pindah dari Anda ke kerangka kerja.

Itulah sebabnya ia melanjutkan dengan istilah "Injeksi Ketergantungan" untuk mencakup implementasi khusus Pembalikan Kontrol ini.

Akibatnya saya pikir kita perlu nama yang lebih spesifik untuk pola ini. Inversion of Control adalah istilah yang terlalu umum, dan dengan demikian orang menganggapnya membingungkan. Sebagai hasil dengan banyak diskusi dengan berbagai advokat IoC, kami memilih nama Dependency Injection.

Untuk sedikit memperjelas: Pembalikan Kontrol berarti segala sesuatu yang membalikkan struktur kontrol suatu program dari desain prosedural klasik.

Di masa lalu, contoh utama dari ini adalah membiarkan kerangka menangani komunikasi antara UI dan kode Anda, daripada meninggalkan kode Anda untuk menghasilkan UI secara langsung.

Dalam waktu yang lebih baru (ketika kerangka kerja seperti itu cukup banyak mendominasi, jadi pertanyaannya tidak lagi relevan), contohnya adalah membalikkan kontrol atas instantiasi objek.

Fowler, dan yang lainnya, memutuskan bahwa istilah Inversion of Control mencakup terlalu banyak teknik dan kami membutuhkan istilah baru untuk contoh spesifik objek Instansiasi (Injeksi Ketergantungan) tetapi, pada saat perjanjian telah dibuat, frasa "IoC Container "telah lepas landas.

Ini sangat mengotori air, karena wadah IoC adalah jenis Injeksi Ketergantungan khusus, tetapi Injeksi Ketergantungan adalah jenis Pembalikan Kontrol tertentu. Inilah sebabnya mengapa Anda mendapatkan jawaban yang membingungkan, di mana pun Anda melihat.


4
Saya biasanya tidak memberikan suara sebanyak itu, tetapi ini adalah jawaban yang bagus. 1 suara tidak akan cukup. :(
RJD22

1
jawaban ini benar-benar menjawab semua pertanyaan IOC dan kebingungan DI.
Ali Umair

32

Inilah program aliran kontrol "biasa" yang biasanya diikuti:

  • Jalankan perintah secara berurutan
  • Anda mempertahankan kontrol atas aliran kontrol program

Pembalikan Kontrol "membalikkan" aliran kontrol itu, yang berarti ia membalikkan kepalanya:

  • Program Anda tidak lagi mengontrol arus. Daripada memanggil perintah sesuai keinginan Anda , Anda menunggu orang lain memanggil Anda .

Baris terakhir itu yang penting. Alih-alih memanggil orang lain ketika Anda menginginkannya, orang lain memanggil Anda ketika mereka menginginkannya.

Contoh umum dari ini adalah kerangka kerja web seperti Rails. Anda mendefinisikan Pengontrol, tetapi Anda tidak benar-benar memutuskan kapan mereka dipanggil. Rails memanggil mereka ketika memutuskan ada kebutuhan.


19
[masukkan lelucon "wajib dalam Soviet" di sini]
Robert Harvey

2
Mengesampingkan, apa yang saya pikir Anda gambarkan lebih seperti pesan lewat, yang telah menjadi pokok OO selama beberapa dekade.
Robert Harvey

3
@JimmyHoffa - Ini tidak salah sama sekali - lihat di sini . Inversi kontrol adalah konsep yang lebih umum daripada menciptakan dependensi, dan injeksi dependensi hanyalah salah satu bentuk IoC.
Lee

7
@JimmyHoffa: Saya tidak setuju. Ini adalah definisi yang benar tentang Inversion of Control sebagai jawaban Anda atau jawaban Robert, yang merupakan kebingungan yang dijelaskan Fowler ketika membuat frase Dependency Injection (yang Anda berdua sebut IoC).
pdr

5
Saya setuju dengan pernyataan ini oleh @pdr: "Pembalikan Kontrol berarti segala sesuatu yang membalikkan struktur kontrol program dari desain prosedural klasik." Itulah yang saya gambarkan, dan itu adalah inversi kontrol generik. Ketergantungan injeksi adalah jenis IoC, tapi itu bukan satu-satunya hal yang mempraktikkan
IoC

13

Ini tentang siapa yang mengendalikan Instansiasi dependensi.

Secara tradisional, ketika suatu kelas / metode perlu menggunakan kelas lain (dependensi), ia dipakai oleh kelas / metode secara langsung. Ia mengontrol dependensinya.

Dengan Inversion of Control (IoC), penelepon meneruskan dependensi, oleh karena itu instantiates dependensi. Penelepon mengontrol dependensi.

Kontrol di mana dependensi adalah instantiated telah terbalik - alih-alih berada di "bawah", di mana kode yang membutuhkannya, itu dipakai di "atas", di mana kode yang membutuhkannya dipanggil.


1
Bukan bahasa Inggris biasa. Gagal.
Robert Harvey

2
@RobertHarvey - bagaimana polosnya?
Oded

4
@RobertHarvey Huh? Ini terlihat cukup jelas bagi saya ... Apa yang tidak jelas? Kata "instantiation" atau "dependensi"?
Jimmy Hoffa

@JimmyHoffa: Lihat jawaban saya, yang memberikan contoh spesifik. IoC adalah salah satu istilah bermasalah yang digunakan semua orang tetapi tidak ada yang menjelaskan; orang menggunakan wadah IoC dalam program yang tidak mengharuskannya karena mereka salah paham. Yang mengatakan, saya pikir jawaban ini memiliki beberapa suntingan ninja. :)
Robert Harvey

Ini dan pos menjadi @ dsw88 di atas cukup sederhana bagi saya. Dengar, jika aku belum pernah mendengar tentang IoC, aku akan secara intuitif berpikir "Oh, di mana siapa yang bisa mengendalikan sesuatu membalik dari satu sisi ke sisi lain". Kerja bagus untuk ini!
Oliver Williams

2

Biasanya panggilan kode tingkat lebih tinggi (yaitu, kontrol) kode tingkat lebih rendah. Fungsi panggilan utama () (), fungsi () panggilan libraryFunction ().

Itu bisa dibalik, jadi fungsi pustaka tingkat rendah di bagian bawah memanggil fungsi tingkat lebih tinggi.

Kenapa kamu ingin melakukan itu? Middleware. Terkadang Anda ingin mengontrol level atas dan level bawah, tetapi ada banyak pekerjaan di tengah yang tidak ingin Anda lakukan. Mengambil pelaksanaan quicksort di C stdlib . Anda memanggil quicksort di tingkat atas. Anda memberikan qsort () pointer fungsi ke fungsi Anda sendiri yang mengimplementasikan komparator pada apa pun yang Anda suka. Ketika qsort () dipanggil, ia memanggil fungsi pembanding ini. qsort () mengendalikan / memanggil / mengarahkan fungsi tingkat tinggi Anda.


1

Berikut ini ikhtisar sederhana:

  1. Kontrol mengacu pada apa yang dilakukan program selanjutnya
  2. Di tingkat atas, biasanya ada dua hal yang mengontrol kontrol: aplikasi itu sendiri dan pengguna

Di masa lalu, kontrol dimiliki oleh aplikasi pertama dan pengguna kedua. Jika aplikasi membutuhkan sesuatu dari pengguna, itu akan berhenti dan bertanya dan kemudian beralih ke tugas berikutnya. Interaksi pengguna sebagian besar menyediakan data daripada mengontrol apa yang dilakukan aplikasi selanjutnya. Ini agak asing bagi kita saat ini karena kita jarang melihat jenis perilaku ini.

Jika kami beralih itu dan memberikan kontrol utama pengguna, maka kami telah membalikkan kontrol. Ini berarti bahwa alih-alih pengguna menunggu aplikasi untuk memberikannya sesuatu untuk dilakukan, aplikasi duduk menunggu pengguna untuk memberikannya sesuatu untuk dilakukan. GUI adalah contoh yang bagus untuk ini dan hampir semua hal dengan loop acara memiliki kontrol terbalik.

Perhatikan bahwa contoh saya ada di tingkat atas dan konsep inversi kontrol ini dapat diabstraksikan ke berbagai lapisan kontrol dalam aplikasi (mis. Injeksi ketergantungan). Inilah sebabnya mengapa sangat sulit untuk mendapatkan jawaban langsung.


0

Mari kita coba memahaminya melalui dua contoh.

Contoh 1

Pada hari-hari sebelumnya, aplikasi yang digunakan untuk membuat perintah meminta untuk menerima input pengguna satu demi satu. Saat ini, kerangka kerja UI membuat berbagai elemen UI, mengulang berbagai peristiwa elemen UI tersebut (seperti mouse hover, klik dll.) Dan program pengguna / utama menyediakan pengait (misalnya pendengar acara UI di Jawa) untuk mendengarkan acara tersebut. Jadi aliran elemen utama UI "kontrol" dipindahkan dari program pengguna ke kerangka UI. Pada hari-hari sebelumnya, itu dalam program pengguna.

Contoh 2

Pertimbangkan kelas di CustomerProcessorbawah ini:

class CustomerProcessor
{
    SqlCustRepo custRepo = new SqlCustRepo(); 
    private void processCustomers()
    {
            Customers[] custs = custRepo.getAllCusts();
    }
}

Jika saya ingin processCustomer()mandiri dari implementasi apa pun getAllCusts(), tidak hanya dari yang disediakan oleh SqlCustRepo, saya akan perlu menyingkirkan garis: SqlCustRepo custRepo = new SqlCustRepo()dan menggantinya dengan sesuatu yang lebih umum, mampu menerima beragam jenis implementasi, sehingga processCustomers()hanya akan bekerja untuk implementasi yang disediakan. Kode di atas (instantiating class yang diperlukan SqlCustRepooleh logika program utama) adalah cara tradisional dan tidak mencapai tujuan decoupling processCustomers()dari implementasi getAllCusts(). Dalam inversi kontrol, wadah instantiates kelas implementasi yang diperlukan (seperti yang ditentukan oleh, katakanlah konfigurasi xml), menyuntikkannya dalam logika program utama yang akan terikat sesuai kait yang ditentukan (misalnya dengan @Autowiredpenjelasan atau getBean()metode dalam kerangka kerja pegas).

Mari kita lihat bagaimana ini bisa dilakukan. Pertimbangkan kode di bawah ini.

Config.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean id="custRepo" class="JsonCustRepo" />
</beans>

CustRepo.java

interface ICustRepo 
{ ... }

JsonCustRepo.java

class JsonCustRepo implements CustRepo
{ ... }

App.java

class App
{
    public static void main(String[] args) 
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("Config.xml");
        ICustRepo custRepo = (JsonCustRepo) context.getBean("custRepo");
    }
}

Kita juga bisa punya

class GraphCustRepo implements ICustRepo { ... }   

dan

<bean id="custRepo" class="GraphCustRepo">

dan kita tidak perlu mengubah App.java.

Di atas wadah (yang merupakan kerangka pegas) memiliki tanggung jawab untuk memindai file xml, membuat instance kacang jenis tertentu dan menyuntikkannya ke dalam program pengguna. Program pengguna tidak memiliki kontrol pada kelas mana yang dipakai.

PS: IoC adalah konsep umum dan dicapai dengan banyak cara. Contoh di atas mencapainya dengan injeksi ketergantungan.

Referensi: Artikel Martin Fowler .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.