Baru-baru ini saya membaca artikel Mark Seemann tentang anti-pola Service Locator.
Penulis menunjukkan dua alasan utama mengapa ServiceLocator merupakan anti-pola:
Masalah penggunaan API (yang saya baik-baik saja)
Ketika kelas menggunakan pencari Layanan, sangat sulit untuk melihat ketergantungannya karena, dalam banyak kasus, kelas hanya memiliki satu konstruktor PARAMETERLESS. Berbeda dengan ServiceLocator, pendekatan DI secara eksplisit mengekspos dependensi melalui parameter konstruktor sehingga dependensi mudah dilihat di IntelliSense.Masalah pemeliharaan (yang membuat saya
bingung ) Perhatikan contoh berikut
Kami memiliki kelas 'MyType' yang menggunakan pendekatan pencari lokasi:
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
}
}
Sekarang kami ingin menambahkan ketergantungan lain ke kelas 'MyType'
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}
}
Dan di sinilah kesalahpahaman saya dimulai. Penulis berkata:
Menjadi jauh lebih sulit untuk mengetahui apakah Anda memperkenalkan perubahan yang menghancurkan atau tidak. Anda perlu memahami seluruh aplikasi di mana Service Locator digunakan, dan compiler tidak akan membantu Anda.
Tapi tunggu sebentar, jika kita menggunakan pendekatan DI, kita akan memperkenalkan ketergantungan dengan parameter lain dalam konstruktor (dalam kasus injeksi konstruktor). Dan masalahnya akan tetap ada. Jika kita mungkin lupa menyiapkan ServiceLocator, maka kita mungkin lupa menambahkan pemetaan baru dalam wadah IoC kita dan pendekatan DI akan memiliki masalah run-time yang sama.
Juga, penulis menyebutkan tentang kesulitan tes unit. Tapi, bukankah kita memiliki masalah dengan pendekatan DI? Tidakkah kita perlu memperbarui semua tes yang membuat instance kelas itu? Kami akan memperbaruinya agar lulus dependensi baru yang dibuat-buat hanya untuk membuat pengujian kami dapat disusun. Dan saya tidak melihat manfaat apa pun dari pembaruan dan pengeluaran waktu itu.
Saya tidak mencoba mempertahankan pendekatan Service Locator. Tetapi kesalahpahaman ini membuat saya berpikir bahwa saya kehilangan sesuatu yang sangat penting. Bisakah seseorang menghilangkan keraguan saya?
UPDATE (RINGKASAN):
Jawaban untuk pertanyaan saya "Apakah Pencari Lokasi Layanan merupakan anti-pola" sangat bergantung pada keadaan. Dan saya pasti tidak akan menyarankan untuk mencoretnya dari daftar alat Anda. Ini mungkin menjadi sangat berguna ketika Anda mulai berurusan dengan kode warisan. Jika Anda cukup beruntung berada di awal proyek Anda, maka pendekatan DI mungkin merupakan pilihan yang lebih baik karena memiliki beberapa keunggulan dibandingkan Service Locator.
Dan inilah perbedaan utama yang meyakinkan saya untuk tidak menggunakan Service Locator untuk proyek baru saya:
- Paling jelas dan penting: Service Locator menyembunyikan dependensi kelas
- Jika Anda menggunakan beberapa kontainer IoC, kemungkinan akan memindai semua konstruktor saat startup untuk memvalidasi semua dependensi dan memberi Anda umpan balik langsung tentang pemetaan yang hilang (atau konfigurasi yang salah); ini tidak mungkin jika Anda menggunakan container IoC Anda sebagai Service Locator
Untuk detailnya, baca jawaban luar biasa yang diberikan di bawah ini.