I have 10-15 different types of results to calculate say AResult, BResult etc. All result calculation return single type of value(consider an integer
value).
To calculate these I needs input parameters which are mostly common but a few needs different ones as follows:
Input parameters example:
AResult needs int x, int y, int a[], int b[]
BResult needs int x, int y, int a[], boolean c
CResult needs int x, int y, int a[], boolean c, boolean d
DResult needs int x, int y, int p[], boolean e
.....
NOTE that in some cases result of one calculation is also used in other result calculations, but that is only in few cases and not all.
The way I am doing it is through Approach1 as follows:
Approach 1:
I am defining an interface which has single method to calculate result taking an InputParameter obj
. In the implementation classes I would extract out the values from InputParameter obj
whichever are applicable to that particular type of result. Here is the snippet of my sample code:
public interface Result {
int calculate(InputParameter obj);
}
public class AResult implements Result {
public int calculate(InputParameter obj){
// code
}
}
public class BResult implements Result {
public int calculate(InputParameter obj)){
// code
}
}
public class InputParameter {
int x;
int y;
int z;
int a[];
int b[];
int p[];
boolean c;
boolean d;
boolean e;
....
// Getters and Setters
}
As an example, say I create an InputParameter
object and set values of all the fields in there. I pass this object to aResultObject.calculate(InputParameter obj) , dResultObject.calculate(InputParameter obj) and so on.
AResult
needs int x, int y, int a[], int b[]
which I extract from InputParameter obj
do the calulations and return result.
DResult
needs int x, int y, int p[], boolean e
which I extract from same InputParameter obj
to do the calulations and return result.
Note that I might have to do other sets of result calculations, so may create multiple objects of InputParameter
, AResult
, BResult
so on. Just want to convey that InputParameter
need not be singleton.
Approach2:
Having calculate()
method without any parameter and setting these values in individual Result class constructors.
As @Duncan pointed out one drawback of Approach1 is that, here I might miss setting the required fields in InputParameter
object for a given result calculation. And when I actually try to extract out the value from InputParameter
object in calculation(InputParameter obj)
method, I discover it is not set.
public interface Result {
int calculate();
}
public class AResult implements Result {
public AResult(int x, int y, int a[], int b[]) {
//set input params
}
public int calculate() {
//calculate and return AResult
}
}
Approach3:
Create Single class (or may be just 2-3 classes) for Result and then just have separate methods to calculate different results.
I am also considering this approach because in some cases result of one calculation is also used in other result calculations (but that is only in few cases and not all).
public class Result {
// various fields...
int calculateResultA(){...}
int calculateResultB(){...}
int calculateResultC(){...}
}
Is the above mentioned Approach1 good for given situaltion? or the other alternatives are better?
I suggest approach 2 with a factory. The pattern is (maybe) command.
package blammy.result;
public interface Result
{
int calculate();
}
package blammy.result.impl;
public class AResult
implements Result;
{
/*
* Protected constructor to hinder naughty construction.
*/
protected AResult(
int x,
int y,
int a[],
int b[])
{
... blah;
}
public int calculate()
{
int returnValue;
returnValue = ... blah.
return returnValue;
}
}
public class BResult
implements Result;
{
/*
* Protected constructor to hinder naughty construction.
*/
protected BResult(
int x,
int y,
boolean c)
{
... blah;
}
public int calculate()
{
int returnValue;
returnValue = ... blah.
return returnValue;
}
}
public static class ResultFactory
{
public static Result createResult(
int x,
int y,
int a[],
int b[])
{
return new AResult(x, y, a, b);
}
public static Result createResult(
int x,
int y,
boolean c)
{
return new BResult(x, y, c);
)
}
If different calculations require the same parameters, then you should use descriptive name in the factory and in the class name. For example:
public static class ResultFactory
public static Result createBlammy(
int x,
int y,
int a[],
int b[])
{
return new ResultBlammy(x, y, a, b);
}
public static Result createHooty(
int x,
int y,
int a[],
int b[])
{
return new ResultHooty(x, y, a, b);
}