lundi 7 janvier 2019

Dilemma while selecting a design pattern

I am looking to select a design pattern for a project I am working on and was wondering if I can get some input.


Background

An interface called Ranker is defined as follows.

interface Ranker<T> {
    public void rank(List<T> item);
}

Each implementation of Ranker can have multiple Rankers as member variables and each of the member Rankers can have multiple Rankers as their member variables. You get the idea. A Ranker can use another Ranker to help rank it's items.

In my particular case I have 27 different Rankers defined each of which Rank a different dataType. 26 of those rankers will be used by one of the Rankers to be ultimately be able to rank the items.

RankerForTypeA
  RaknerForTypeB 
    RankerForTypeC
    RankerForTypeD
    RankerForTypeE
  RankerForTypeF
    RankerForTypeG
      RankerForTypeH
        RankerForTypeI 
      RankerForTypeJ
  RankerForTypeK
  ...

Meaning, RankerTypeA has, RankerTypeB, RankerTypeF and RankerTypeK as members and needs them in order to appropriately rank items of type A.


Problem

The instantiation logic for each of the Rankers is different. I would like to use some sort Module/Factory/etc that helps me create these rankers. I ultimately need it to create RankerForTypeA. I had something like this in mind.

 interface RankerFactory {
      Ranker<A> getRankerForA(paramsForA);
      Ranker<B> getRankerForB(paramsForB);
      Ranker<C> getRankerForC(paramsForC);
      ...
 }

 public class DefaultRankerFactory implements RankerFactory  {
      Ranker<A> getRankerForA(paramsForA) {
          getRankerForB(paramsForB)
          ...
      }
      Ranker<B> getRankerForB(paramsForB) {
          getRankerForC(paramsForC)
          ...
      }
      Ranker<C> getRankerForC(paramsForC) {
          ...
      }
 }

Here's the bit tricky part. I would like to make it easy for people to let's say use custom rankers where they see fit. Going back to the hierarchy I drew before, let's say for TypeB, people wanted to use CustomRankerForTypeB instead of RankerForTypeB, they should be easily be able to. So in that case the hierarchy would look like

RankerForTypeA
  CustomRankerForTypeB 
    ...
  RankerForTypeF
    RankerForTypeG
      RankerForTypeH
        RankerForTypeI 
      RankerForTypeJ
  RankerForTypeK
  ...

So here, if they want to create RankerForTypeA, they can't directly use DefaultRankerFactory because it uses RankerForTypeB instead of CustomRankerForTypeB. So normally you would be like, they can just create a new implementation of RankerFactory but then it would have a lot of duplicate code because the instantiation logic of a lot of the of other parts of RankerForTypeA is similar.

So, for this scenario I had something like this in mind.

 public class CustomRankerFactory extends DefaultRankerFactory  {

      Ranker<B> getRankerForB(paramsForB) {
          //Define instantiation logic for CustomRankerForTypeB
          ...
      }

 }

This solution however doesn't seem right to me because it relies heavily on inheritance. Plus the approach here doesn't seem like a Factory pattern I keep going back to that term. I am looking for help with the best approach to define the "Factory" so that it's modular and easily extensible.

Aucun commentaire:

Enregistrer un commentaire