Reputation: 470
Lets say we have to retrive data of class: Trade. This trade class has many parameters like A, B, C....
class A { retrieveTradeDataWithA(); and many more methods which do something }
class B { retrieveTradeDataWithB(); and many more methods which do something }
class LetsSaySomeResource {
@Inject
private A classAInstance;
@Inject
private B classBInstance;
public void getTradeDataBasedOnA(){
classAInstance.retrieveTradeDataWithA();
}
public void getTradeDataBasedOnB(){
classBInstance.retrieveTradeDataWithB();
}
}
Now the requirement is we want to fetch some trade data based on A and B both and later on maybe more classes like A and B will be added to get data based on this. How shall i make the design more flexible?
Like,
public void getDataBasedOnAandB(){
}
Or, later on C class can come, so i dont want to keep injecting filters like A,B.... Can someone help on this?
Upvotes: 3
Views: 176
Reputation: 662
I think template design pattern would be useful here. http://en.wikipedia.org/wiki/Template_method_pattern
you can define your template method in the base class and let the sub classes implementing this class define their own algorithm to do this. Do read the wiki link and you would find your way out.
Upvotes: 0
Reputation: 1681
Try something like the decorator pattern. If your classes will grow over time always based on previous requirements, you could add the additional computations by decorating them.
Your example is still very abstract so it is hard to tell whether your additional classes are interdependent or simply "extended" (a simple inheritance would do).
Or completely decoupled so something like SimY4 did could help (use e.g. a variation of the visitor pattern).
Upvotes: 0
Reputation: 7926
It may look something like this:
class LetsSaySomeResource {
@Resource
private Map<String, DataAccessInterface> instanceToDataAccessMapping;
public DateAggregationResult getDataFor(String... instanceNames) {
DataAggregationResult result = new DataAggregationResult(); // some list or whatever
for (String instanceName : instanceNames) {
Data data = instanceToDataAccessMapping.get(instanceName).getData();
/**
* Add this data to aggregation result here
*/
}
return result;
}
}
Upvotes: 1
Reputation: 15212
First create an interface that will define the contract for doing something :
public interface IData {
void doSomething();
}
Then create the concrete implementations to do something :
public class DataA implements IData {
@Override
public void doSomething() {
// TODO Do something for A
}
}
public class DataB implements IData {
@Override
public void doSomething() {
// TODO Do something for B
}
}
And finally a class that will actually do something :
public class DataDAO {
private List<IData> dataList;
public DataDAO(List<IData> dataList) {
this.dataList = dataList;
}
public void doSomething() {
for(IData data : dataList) {
data.doSomething();
}
}
}
Now let's take your use cases :
do something for A :
List<IData> dataAList = new ArrayList<IData>();
dataList.add(new DataA());
DataDAO dataADAO = new DataDAO(dataAList);
dataADAO.doSomething();
do something for A and B :
List<IData> dataAList = new ArrayList<IData>();
dataList.add(new DataA());
dataList.add(new DataB());
DataDAO dataADAO = new DataDAO(dataAList);
dataADAO.doSomething();
Upvotes: 4