Uso una libreria di terze parti. Mi passano un POJO che, per i nostri intenti e scopi, è probabilmente implementato in questo modo:
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.
}
Per molte ragioni, incluso ma non limitato all'incapsulamento della loro API e alla facilitazione del test unitario, voglio racchiudere i loro dati. Ma non voglio che le mie classi principali dipendano dai loro dati (di nuovo, per motivi di test)! Quindi in questo momento ho qualcosa del genere:
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;
}
}
E poi questo:
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();
);
}
}
Questa classe dell'adattatore è accoppiata con le altre poche classi che DEVONO conoscere l'API di terze parti, limitando la sua pervasività attraverso il resto del mio sistema. Tuttavia ... questa soluzione è LORDA! In Codice pulito, pagina 40:
Più di tre argomenti (poliadici) richiedono una giustificazione molto speciale - e quindi non dovrebbero essere usati comunque.
Cose che ho considerato:
- Creazione di un oggetto factory anziché un metodo di supporto statico
- Non risolve il problema di avere un bajillion di argomenti
- Creazione di una sottoclasse di DataTypeOne e DataTypeTwo che ha un costruttore dipendente
- Ha ancora un costruttore poliadico protetto
- Crea implementazioni completamente separate conformi alla stessa interfaccia
- Molteplici delle idee precedenti contemporaneamente
Come dovrebbe essere gestita questa situazione?
Nota che questa non è una situazione di livello anticorruzione . Non c'è niente di sbagliato con la loro API. I problemi sono:
- Non voglio che le MIE strutture dati abbiano
import com.third.party.library.SomeDataStructure;
- Non riesco a costruire le loro strutture di dati nei miei casi di test
- La mia soluzione attuale ha come risultato conteggi di argomenti molto elevati. Voglio mantenere bassi i conteggi degli argomenti, SENZA passare nelle loro strutture di dati.
- Quella domanda è " cos'è uno strato anticorruzione?". La mia domanda è " come posso usare un modello, qualsiasi modello, per risolvere questo scenario?"
Nemmeno io sto chiedendo il codice (altrimenti questa domanda sarebbe su SO), sto solo chiedendo abbastanza di una risposta per permettermi di scrivere il codice in modo efficace (che quella domanda non fornisce).
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.