user2693979
user2693979

Reputation: 2542

What is best solution (design pattern) for this situation?

I have some very similar functions, but one line is different in each function.

How can I avoid code duplication?

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

Could you tell me some appropriate design patterns?

Upvotes: 2

Views: 161

Answers (6)

StackFlowed
StackFlowed

Reputation: 6816

This is for prior to JAVA 8 without using lambda expressions

You can refactor your code like this to make it look neater and readable :

public abstact class ParentClass(){

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

   public abstract void callMethodLetter();       

}

Then you can extend the ParentClass and implement the callMethodLetter() to call the correct method.

Upvotes: 3

folkol
folkol

Reputation: 4883

This is exactly what Lambda Expressions are for:

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

Upvotes: 5

Eric Cornelson
Eric Cornelson

Reputation: 771

If you're able to use Java 8, this is a perfect use case for 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");
    }
}

Upvotes: 1

Kraal
Kraal

Reputation: 2877

Your four "examples" methods are all inside the same class. is there a reason for it ? If these are real different "examples", make it more object oriented.

First create an Example class :

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

Then have 4 different implementations of this Example class such as :

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

You can then have your code have somewhere :

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

And call this snippet with :

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

Upvotes: 0

Moni
Moni

Reputation: 433

you can make two separate method for start and end like below -

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

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

than call in your method call -

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

same call with other methods too.

Upvotes: 1

Raskolnikov
Raskolnikov

Reputation: 111

Your example is so simple that it's hard to avoid code duplication whilst being less verbose, but presumably you have more complicated situations in mind.

You could do it like this:

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

}

Upvotes: 1

Related Questions