I solve the problem of finding a leader ( leader election ) This is a purely algorithmic problem, which has 2 forms: a unidirectional ring and a bidirectional one. To represent the data, I created my own class for a list, twisted into a ring. That is, I have two algorithms, one for each form of the task.
public abstract class MyAbstractRoundList { protected int size; protected Agent[] arr = new Agent[1]; protected int index = 0; public boolean isEmpty() { return size == 0; } public int size() { return size; } public void add(Agent agent) { if (size >= arr.length) { Agent[] temp = arr; arr = new Agent[temp.length * 2]; System.arraycopy(temp, 0, arr, 0, temp.length); } arr[size++] = agent; } // и дальше еще много методов
Next, I create the heirs of this class for unidirectional mode and for bidirectional. The implementations in them are certainly different. Next, I have a class:
public class LeaderElection { public static void solve(MyAbstractList list, int i) { if (i == 0) { list.initiateStartState(); } else { list.setMessages(); } }
}
I have a solution for unidirectional mode in it. And there is a similar class with a solution for bidirectional, but the implementations of course also differ. What not to register in the client code
if(isOneDirectMode()){ LeaderElection.solve(); { if(isBiDirectMode()){ BiLeaderElection.solve(); }
I could also create an abstract class for the solution and its heirs and use polymorphism (as I do for lists). But here comes the problem: I have parallel inheritance hierarchies. If a new mode appears, I will have to add a new subclass of MyAbstractRoundList
and a new subclass of the solution. How can you get rid of it? I see only one way: It would be possible to make the abstract (solve) method in MyAbstractRoundList and implement it in the subclasses of each mode as required for a particular mode. But this is bad, because then my subclasses of MyAbstractRoundList
will not only store data, but also solve the problem. That is, to perform 2 functions.