J'utilise une bibliothèque tierce. Ils me passent un POJO qui, à nos fins et à des fins, est probablement implémenté comme ceci:
public class OurData {
private String foo;
private String bar;
private String baz;
private String quux;
// A lot more than this
// IMPORTANT: NOTE THAT THIS IS A PACKAGE PRIVATE CONSTRUCTOR
OurData(/* I don't know what they do */) {
// some stuff
}
public String getFoo() {
return foo;
}
// etc.
}
Pour de nombreuses raisons, notamment, mais sans s'y limiter, l'encapsulation de leur API et la facilitation des tests unitaires, je souhaite encapsuler leurs données. Mais je ne veux pas que mes classes de base dépendent de leurs données (encore une fois, pour des raisons de test)! Alors maintenant, j'ai quelque chose comme ça:
public class DataTypeOne implements DataInterface {
private String foo;
private int bar;
private double baz;
public DataTypeOne(String foo, int bar, double baz) {
this.foo = foo;
this.bar = bar;
this.baz = baz;
}
}
public class DataTypeTwo implements DataInterface {
private String foo;
private int bar;
private double baz;
public DataTypeOne(String foo, int bar, double baz, String quux) {
this.foo = foo;
this.bar = bar;
this.baz = baz;
this.quux = quux;
}
}
Et puis ceci:
public class ThirdPartyAdapter {
public static makeMyData(OurData data) {
if(data.getQuux() == null) {
return new DataTypeOne(
data.getFoo(),
Integer.parseInt(data.getBar()),
Double.parseDouble(data.getBaz()),
);
} else {
return new DataTypeTwo(
data.getFoo(),
Integer.parseInt(data.getBar()),
Double.parseDouble(data.getBaz()),
data.getQuux();
);
}
}
Cette classe d'adaptateur est couplée aux quelques autres classes qui DOIVENT connaître l'API tierce, ce qui limite son omniprésence dans le reste de mon système. Cependant ... cette solution est BRUTE! Dans Clean Code, page 40:
Plus de trois arguments (polyadiques) nécessitent une justification très spéciale - et ne devraient donc pas être utilisés de toute façon.
Choses que j'ai envisagées:
- Créer un objet d'usine plutôt qu'une méthode d'assistance statique
- Ne résout pas le problème d'avoir un bajillion d'arguments
- Création d'une sous-classe de DataTypeOne et DataTypeTwo qui a un constructeur dépendant
- A toujours un constructeur protégé polyadique
- Créez des implémentations entièrement distinctes conformes à la même interface
- Plusieurs des idées ci-dessus simultanément
Comment gérer cette situation?
Notez que ce n'est pas une situation de couche anti-corruption . Il n'y a rien de mal avec leur API. Les problèmes sont:
- Je ne veux pas que MES structures de données aient
import com.third.party.library.SomeDataStructure;
- Je ne peux pas construire leurs structures de données dans mes cas de test
- Ma solution actuelle se traduit par un nombre d'arguments très très élevé. Je veux garder le nombre d'arguments bas, SANS passer dans leurs structures de données.
- Cette question est " qu'est - ce qu'une couche anti-corruption?". Ma question est " comment puis-je utiliser un modèle, n'importe quel modèle, pour résoudre ce scénario?"
Je ne demande pas non plus de code (sinon cette question serait sur SO), je demande juste assez de réponse pour me permettre d'écrire le code efficacement (ce que cette question ne fournit pas).
The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification — and then shouldn’t be used anyway.