Yolsuzlukla Mücadele katmanı nedir ve nasıl kullanılır?


151

Yolsuzlukla Mücadele katmanının gerçekte ne anlama geldiğini bulmaya çalışıyorum. Eski kodlar veya hatalı API'ler arasında geçiş yapmanın / çalışmanın bir yolu olduğunu biliyorum. Anlamadığım şey, nasıl çalıştığı ve istenmeyen katmandan temiz bir ayrılık kılan şey.

Bazı araştırmalar yaptım, ancak basit örnekler veya açıklamalar bulamıyorum, bu yüzden onu anlayan ve basit örneklerle açıklayabilen birini arıyorum. Sorumu tatmin edecek bir cevap basit olmalı (mutlaka kısa olmamalıdır) ve anlaşılabilir uygulama ve kullanım örnekleri sağlamalıdır.

Kullanım davam için bu soruya bakın .

Yanıtlar:


147

Aşağıda gösterildiği gibi tasarlanmış bir başkasının kodunu kullanmanız gerektiğini düşünün:

    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) { /* ... */ }
    }

Şimdi, ona bağlı olan kodunuzun aşağıdaki gibi göründüğünü öğrendiğinizi hayal edin:

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?
}

... ve özellikle uygulamanız için gerekmeyen parametrelerin tekrarlayan kullanımından kurtulmak için, özellikle kullanımını kolaylaştırmak istediğinizde.

Tamam, yolsuzlukla mücadele katmanı oluşturmaya başladınız.

  1. İlk olarak, "ana kod" unun Messydoğrudan atıfta bulunmadığından emin olmaktır . Örneğin, bağımlılık yönetimini erişmeye çalışmak Messyderlenmeyecek şekilde düzenlersiniz .

  2. İkincisi, yalnızca Messysizin için daha iyi anlaşılır bir şekilde erişen ve onu "ana kodunuza" maruz bırakan özel bir "katman" modülü oluşturursunuz .

Katman kodu aşağıdaki gibi görünür:

    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); }
    }

Sonuç olarak, "ana kodunuz" bunun yerine, aşağıdakileri Messykullanarak Reasonablekarışmaz:

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");
}

Hala biraz karışıklık olduğunu unutmayın, Messyancak bu şimdi oldukça derinlere gizlenmiş durumda Reasonableve bu da “ana kodunuzu” oldukça temiz ve doğrudan Messyeşyaların kullanabileceği yolsuzluklardan arınmış bir hale getiriyor .


Yukarıdaki örnek, C2 wiki'de Yolsuzlukla Mücadele Katmanı'nın nasıl açıklandığına dayanmaktadır :

Uygulamanızın bir veritabanıyla veya modeli kendi uygulamanız içinde istediğiniz modele uygun olmayan veya uygulanamayan başka bir uygulama ile ilgilenmesi gerekiyorsa, bu modele ve kendinize ait olandan çevirmek için bir AnticorruptionLayer kullanın.

Not örneği, açıklamayı kısa tutmak için kasıtlı olarak basit ve yoğun yapılmıştır.

Yolsuzlukla mücadele katmanının arkasını kapsayacak daha geniş bir API karmaşasına sahipseniz aynı yaklaşım geçerlidir: ilk önce, "ana kod" un bozuk parçalara doğrudan ve ikinci olarak erişmediğinden emin olun, daha fazlasını ortaya çıkarın kullanım bağlamında uygun.

Katmanınızı yukarıdaki basitleştirilmiş bir örneğin ötesine ölçeklerken, API'nizi uygun kılmanın önemsiz bir iş olmadığını unutmayın. Bir yatırım çaba için sizin katman doğru yolu tasarımı ile hedeflenen kullanımı doğrulamak birim testler vb

Başka bir deyişle, API'nizin gizlenenden daha iyi bir gelişme olduğundan emin olun, yalnızca başka bir yolsuzluk katmanını tanıtmamaya dikkat edin.


Bütünlüğün uğruna, bu ve ilgili modeller Adaptör ve Cephe arasındaki ince ama önemli bir fark dikkat edin . Adından da anlaşılacağı gibi, yolsuzlukla mücadele katmanı, altta yatan API'nin kalite sorunlarına ("bozuk") sahip olduğunu ve söz konusu sorunların korunmasını sağlama niyetinde olduğunu varsaymaktadır .

Sen Bunu şu şekilde düşünebilirsiniz: Eğer onun işlevselliğini açığa daha iyi olacağını kütüphane tasarımcısı haklı eğer Reasonableyerine Messy, bu, yolsuzlukla katmanda çalışan yapıyoruz anlamına geleceğini kendi işini, sabitleme kendi tasarım hatalarını.

Buna karşılık Adaptör ve Cephe , altta yatan tasarımın kalitesi hakkında varsayımlarda bulunmaz. Bunlar başlangıçta iyi tasarlanmış API'ye uygulanabilir, sadece sizin özel gereksinimlerinize uyarlar.

Aslında, Adaptör ve Cephe gibi kalıpların temel kodun iyi tasarlanmış olmasını beklediğini varsaymak daha verimli olabilir . Bunu şu şekilde düşünebilirsiniz: iyi tasarlanmış kod, belirli kullanım durumları için ince ayar yapmak çok zor olmamalıdır. Bağdaştırıcınızın tasarımının beklenenden daha fazla çaba harcadığı ortaya çıkarsa, bu, temel kodun bir şekilde "bozuk" olduğunu gösterebilir. Bu durumda, işi aşamalara ayırmayı düşünebilirsiniz: ilk önce, temel API'yi uygun şekilde yapılandırılmış bir şekilde sunmak için bir bozulma önleyici katman oluşturun ve ardından bağdaştırıcınızı / cephenizi o koruma katmanı üzerinde tasarlayın.


1
Bağımlı API sınıflarının bütün bir yapısı varsa, bu ölçek nasıl? Uygulamanın geri kalanını koruduğu tabakadan daha yönetilebilir mi?
Bilinenasilya

1
@Knownasilya bu çok iyi bir soru, cevap bu hitap etmek için genişledi
gnat

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.Tüm bölüm cesur bir etikete layık.
Lilienthal,

19
Yolsuzlukla mücadele katmanları, düşük kaliteli API'lerle başa çıkmakla ilgili değildir. Kavramsal uyumsuzluklarla uğraşmak, sadece kodumuzu "bozmak" suretiyle kullanabileceğimiz etki alanlarını daha kolay kullanabileceğimiz etki alanlarına uyarlamakla ilgilidir.
Ian Fairman

8
Ian Fairman haklı buldu, bu cevabın yazarı kesinlikle yapmadı. Konseptin kaynağına giderseniz (DDD kitabı), bu cevaba aykırı en az iki şey bulacaksınız: 1) öğelerle geliştirdiğimiz yeni alan modelinin bozulmasını önlemek için bir yolsuzlukla mücadele katmanı oluşturuldu mevcut bir dış sistem modelinden; diğer sistemin “bozuk” olması değildir, aslında tamamen iyi ve iyi tasarlanmış olabilir; 2) bir anti-bozulması tabaka , genellikle çoğu kez çeşitli sınıflar içerecektir dahil Cepheler ve Adaptörler gibi, Hizmetleri .
Rogério

41

Başka bir kaynaktan alıntı yapmak için:

Müşterilere kendi etki alanı modellerinde işlevsellik sağlamak için bir yalıtım katmanı oluşturun. Katman, diğer sistemde çok az değişiklik yapmayı veya hiç değişiklik yapmayı gerektirmeden mevcut arayüzüyle diğer sistemle konuşur. Dahili olarak, katman iki model arasında gerektiğinde her iki yönde de çeviri yapar.

Eric Evans, Domain Driven Design, 16. baskı, sayfa 365

En önemlisi, yolsuzlukla mücadele katmanının her iki tarafında farklı terimlerin kullanılmasıdır. Bir zamanlar nakliye lojistiği için bir sistem üzerinde çalışıyordum. Mermiler planlanmalıydı. Aracı bir depoya yerleştirmeniz, farklı müşteri sitelerine gitmeniz ve onlara hizmet vermeniz ve bir tank durağı gibi diğer yerleri ziyaret etmeniz gerekiyordu. Ancak, üst seviyeden itibaren tüm bunlar görev planlama ile ilgiliydi. Bu nedenle, daha genel görev planlama terimlerini çok spesifik nakliye lojistiği terimlerinden ayırmak mantıklıydı.

Dolayısıyla, yolsuzlukla mücadele katmanlarının yalıtılması, yalnızca sizi dağınık kodlardan korumakla ilgili değil, farklı alanları ayırmak ve gelecekte ayrılmalarını sağlamakla da ilgilidir.


6
Bu çok önemli! Bir ACL yalnızca Messy kodu ile kullanılmayacak, aynı zamanda sınırlı bağlamlar arasında iletişim kurmanın bir aracı olarak kullanılacaktır. Bir bağlamdan diğerine çeviri yapar, böylece her bağlamdaki veriler dili ve bu bağlamın veriler hakkında düşünme ve konuşma şeklini yansıtır.
Didier A.

29

adaptör

Birbirini diğerine adapte etmek için, benzer mantık uygulayan uyumlu olmayan arayüzleriniz varsa, birinin uygulamalarını diğerini bekleyen şeyler ile birlikte kullanabilirsiniz.

Örnek:

Araba isteyen bir nesneniz var, ancak yalnızca 4WheelVehicle sınıfınız var, bu yüzden bir CarBuiltUsing4WheelVehicle yaratıp bunu Arabanız olarak kullanıyorsunuz.

Cephe

Karmaşık / kafa karıştırıcı / devasa bir API'niz olduğunda ve daha basit / daha net / daha küçük yapmak istediğinizde. Karmaşıklığı / karışıklığı / ekstraları gizlemek ve sadece basit / temiz / küçük bir API göstermek için bir Cephe oluşturacaksınız.

Örnek:

100 yöntemi olan bir kütüphane kullanıyorsunuz ve belirli bir görevi gerçekleştirmek için bir sürü başlatma, bağlantı kurma, açma / kapama, sadece sonunda istediğinizi yapabilmeniz için ihtiyacınız olan her şeyi yapmanız gerekiyor. 50 kütüphanenin tümünde yapabiliyor, böylece sadece ihtiyacınız olan 1 özellik için bir yönteme sahip olan ve sizin için tüm başlatma, temizleme vb. işlemleri yapan bir Cephe oluşturursunuz.

Yolsuzlukla Mücadele Katmanı

Etki alanınızın dışında bir sisteminiz varsa, ancak iş gereksinimleriniz o etki alanıyla çalışmanızı gerektirir. Bu diğer etki alanını kendinize tanıtmak istemezsiniz, bu nedenle onu bozar, böylece etki alanınızın kavramını, bu diğer etki alanına ve bunun tersine çevirirsiniz.

Örnek:

Bir sistem, her bir işlem için bir isim ve bir dizi dizeye sahip olan müşteriyi izler. Profilleri, bir adı olan tek başına sınıflar ve İşlemleri bir dize olan tek başına sınıflar ve Müşteri, bir Profili ve İşlemler koleksiyonu olarak görürsünüz.

Böylece Müşterinizle diğer sistemin Müşterisi arasında çeviri yapmanıza izin verecek bir ACL katmanı yaratırsınız. Bu şekilde, asla diğer sistemin Müşterisini kullanmak zorunda kalmazsınız, ACL'ye söylemeniz gerekir: "Bana Profil X ile Müşteriyi verin ve ACL diğer sisteme X.name Müşterisinin adını vermesini söyler ve iade eder. Profil X ile bir Müşteri

====================

Üçü de nispeten benzer, çünkü hepsi dolaylı kalıplar. Ancak farklı yapılara, sınıflara / nesnelere karşı API'lere karşı modüllere / alt sistemlere yöneliktirler. Gerekirse hepsini birleştirebilirsin. Alt sistem karmaşık bir API'ye sahiptir, bu nedenle bir FACADE oluşturur, farklı bir model kullanır, bu nedenle modelinize uymayan her veri gösterimi için, bu verileri tekrar nasıl modellediğinize çevirirsiniz. Son olarak, belki arayüzler de uyumsuzdur, bu yüzden birinden diğerine uyum sağlamak için ADAPTÖRLER kullanırsınız.


12

Buradaki birçok cevap, ACL'lerin dağınık kodu sarmalama konusunda "sadece" olmadığını söylüyor. Daha ileri gidip bununla hiç alakası olmadığını söylerdim ve eğer yaparlarsa bu bir yan faydadır.

Yolsuzlukla mücadele katmanı, bir etki alanını diğerine eşlemektir, böylece ikinci etki alanını kullanan hizmetlerin ilk önce gelen kavramlar tarafından "bozulmasına" gerek kalmaz. ACL'ler, bağdaştırıcıların sınıflara ne olduğunu etki alanı modellemektir, farklı bir düzeyde gerçekleşir. Bağdaştırıcı tartışmasız en önemli tasarım kalıbıdır - her zaman kullanırım - ama sarılmış sınıfı dağınık veya dağınık olarak değerlendirmek önemsizdir. Ne olduğu, farklı bir arayüze sahip olmam gerek.

Dağınıklığa odaklanmak yanıltıcıdır ve DDD'nin ne anlama geldiğini özlüyor. ACL'ler, kalitesiz değil, kavramsal uyumsuzluklarla ilgilenmekle ilgilidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.