2

I have an abstract class with a single abstract method; and a number of implementing classes (about 6).

The method returns an object that "needs" two parameters.

However, in some cases, only one of the two parameters is required.

Is there an elegant way to implement this case? (instead of return this parameter as empty)

public class NormResult {
    protected List<String> normWords;
    protected  List<String> unNormWords;

    public NormResult(List<String> normWords,List<String> unNormWords) {
        this.normWords = normWords;
        this.unNormWords = unNormWords;
    }

    public NormResult(List<String> normWords) {
        this.normWords = normWords;
        this.unNormWords =  Collections.emptyList();
    }
}

public abstract class AbstractNormalizer {
    protected abstract List<NormResult> doNorm();
}

public class FirstNormImpl extends AbstractNormalizer {
    protected List<NormResult> doNorm() {
        List<String> normWords = new ArrayList<>(5);
        List<String> unNormWords = new ArrayList<>(7);

        NormResult result = new NormResult(normWords, unNormWords);
        return result;      
    }
}

public class SecondNormImpl extends AbstractNormalizer {
    protected List<NormResult> doNorm() {
        List<String> normWords = new ArrayList<>(8);    
        NormResult result = new NormResult(normWords);
        return result;
    }
}
GhostCat
  • 137,827
  • 25
  • 176
  • 248
userit1985
  • 961
  • 1
  • 13
  • 28

2 Answers2

2

if you do this to members final:

 protected final List<String> normWords;
 protected final List<String> unNormWords;

then in the constructor you have to initialize them both... then you can set to an empty collection or a null reference the one you dont have/need

and your overloaded constructor can look like:

public NormResult(List<String> normWords, List<String> unNormWords) {
    this.normWords = normWords;
    this.unNormWords = unNormWords;
}

public NormResult(List<String> normWords) {
    this(normWords, Collections.emptyList());
}
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
  • I thought maybe add another abstract class and only classes which have the second parameter will implements it. – userit1985 Jun 21 '17 at 08:19
2

The two changes I would make:

  • Make the fields final
  • Use constructor telescoping

as in:

public NormResult(List<String> normWords) {
  this(normWords(), Collections.emptyList()); 
}

to avoid even that simple "code duplication" of assigning values twice.

Beyond that; I agree with the comments; this approach looks reasonable.

GhostCat
  • 137,827
  • 25
  • 176
  • 248