commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gilles <gil...@harfang.homelinux.org>
Subject Re: [math] fluent/builder API for algorithms in 4.0 ?
Date Wed, 01 May 2013 15:53:22 GMT
> [...]
> One of the pitfalls or devil in the details we can expect is we 
> attempt
> to do this while still having a class hierarchy for some aspects,
> typically with an abstract class at the top.
>
> Lets consider a withMaxEvaluation(int maxEval) implementation which 
> may
> probably be implemented once in the abstract class and simply 
> inherited
> in the specialized classes deeper in the hierarchy.
>
> The top implementation should create an object of the appropriate 
> type.
> The simplest solution I think of is having a protected factory 
> method.
> So if we look at the abstract class and one of its derived class, we
> should have something like:
>
>  public abstract class AbstractAlgorithm {
>
>     private final int maxEval;
>
>     protected AbstractAlgorithm(final int maxEval) {
>       this.maxEval = maxEval;
>     }
>
>     public AbstractAlgorithm() {
>        // default setting
>        this(Integer.MAX_VALUE);
>     }
>
>     protected abstract AbstractAlgorithm build(final int maxEval);
>
>     public AbstractAlgorithm withMaxEval(final int maxEval) {
>        return build(maxEval);
>     }
>
>     public int getMaxEval() {
>       return maxEval;
>     }
>
>  }
>
>  public class SpecializedAlgorithm
>     extends AbstractAlgorithm implements ThresholdTunable {
>
>    private final double threshold;
>
>     protected SpecializedAlgorithm(final int maxEval,
>                                    final double threshold) {
>       super(maxEval);
>       this.threshold = threshold;
>     }
>
>     public SpecializedAlgorithm() {
>        // use default values all way up to the class root
>        super();
>        this.threshold = 1.0;
>     }
>
>     protected SpecializedAlgorithm build(final int maxEval) {
>        // make sure we don't lose our local threshold
>        // when the top level abstract class creates a new instance
>        // with an updated maxEval
>        return new SpecializedAlgorithm(maxEval, threshold);
>     }
>
>     public SpecializedAlgorithm withThreshold(final double threshold) 
> {
>        return new SpecializedAlgorithm(getMaxEval(), threshold);
>     }
>
>  }
>

 From what you proposed in the original post, I rather understood
the following:

   public abstract class AbstractAlgorithm {
      private final int maxEval;

      protected AbstractAlgorithm(final int maxEval) {
        this.maxEval = maxEval;
      }

      public int getMaxEval() {
        return maxEval;
      }
   }

   public class SpecializedAlgorithm
      extends AbstractAlgorithm
      implements ThresholdTunable,
                 IterationLimitable {
      private final double threshold;

      protected SpecializedAlgorithm(final int maxEval,
                                     final double threshold) {
        super(maxEval);
        this.threshold = threshold;
      }

      public SpecializedAlgorithm() {
         this(Integer.MAX_VALUE);
      }

      public double getThreshold() {
         return threshold;
      }

      public SpecializedAlgorithm withThreshold(final double threshold) 
{
         return new SpecializedAlgorithm(getMaxEval(), threshold);
      }

      public SpecializedAlgorithm withMaxEval(int maxEval) {
         return new SpecializedAlgorithm(maxEval, getThreshold());
      }
   }

I.e. the "end-user" instantiates using the default constructor and 
applying
"withXxx" methods.
All classes in the hierarchy provide "protected" constructors to allow
subclasses to set the state implemented in the base classes.

Is there something wrong with that approach?


Gilles


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message