Apa itu lapisan Anti-Korupsi, dan bagaimana cara menggunakannya?

151

Saya mencoba mencari tahu apa arti sebenarnya dari lapisan Anti-Korupsi. Saya tahu ini adalah cara untuk transisi / bekerja di sekitar kode lama atau API yang buruk. Yang tidak saya mengerti adalah cara kerjanya dan apa yang membuatnya menjadi pemisahan yang bersih dari lapisan yang tidak diinginkan.

Saya telah melakukan pencarian, tetapi saya tidak dapat menemukan contoh atau penjelasan sederhana, jadi saya mencari seseorang yang memahaminya dan dapat menjelaskannya dengan contoh sederhana. Jawaban yang akan memuaskan pertanyaan saya harus sederhana (tidak harus singkat), dan memberikan contoh implementasi dan penggunaan yang dapat dipahami.

Lihat pertanyaan ini , untuk kasus penggunaan saya.

diketahuiasilya
sumber

Jawaban:

147

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.

  1. Hal pertama adalah memastikan bahwa "kode utama" Anda tidak merujuk Messylangsung. Misalnya, Anda mengatur manajemen ketergantungan sedemikian rupa sehingga mencoba mengakses Messygagal dikompilasi.

  2. Kedua, Anda membuat modul "layer" khusus yang merupakan satu-satunya yang mengakses Messydan 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, Messytetapi ini sekarang tersembunyi cukup dalam Reasonable, membuat "kode utama" Anda cukup bersih dan bebas dari korupsi yang akan dibawa ke sana dengan penggunaan langsung Messybarang - 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 Reasonablealih - 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.

agas
sumber
1
Bagaimana skala ini jika ada seluruh struktur kelas API dependen? Apakah masih lebih mudah dikelola daripada lapisan yang melindungi sisa aplikasi?
knownasilya
1
@Knownasilya itu pertanyaan yang sangat bagus, jawabannya diperluas ke alamat itu
nyamuk
4
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.
Lilienthal
19
Lapisan anti-korupsi tidak ada hubungannya dengan berurusan dengan API berkualitas buruk. Mereka membahas tentang ketidaksesuaian konseptual, mengadaptasi domain yang hanya bisa kita gunakan dengan "merusak" kode kita ke domain yang bisa kita gunakan dengan lebih mudah.
Ian Fairman
8
Ian Fairman benar, sedangkan penulis jawaban ini jelas tidak. Jika Anda pergi ke sumber konsep (buku DDD), Anda akan menemukan setidaknya dua hal yang bertentangan dengan jawaban ini: 1) lapisan anti-korupsi dibuat untuk menghindari kerusakan model domain baru yang sedang kami kembangkan dengan elemen-elemen dari model sistem eksternal yang ada; bukan bahwa sistem yang lain "rusak", pada kenyataannya itu mungkin sangat baik dan dirancang dengan baik; 2) anti-korupsi lapisan biasanya akan berisi beberapa kelas, sering termasuk fasad dan Adaptor , serta Jasa .
Rogério
41

Mengutip sumber lain:

Buat layer isolasi untuk memberikan fungsionalitas kepada klien dalam hal model domain mereka sendiri. Lapisan berbicara ke sistem lain melalui antarmuka yang ada, membutuhkan sedikit atau tidak ada modifikasi ke sistem lain. Secara internal, layer menerjemahkan di kedua arah sebagaimana diperlukan antara kedua model.

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.

SpaceTrucker
sumber
6
Ini sangat penting! ACL tidak hanya untuk digunakan dengan kode berantakan, tetapi sebagai sarana untuk berkomunikasi antara konteks yang dibatasi. Ini menerjemahkan dari satu konteks ke yang lain, sehingga data dalam setiap konteks mencerminkan bahasa dan cara konteks itu berpikir dan berbicara tentang data.
Didier A.
29

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.

Didier A.
sumber
12

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.

Ian Fairman
sumber