Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当吻和干碰撞时_Java_Dry - Fatal编程技术网

Java 当吻和干碰撞时

Java 当吻和干碰撞时,java,dry,Java,Dry,我是一个执迷于法律和原则的追随者,但上周我遇到了一个案例,两者似乎相互矛盾: 对于我正在做的一个应用程序,我必须实现一个循环For times,它执行以下操作: 迭代类型a列表的元素 将类型A的元素转换为类型B,并将其插入类型B的列表中 下面是一个例子: for (A a : listOfA) { listOfB.add(BFactory.convertFromAToB(a)); } 在代码中,我必须这样做大约4次,将一个类型(如D、e等)转换为另一个类型。我可能无法更改我要转换的类型

我是一个执迷于法律和原则的追随者,但上周我遇到了一个案例,两者似乎相互矛盾:

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

  • 迭代类型a列表的元素
  • 将类型A的元素转换为类型B,并将其插入类型B的列表中
  • 下面是一个例子:

    for (A a : listOfA) {
        listOfB.add(BFactory.convertFromAToB(a));
    }
    
    在代码中,我必须这样做大约4次,将一个类型(如D、e等)转换为另一个类型。我可能无法更改我要转换的类型,因为它们是我们必须在out应用程序中使用的第三方类型

    因此,我们:

    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));
        }
    }
    
    专用接口函数{
    不适用;;
    }
    public void convertAndCopy(列表src、列表dst、函数f){
    适用于(S:src){
    dst.添加(f.应用);
    }
    }
    
    一个电话看起来像这样:

    convertAndCopy(listOfA, listOfB, new Function<A, B>() {
        A apply(B b) {
            return CFactory.convertFromBToC(b);
        }
    });
    
    convertAndCopy(listOfA,listOfB,new函数),因为这种解决方案比复制for循环更难理解

    那么,这是干吻还是吻?在这种情况下,哪一个更受欢迎

    编辑


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

    干燥和亲吻等一般原则永远不会奏效

    在我看来,答案是忘记教条(至少在这个问题上是这样),想想什么能给你提供最好/最具可读性的解决方案

    如果复制的x 4代码更容易理解,并且不是维护负担(即,您不需要对其进行太多更改),那么它就是正确的解决方案


    (Thilo的答案也是正确的……IMO)

    如果在整个应用程序中只需执行4次,并且转换与示例一样简单,那么我会选择在通用解决方案中随时编写4 for循环

    使用这种通用解决方案会使可读性受到很大影响,而实际上您并没有从中获得任何好处。

    两者都可以

    对于循环,您并不是在真正地重复自己,因为唯一重复的部分是“语法混乱”(在您的例子中不是太多),您并不是在重复/复制“应用程序逻辑”代码


    如果您喜欢“函数”样式,可以使用Guava库(它有函数接口和许多在集合中使用它们的助手方法)。这是干巴巴的(因为您不重复自己,并且重复使用已经存在的代码),并且仍然可以使用KISS(因为这些是很好理解的模式).

    我认为并不是KISS和DRY互相矛盾。我宁愿说Java不允许您在不重复自己的同时表达简单性

    首先,如果您引入正确命名的方法,从
    List
    转换为
    List
    等等,而不是一直重复循环,那么它将是干燥的,同时仍然保持亲吻

    但我的建议是,看看其他语言,让你在推广亲吻的同时充分利用DRY,例如Scala:

    val listOfB = listOfA map convertAtoB
    val listOfC = listOfB map convertBtoC
    val listOfD = listOfC map convertCtoD
    
    其中,
    convertAtoB
    是一个函数,它接受类型为a的项并返回B:

    def convertAtoB(a: A): B = //...
    

    或者您甚至可以链接这些
    map
    调用。

    您可以将转换函数移到CFactory中:

    convertAndCopy(listOfA, listOfB, CFactory.getConverterFromAToB());
    
    通过这种方式,代码非常可读/简单,并且可以促进代码重用(以后可能需要在另一个上下文中使用converter对象)

    实施:

    public <S, T> void convertAndCopy(List<A> listofA, List<B> listOfB, Function<A, B> f) {
      listOfB.addAll(Collections2.transform(listOfA,f));
    }
    

    关键词:爪哇干吻-爱死它了!什么是“干”的意思?啊,答案是这样的,我想你不要重复了。@Angel,sry我稍后会添加引用:-)。@helpermethod-无需。Angel应该阅读标签wiki中的标签;e、 在它上面盘旋。+1次,完全忘记番石榴!在这种情况下,您不会从DRY中获得太多好处:您没有主要的代码分解;你可能不会因为重复自己的话而导致语无伦次的行为。您仍然需要重复自己的操作,因为您必须始终编写“新函数{X apply(Y){return CFactory.convertFromYToX(Y);}}”。这次我要接吻了。+1这真是个好主意:-)。
    listOfB.addAll(Collections2.transform(listOfA,CFactory.getConverterFromAToB()));