Я использую стороннюю библиотеку. Они передают мне 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, ограничивая его распространение во всей моей системе. Однако ... это решение GROSS! В Чистом Коде, страница 40:
Более трех аргументов (полиадические) требуют особого обоснования, и их не следует использовать в любом случае.
Вещи, которые я рассмотрел:
- Создание фабричного объекта, а не статического вспомогательного метода
- Не решить проблему с баджиллионными аргументами
- Создание подкласса DataTypeOne и DataTypeTwo с зависимым конструктором
- Все еще имеет конструктор с полиадной защитой
- Создайте совершенно отдельные реализации, которые соответствуют одному и тому же интерфейсу
- Множество вышеперечисленных идей одновременно
Как справиться с этой ситуацией?
Обратите внимание, что это не ситуация с антикоррупционным уровнем . Нет ничего плохого в их API. Проблемы:
- Я не хочу, чтобы мои структуры данных имели
import com.third.party.library.SomeDataStructure;
- Я не могу построить их структуры данных в моих тестовых примерах
- Мое текущее решение приводит к очень очень большому количеству аргументов. Я хочу, чтобы количество аргументов было низким, БЕЗ передачи их структур данных.
- Этот вопрос « что такое антикоррупционный слой?». Мой вопрос: « Как я могу использовать шаблон, любой шаблон, чтобы решить этот сценарий?»
Я также не прошу код (в противном случае этот вопрос был бы о SO), я просто спрашиваю достаточно ответа, чтобы я мог эффективно написать код (который этот вопрос не предоставляет).
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.