Я одержимый приверженец принципов DRY и KISS, но на прошлой неделе у меня было случай, когда оба кажутся противоречащими друг другу:
Для приложения, которое я делал, мне пришлось реализовать цикл для времени, который делает следующее:
- итерация по элементам списка типа A
- преобразуйте элемент типа A в тип B и вставьте его в список типа B
Вот пример:
for (A a : listOfA) {
listOfB.add(BFactory.convertFromAToB(a));
}
Внутри кода я должен сделать это примерно 4 раза, преобразовать тип (например, D, E и т.д.) в другой. Я не могу изменить типы, которые я собираюсь преобразовать, поскольку они являются сторонними типами, которые мы должны использовать в приложении.
Итак, мы имеем:
for (A a : listOfA) {
listOfB.add(BFactory.convertFromAToB(a));
}
for (C a : listOfC) {
listOfB.add(DFactory.convertFromCToD(c));
}
...
Итак, чтобы не нарушать сухость, я придумал общее решение:
private interface Function<S, T> {
T apply(S s);
}
public <S, T> void convertAndCopy(List<S> src, List<T> dst, Function<S, T> f) {
for (S s : src) {
dst.add(f.apply(s));
}
}
Вызов выглядит примерно так:
convertAndCopy(listOfA, listOfB, new Function<A, B>() {
A apply(B b) {
return CFactory.convertFromBToC(b);
}
});
Теперь, хотя это лучше с точки зрения СУХОЙ, я думаю, что это нарушает KISS, поскольку это решение гораздо труднее понять, чем дублирование для циклов.
Итак, это DRY против KISS? Какая из них выгодна в этом контексте?
ИЗМЕНИТЬ
Просто, чтобы быть ясным, класс, о котором я говорю, является адаптером, который делегирует вызов устаревшей системе для нашей собственной реализации, превращая наследие в наши собственные типы на этом пути. У меня нет средств для изменения устаревших типов, и я не могу изменить наши типы (которые генерируются XML-Schema).