I'm an obsessive follower of the DRY and KISS principles but last week I had a case where both seem to contradict each other:
For an application I was doing, I had to implement a loop for times which does the following:
Here's an example:
for (A a : listOfA) {
listOfB.add(BFactory.convertFromAToB(a));
}
Within the code, I have to do this about 4 times, convert a type (e.g. D, E etc.) into another one. I may not be able to change the types I'm about to convert, as they are 3rd party types which we have to use in out app.
So we have:
for (A a : listOfA) {
listOfB.add(BFactory.convertFromAToB(a));
}
for (C a : listOfC) {
listOfB.add(DFactory.convertFromCToD(c));
}
...
So, to not violate dry, I came up with a generic solution:
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));
}
}
A call looks something like this:
convertAndCopy(listOfA, listOfB, new Function<A, B>() {
A apply(B b) {
return CFactory.convertFromBToC(b);
}
});
Now, while this is better in terms of DRY, I think it violates KISS, as this solution is much harder to understand than the duplicated for loops.
So, is this DRY vs. KISS? Which one to favor in this context?
EDIT
Just to be clear, the class I'm talking about is an Adapter, which delegates call to a legacy system to our own implementation, converting the legacy into our own types along the way. I have no means of changing the legacy types, nor may I change our types (which are XML-Schema-generated).
The KISS principle was coined by Kelly Johnson, and it states that most systems work best if they are kept simple rather than making them complex; therefore, simplicity should be a key goal in design and unnecessary complexity should be avoided.
"Don't repeat yourself" (DRY) is a principle of software development aimed at reducing repetition of software patterns, replacing it with abstractions or using data normalization to avoid redundancy.
Either is fine.
With the loops, you are not really repeating yourself, because the only parts that are repetitive is "syntactic clutter" (and not too much of that in your case). You are not repeating/duplicating "application logic" code.
If you like the "Function" style, maybe make use of the Guava library (which has the Function interface and many helper methods that work with them on collections). That is DRY (because you don't repeat yourself, and re-use code that already exists), and still KISS (because those are well understood patterns).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With