Q:

How do I handle two algorithms that seem the same but different?

I have two algorithms that share a lot of commonalities. One performs an iterative procedure, the other does just the first iteration. The results are, of course, different (one class provides results that the other can't), as well as the setup (the iterative process requires tolerances and max number of iterations, which are irrelevant in the non-iterative one).
Should I have a unique class with internal ifs (like if (iterative) do this else do that) or should I implement two different classes (and potentially put common code in an accessible place so that it can be shared ?) What do you think ?

A:

It sounds like the Template Method Pattern:

A template method defines the program skeleton of an algorithm. One or more of the algorithm steps can be overridden by subclasses to allow differing behaviors while ensuring that the overarching algorithm is still followed.

For example:
abstract class Base {
    void stepOne(Object item) {
        // Do some stuff on item...
    }

    void stepTwo(Object item) {
        // Do some stuff on item...
    }

    void stepThree(Object item) {
        // Do some stuff on item...
    }

    void allSteps(Collection<Object> data) {
        for (Object x : data) {
            stepOne(x);
            stepTwo(x);
            stepThree(x);
        }
    }
}

class SpecificOne extends Base {
    @Override
    void stepTwo(Object item) {
        // Do something different on item
    }
}

class SpecificTwo extends Base {
    @Override
    void allSteps(Collection<Object> data) {
        for (Object x : data) {
            // The order is altered
            stepThree(x);
            stepTwo(x);
            stepOne(x);
        }
    }
}

Then you would use the different algorithms like this:
public class TMTest {
    public static void main(String[] args) {
        Collection<Object> items = ...;

        Base one = new SpecificOne();
        Base two = new SpecificTwo();

        one.allSteps(items);
        two.allSteps(items);
    }
}

