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.
İlk olarak, "ana kod" unun Messy
doğrudan atıfta bulunmadığından emin olmaktır . Örneğin, bağımlılık yönetimini erişmeye çalışmak Messy
derlenmeyecek şekilde düzenlersiniz .
İkincisi, yalnızca Messy
sizin 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 Messy
kullanarak Reasonable
karış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, Messy
ancak bu şimdi oldukça derinlere gizlenmiş durumda Reasonable
ve bu da “ana kodunuzu” oldukça temiz ve doğrudan Messy
eş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 Reasonable
yerine 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.