Я використовую сторонню бібліотеку. Вони передають мені POJO, яке, зважаючи на наші наміри та цілі, можливо, реалізується так:
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.
}
З багатьох причин, включаючи, але не обмежуючись тим, щоб капсулювати їх API та полегшити тестування одиниць, я хочу обернути їхні дані. Але я не хочу, щоб мої основні класи залежали від їх даних (знову ж таки, з тестових причин)! Тож зараз у мене є щось подібне:
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;
}
}
І тоді це:
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();
);
}
}
Цей клас адаптерів поєднується з іншими кількома класами, які ПОВИНЕН знати про API сторонніх виробників, обмежуючи його поширеність через решту моєї системи. Однак ... це рішення ВІДКРИТЕ! У Чистому коді, стор. 40:
Більше трьох аргументів (поліадичних) вимагає дуже спеціального обґрунтування - і тоді їх не слід використовувати.
Речі, які я врахував:
- Створення фабричного об'єкта, а не статичний метод помічника
- Це не вирішує проблему з аргументом мільйона
- Створення підкласу DataTypeOne та DataTypeTwo, який має залежний конструктор
- Досі має поліадний захищений конструктор
- Створіть цілком окремі реалізації, які відповідають одному інтерфейсу
- Кілька перерахованих вище ідей одночасно
Як слід вирішувати цю ситуацію?
Зауважте, це не антикорупційний рівень . З їх API немає нічого поганого. Проблеми:
- Я не хочу, щоб мої структури даних мали
import com.third.party.library.SomeDataStructure;
- Я не можу побудувати їх структуру даних у своїх тестових випадках
- Моє поточне рішення призводить до дуже високих підрахунків аргументів. Я хочу, щоб кількість аргументів залишалася низькою, БЕЗ передачі їхніх структур даних.
- Це питання " що таке антикорупційний шар?". Моє запитання: " як я можу використовувати шаблон, будь-яку схему для вирішення цього сценарію?"
Я також не прошу коду (інакше це питання буде на ЗО), просто прошу достатньо відповіді, щоб я міг ефективно написати код (чого це питання не передбачає).
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.