My question concerns classes design in OOP. Let say we have ItemBase which is parent class for Canceled, Modified and Added class. We also have DueToBase class - parent of Provider and Distributor.

ItemBase may be changed due to DueToBase class.
Assume that ItemBase has property of type DueToBase, and DueToBase has interface method called compute(). Compute algorithm is RELATED to the specific ItemBase derived class. So we have six different possible combinations of ItemBase-DueToBase relationship.
Example.
ItemBase ib = new Added();
ib.changed = new Provider(ib);
ib.changed.compute();
My question is how should relationship between ItemBase and DueToBase be built in real object oriented programming ? I do not see swich/case or if condition clause in compute method for checking which type of instance ItemBase is. It gets even worse if DueToBase has another XXXBase class inside which has another interface method YYY() which algorithm depends on the specific instance of DueToBase (and even on the ItemBase). How to deal with such cases ? Is there any good programming pattern for such things ? Maybe direction I followed is bad. I would appreciate for your assistance.
maybe that my diagram was not clear. The problem is with following... pseudocode:
doSomething(){
if(itemBase instanceof Cancelled){
if(dueToBase instanceof Provider)
algorithm1();
else if(dueToBase instanceof Company)
algorithm2();
}else if(itemBase instanceof Modified){
if(dueToBase instanceof Provider)
algorithm3();
else if(dueToBase instanceof Company)
algorithm4();
}else if(itemBase instanceof Added){
if(dueToBase instanceof Provider)
algorithm5();
else if(dueToBase instanceof Company)
algorithm6();
}
}
it gets even worse with deeper if clauses.
Your ItemBase class can be an abstract class with compute() method in it, and all the child classes can have their own implementation.
So later you can do something like this,
ItemBase ib = new Added();
ib.changed = new Provider(ib);
ib.changed.compute();
Now, when you will call compute method on ib.changed, it will execute compute implementation of Added class.
In your case, due to base class, Add a instance variable which distinguish between Provider and Company. Something like a boolean flag or int.
Then instead of using dueToBase instanceof Provider you can just create if statement. So your updated pseudo code will decreased to few line. Something like this,
doSomething(){
if(dueToBase.isProvider) {
algorithm1(); //execute if Provider
} else {
algorithm2(); //execute if Company
}
}
Now the complexity to choose compute will be handled by Abstract pattern and then you just have to worry about whether it is company or provider.
the better way will be:
interface Algorithm {
void executeAlgorithm();
}
and have classes, that implement Algorithm interface, instead of functions. Algorithm1, Algorithm2, Algorithm3 and so on.
and have table:
Algorithm[,] algorithmTable = { { new Algorithm1(), new Algorithm2() },
{ new Algorithm3(), new Algorithm4() },
{ new Algorithm5(), new Algorithm6() }
};
and have maps
Map< Class<?> , Integer > itemBaseMap = new HashMap<>();
Map< Class<?> , Integer > dueToBaseMap = new HashMap<>();
and somewhere build this maps
itemBaseMap.add( Canceled.class , 0 );
itemBaseMap.add( Modified.class , 1 );
itemBaseMap.add( Added.class , 2 );
dueToBaseMap.add( Provider.class, 0 );
dueToBaseMap.add( Company.class, 1 );
and in doSomething method you can write
void doSomething( ItemBase itemBase, DueToBase dueToBase ) {
Integer itemBaseIndex = itemBaseMap.get( itemBase.getClass() );
Integer dueToBaseIndex = dueToBaseMap.get( dueToBase.getClass() );
Algorithm algorithm = algorithmTable[ itemBaseIndex, dueToBaseIndex ];
algorithm.executeAlgorithm();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With