这种情况的最佳解决方案(设计模式)是什么?

时间:2014-09-19 17:52:40

标签: java design-patterns

我有一些非常相似的功能,但每个功能中有一行不同。

如何避免代码重复?

public class Example{

    public void f(){
       System.out.println("Start");
       OtherExample.start();
       AnotherExample.funct1(); //DIFFERENT CODE LINE
       OtherExample.end();
       System.out.println("End");
    }

    public void g(){
       System.out.println("Start");
       OtherExample.start();
       AnotherExample.funct2(); //DIFFERENT CODE LINE
       OtherExample.end();
       System.out.println("End");
    }

    public void h(){
       System.out.println("Start");
       OtherExample.start();
       AnotherExample.funct3(); //DIFFERENT CODE LINE
       OtherExample.end();
       System.out.println("End");
    }

    public void i(){
       System.out.println("Start");
       OtherExample.start();
       AnotherExample.funct4(); //DIFFERENT CODE LINE
       OtherExample.end();
       System.out.println("End");
    }
}

你能告诉我一些合适的设计模式吗?

6 个答案:

答案 0 :(得分:5)

这正是Lambda Expressions的用途:

public static void f(Runnable r) {
    System.out.println("Start");
    OtherExample.start();
    r.run();
    OtherExample.end();
    System.out.println("End");
}

public static void main(String[] args) {
    f(AnotherExample::funct1);
    f(AnotherExample::funct2);
    f(AnotherExample::funct3);
    f(AnotherExample::funct4);
}

答案 1 :(得分:3)

这是针对JAVA 8而不使用lambda expressions

您可以像这样重构代码,使其看起来更整洁可读:

public abstact class ParentClass(){

   public void start() {
      System.out.println("Start");
      OtherExample.start();         
      callMethodLetter();
      OtherExample.end();
      System.out.println("End");
   }

   public abstract void callMethodLetter();       

}

然后你可以扩展ParentClass并实现callMethodLetter()来调用正确的方法。

答案 2 :(得分:1)

您的示例非常简单,以至于很难避免代码重复,同时又不那么详细,但可能会考虑到更复杂的情况。

你可以这样做:

public class Example {

    public void f() {
        (new F()).execute();
    }

    public void g() {
        (new G()).execute();
    }

    public void h() {
        (new H()).execute();
    }

    public void i() {
        (new I()).execute();
    }

    private class F extends AbstractX {
        @Override
        public void executeFunction() {
            AnotherExample.funct1();
        }
    }

    private class G extends AbstractX {
        @Override
        public void executeFunction() {
            AnotherExample.funct2();
        }
    }

    private class H extends AbstractX {
        @Override
        public void executeFunction() {
            AnotherExample.funct3();
        }
    }

    private class I extends AbstractX {
        @Override
        public void executeFunction() {
            AnotherExample.funct4();
        }
    }

    private abstract class AbstractX {
        public void execute() {
            System.out.println("Start");
            OtherExample.start();
            executeFunction();
            OtherExample.end();
            System.out.println("End");
        }

        public abstract void executeFunction();
    }

}

答案 3 :(得分:1)

你可以为下面的开始和结束制作两个单独的方法 -

public void start() {
      System.out.println("Start");
      OtherExample.start();         
   }

   public void end() {
      OtherExample.end();
      System.out.println("End");
   }

比调用方法调用 -

   public void f(){
           start();
           AnotherExample.funct1(); //DIFFERENT CODE LINE
           end();
        }

与其他方法同样的调用。

答案 4 :(得分:1)

如果您能够使用Java 8,这是method references的完美用例。

public class Example {

    public void f() {
        common(AnotherExample::funct1);
    }

    public void g() {
        common(AnotherExample::funct2);
    }

    public void h() {
        common(AnotherExample::funct3);
    }

    public void i() {
        common(AnotherExample::funct4);
    }

    public void common(Runnable function){
       System.out.println("Start");
       OtherExample.start();
       function.run();
       OtherExample.end();
       System.out.println("End");
    }
}

答案 5 :(得分:0)

你的四个例子"方法都在同一个类中。这是有原因的吗?如果这些是真正不同的"示例",请使其更加面向对象。

首先创建一个Example类:

public abstract class Example {
  public void execute();
}

然后有这个Example类的4种不同的实现,例如:

public class FirstExample {
  public void execute() {
    // ...
  }
}

然后您可以将代码放在某处:

public void wrap(Example example){
   start();
   example.execute();
   end();
}

并使用以下代码调用此代码段:

wrap(new FirstExample());
...
wrap(new FourthExample());