Bayangkan Anda harus menggunakan kode orang lain yang dirancang seperti yang ditunjukkan di bawah ini:
class Messy {
String concat(String param, String str) { /* ... */ }
boolean contains(String param, String s) { /* ... */ }
boolean isEmpty(String param) { /* ... */ }
boolean matches(String param, String regex) { /* ... */ }
boolean startsWith(String param, String prefix) { /* ... */ }
}
Sekarang bayangkan Anda mengetahui bahwa kode Anda yang bergantung padanya terlihat seperti berikut:
String process(String param) {
Messy messy = new Messy();
if (messy.contains(param, "whatever")) {
return messy.concat(param, "-contains");
}
if (messy.isEmpty(param)) {
return messy.concat(param, "-empty");
}
if (messy.matches(param, "[whatever]")) {
return messy.concat(param, "-matches");
}
if (messy.startsWith(param, "whatever")) {
return messy.concat(param, "-startsWith");
}
return messy.concat(param, "-whatever");
// WTF do I really need to repeat bloody "param" 9 times above?
}
... dan Anda ingin membuatnya lebih mudah digunakan, khususnya, untuk menyingkirkan penggunaan parameter berulang yang hanya tidak diperlukan untuk aplikasi Anda.
Oke, jadi Anda mulai membangun lapisan anti korupsi.
Hal pertama adalah memastikan bahwa "kode utama" Anda tidak merujuk Messy
langsung. Misalnya, Anda mengatur manajemen ketergantungan sedemikian rupa sehingga mencoba mengakses Messy
gagal dikompilasi.
Kedua, Anda membuat modul "layer" khusus yang merupakan satu-satunya yang mengakses Messy
dan mengeksposnya ke "kode utama" Anda dengan cara yang lebih masuk akal bagi Anda.
Kode lapisan akan terlihat seperti berikut:
class Reasonable { // anti-corruption layer
String param;
Messy messy = new Messy();
Reasonable(String param) {
this.param = param;
}
String concat(String str) { return messy.concat(param, str); }
boolean contains(String s) { return messy.contains(param, s); }
boolean isEmpty() { return messy.isEmpty(param); }
boolean matches(String regex) { return messy.matches(param, regex); }
boolean startsWith(String prefix) { return messy.startsWith(param, prefix); }
}
Akibatnya, "kode utama" Anda tidak mengacaukan Messy
, dengan menggunakan Reasonable
, kira-kira sebagai berikut:
String process(String param) {
Reasonable reasonable = new Reasonable(param);
// single use of "param" above and voila, you're free
if (reasonable.contains("whatever")) {
return reasonable.concat("-contains");
}
if (reasonable.isEmpty()) {
return reasonable.concat("-empty");
}
if (reasonable.matches("[whatever]")) {
return reasonable.concat("-matches");
}
if (reasonable.startsWith("whatever")) {
return reasonable.concat("-startsWith");
}
return reasonable.concat("-whatever");
}
Perhatikan bahwa masih ada sedikit kekacauan, Messy
tetapi ini sekarang tersembunyi cukup dalam Reasonable
, membuat "kode utama" Anda cukup bersih dan bebas dari korupsi yang akan dibawa ke sana dengan penggunaan langsung Messy
barang - barang.
Contoh di atas didasarkan pada bagaimana Anticorruption Layer dijelaskan di c2 wiki:
Jika aplikasi Anda perlu berurusan dengan database atau aplikasi lain yang modelnya tidak diinginkan atau tidak dapat diterapkan pada model yang Anda inginkan dalam aplikasi Anda sendiri, gunakan AnticorruptionLayer untuk menerjemahkan ke / dari model itu dan model Anda.
Catatan contoh sengaja dibuat sederhana dan ringkas untuk membuat penjelasan singkat.
Jika Anda memiliki mess-of-API yang lebih besar untuk menutupi di balik lapisan anti-korupsi, pendekatan yang sama berlaku: pertama, pastikan "kode utama" Anda tidak mengakses hal-hal yang rusak secara langsung dan kedua, buka dengan cara yang lebih nyaman dalam konteks penggunaan Anda.
Saat "menskalakan" layer Anda di luar contoh yang disederhanakan di atas, pertimbangkan bahwa membuat API Anda nyaman tidak selalu merupakan tugas sepele. Investasikan upaya untuk merancang lapisan Anda dengan cara yang benar , verifikasi penggunaan yang dimaksudkan dengan uji unit dll.
Dengan kata lain, pastikan API Anda memang lebih baik daripada yang disembunyikannya, pastikan Anda tidak hanya memperkenalkan lapisan korupsi lainnya.
Demi kelengkapan, perhatikan perbedaan halus tapi penting antara ini dan pola terkait Adapter dan Fasad . Sebagaimana ditunjukkan oleh namanya, lapisan anti korupsi mengasumsikan bahwa API yang mendasarinya memiliki masalah kualitas ("rusak") dan bermaksud menawarkan perlindungan terhadap masalah yang disebutkan.
Anda dapat memikirkannya seperti ini: jika Anda dapat membenarkan bahwa perancang perpustakaan akan lebih baik mengekspos fungsinya dengan Reasonable
alih - alih Messy
, ini berarti Anda bekerja pada lapisan anti korupsi, melakukan pekerjaan mereka , memperbaiki kesalahan desain mereka .
Berbeda dengan itu, Adaptor dan Fasad tidak membuat asumsi pada kualitas desain yang mendasarinya. Ini dapat diterapkan pada API yang dirancang dengan baik untuk memulainya, hanya mengadaptasinya untuk kebutuhan spesifik Anda.
Sebenarnya, bahkan bisa lebih produktif untuk mengasumsikan bahwa pola-pola seperti Adapter dan Facade mengharapkan kode yang mendasarinya dirancang dengan baik. Anda dapat memikirkannya seperti ini: kode yang dirancang dengan baik seharusnya tidak terlalu sulit untuk disesuaikan untuk kasus penggunaan tertentu. Jika ternyata desain adaptor Anda membutuhkan upaya lebih dari yang diharapkan, ini dapat menunjukkan bahwa kode yang mendasarinya, baik, entah bagaimana "rusak". Dalam hal ini, Anda dapat mempertimbangkan membagi pekerjaan ke fase terpisah: pertama, buat layer anti korupsi untuk menyajikan API yang mendasarinya dengan cara yang terstruktur dengan baik dan selanjutnya, desain adaptor / fasad Anda di atas lapisan perlindungan.
In other words, make sure that your API is indeed an improvement over one it hides, make sure that you don't just introduce another layer of corruption.
Seluruh bagian itu layak diberi tag tebal.Mengutip sumber lain:
Eric Evans, Desain Berbasis Domain, pencetakan ke-16, halaman 365
Yang paling penting adalah istilah yang berbeda digunakan di setiap sisi lapisan anti korupsi. Saya pernah bekerja pada sistem logistik transportasi. Putaran harus direncanakan. Anda harus melengkapi kendaraan di sebuah depo, berkendara ke lokasi pelanggan yang berbeda dan melayani mereka dan mengunjungi tempat-tempat lain, seperti berhenti tangki. Tetapi dari tingkat yang lebih tinggi, ini semua tentang perencanaan tugas. Jadi masuk akal untuk memisahkan istilah perencanaan tugas yang lebih umum dari istilah logistik transportasi yang sangat spesifik.
Jadi isolasi lapisan anti korupsi bukan hanya tentang melindungi Anda dari kode berantakan, itu adalah untuk memisahkan domain yang berbeda dan memastikan bahwa mereka tetap terpisah di masa depan.
sumber
Adaptor
Ketika Anda memiliki antarmuka yang tidak kompatibel, yang melakukan logika yang sama, untuk mengadaptasi satu ke yang lain, sehingga Anda dapat menggunakan implementasi satu dengan hal-hal yang mengharapkan yang lain.
Contoh:
Anda memiliki objek yang menginginkan mobil, tetapi Anda hanya memiliki kelas 4WheelVehicle, jadi Anda membuat CarBuiltUsing4WheelVehicle dan menggunakannya sebagai mobil Anda.
Tatapan
Ketika Anda memiliki API yang rumit / membingungkan / raksasa dan Anda ingin membuatnya lebih sederhana / lebih jelas / lebih kecil. Anda akan membuat Facade untuk menyembunyikan kompleksitas / kebingungan / ekstra dan hanya mengekspos API sederhana / jelas / kecil yang baru.
Contoh:
Anda menggunakan perpustakaan yang memiliki 100 metode, dan untuk melakukan tugas tertentu Anda perlu melakukan banyak inisialisasi, menghubungkan, membuka / menutup hal-hal, hanya untuk akhirnya dapat melakukan apa yang Anda inginkan, dan semua yang Anda inginkan adalah 1 fitur dari semua yang dapat dilakukan perpustakaan, jadi Anda membuat Fasad yang hanya memiliki metode untuk fitur 1 yang Anda butuhkan dan yang melakukan semua inisialisasi, pembersihan, dll. untuk Anda.
Lapisan Anti Korupsi
Ketika Anda memiliki sistem yang keluar dari domain Anda, namun kebutuhan bisnis Anda mengharuskan Anda untuk bekerja dengan domain lain itu. Anda tidak ingin memperkenalkan domain lain ini ke dalam domain Anda sendiri, karena itu merusaknya, sehingga Anda akan menerjemahkan konsep domain Anda, ke domain lain ini, dan sebaliknya.
Contoh:
Satu sistem memandang pelanggan yang memiliki nama dan daftar string, satu untuk setiap transaksi. Anda melihat Profil sebagai kelas yang berdiri sendiri yang memiliki nama, dan Transaksi sebagai kelas yang berdiri sendiri yang memiliki string, dan Pelanggan memiliki Profil dan kumpulan Transaksi.
Jadi, Anda membuat lapisan ACL yang akan memungkinkan menerjemahkan antara Pelanggan Anda dan Pelanggan sistem lainnya. Dengan cara ini, Anda tidak perlu menggunakan Pelanggan sistem lain, Anda hanya perlu memberi tahu ACL: "beri saya Pelanggan dengan Profil X, dan ACL memberi tahu sistem lain untuk memberi Pelanggan nama X.name, dan mengembalikannya. Anda seorang Pelanggan dengan Profil X.
====================
Ketiganya relatif sama, karena mereka semua adalah pola tipuan. Tetapi mereka membahas berbagai struktur, kelas / objek versus API versus modul / sub-sistem. Anda bisa menggabungkan semuanya jika perlu. Sub-sistem memiliki API yang kompleks, jadi Anda membangun FACADE untuknya, ia menggunakan model yang berbeda, jadi untuk setiap representasi data yang tidak sesuai dengan model Anda, Anda akan MENERJALAKAN data itu kembali ke bagaimana Anda memodelkannya. Akhirnya, mungkin antar muka juga tidak kompatibel, jadi Anda akan menggunakan ADAPTER untuk beradaptasi dari satu ke yang lain.
sumber
Banyak jawaban di sini mengatakan bahwa ACL "bukan hanya" tentang membungkus kode yang berantakan. Saya akan melangkah lebih jauh dan mengatakan mereka sama sekali bukan tentang itu, dan jika mereka melakukannya maka itu adalah keuntungan sampingan.
Lapisan anti-korupsi adalah tentang memetakan satu domain ke domain lain sehingga layanan yang menggunakan domain kedua tidak harus "rusak" oleh konsep-konsep dari yang pertama. ACL adalah untuk memodelkan domain apa adaptor untuk kelas, itu hanya terjadi pada tingkat yang berbeda. Adaptor ini bisa dibilang pola desain yang paling penting - saya menggunakannya sepanjang waktu - tetapi menilai kelas yang dibungkus itu berantakan atau tidak tidak relevan. Ini adalah apa adanya, saya hanya perlu memiliki antarmuka yang berbeda.
Memfokuskan pada kekacauan adalah menyesatkan dan meleset dari inti masalah DDD. ACL adalah tentang berurusan dengan ketidaksesuaian konseptual, bukan kualitas buruk.
sumber