java - 当 KISS 和 DRY 碰撞时

标签 java dry

<分区>

我是 DRY 的忠实追随者和 KISS原则,但上周我遇到了一个案例,两者似乎相互矛盾:

对于我正在做的应用程序,我必须实现一个执行以下操作的时间循环:

  1. 遍历 A 类型列表的元素
  2. 将类型A的元素转换为类型B并将它们插入到类型B的列表中

这是一个例子:

for (A a : listOfA) {
    listOfB.add(BFactory.convertFromAToB(a));
}

在代码中,我必须执行大约 4 次,将一种类型(例如 D、E 等)转换为另一种类型。我可能无法更改我将要转换的类型,因为它们是我们必须在应用程序中使用的第 3 方类型。

所以我们有:

for (A a : listOfA) {
    listOfB.add(BFactory.convertFromAToB(a));
}

for (C a : listOfC) {
    listOfB.add(DFactory.convertFromCToD(c));
}

...

所以,为了不违反 dry,我想出了一个通用的解决方案:

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);
    }
});

现在,虽然这在 DRY 方面更好,但我认为它违反了 KISS ,因为这个解决方案比重复的 for 循环更难理解。

那么,这是 DRY 还是 KISS?在这种情况下应该支持哪一个?

编辑

需要说明的是,我所说的类是一个适配器,它将对遗留系统的调用委托(delegate)给我们自己的实现,并在此过程中将遗留系统转换为我们自己的类型。我无法更改遗留类型,也无法更改我们的类型(由 XML 模式生成)。

最佳答案

哪个都好。

对于循环,您并没有真正重复自己,因为唯一重复的部分是“语法困惑”(在您的情况下不会太多)。您不是在重复/复制“应用程序逻辑”代码。

如果您喜欢“Function”风格,可以使用 Guava 库(它有 Function 接口(interface)和许多在集合上使用它们的辅助方法)。那是 DRY(因为您不重复自己,而是重复使用已经存在的代码),并且仍然是 KISS(因为这些都是很好理解的模式)。

关于java - 当 KISS 和 DRY 碰撞时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7307202/

相关文章:

coldfusion - ColdFusion 是否支持委托(delegate)?

seo - RDFa DRY 引用的概念

c# - .NET 重构,DRY。双重继承、数据访问和关注点分离

java - 无法在 doInbackground() 方法中执行 AlertDialog

java - 在java程序中添加异常

java - 用 Paint 给位图着色?

go - 你如何在golang中返回一个非原始类型的变量

java - 我不明白 Spring 中的 Autowired

互联网上的 Java 套接字 : ConnectException (operation timed out)

ruby-on-rails - 条件 View /布局