samples/sidemeanings/src/org/apidesign/sidemeanings/math/Arithmetica.java
author Jaroslav Tulach <jtulach@netbeans.org>
Fri, 27 Mar 2009 20:30:39 +0100
changeset 325 4553c2885ce6
child 376 bb34a70d36ba
permissions -rw-r--r--
Arithmetica example with fuzzy modifiers eliminated
     1 package org.apidesign.sidemeanings.math;
     2 
     3 /** Rewrite of original
     4  * <a href="http://source.apidesign.org/hg/apidesign/diff/4e59b6b0e907/samples/composition/src-api1.0/org/apidesign/math/Arithmetica.java">
     5  * Arithmetica</a>
     6  * class from the composition project
     7  * to follow the <q>eliminate fuzzy modifiers</q> rule.
     8  *
     9  * @author Jaroslav Tulach <jtulach@netbeans.org>
    10  * @version 5.0
    11  */
    12 // BEGIN: design.sidemeanings.arith
    13 public abstract class Arithmetica {
    14     // BEGIN: design.sidemeanings.arith.sumTwo
    15     public final int sumTwo(int one, int second) {
    16         return overridableSumTwo(one, second);
    17     }
    18     protected abstract int overridableSumTwo(int one, int second);
    19     protected final int defaultSumTwo(int one, int second) {
    20         return one + second;
    21     }
    22     // END: design.sidemeanings.arith.sumTwo
    23     
    24     public final int sumAll(int... numbers) {
    25         return overridableSumAll(numbers);
    26     }
    27     protected abstract int overridableSumAll(int... numbers);
    28     protected final int defaultSumAll(int... numbers) {
    29         if (numbers.length == 0) {
    30             return 0;
    31         }
    32         int sum = numbers[0];
    33         for (int i = 1; i < numbers.length; i++) {
    34             // do I want to call sumTwo or defaultSumTwo? That is a question!
    35             sum = openUpToSubclasses() ?
    36                 sumTwo(sum, numbers[i]) :
    37                 defaultSumTwo(sum, numbers[i]);
    38         }
    39         return sum;
    40     }
    41     
    42     public final int sumRange(int from, int to) {
    43         return overridableSumRange(from, to);
    44     }
    45     protected abstract int overridableSumRange(int from, int to);
    46     protected final int defaultSumRange(int from, int to) {
    47         int len = to - from;
    48         if (len < 0) {
    49             len = -len;
    50             from = to;
    51         }
    52         int[] array = new int[len + 1];
    53         for (int i = 0; i <= len; i++) {
    54             array[i] = from + i;
    55         }
    56         // BEGIN: design.sidemeanings.arith.the.question
    57         // Again, an API author has to ask what sumAll one wants to call?
    58         // Am I about to open up to subclasses or do I want default impl?
    59         return openUpToSubclasses() ?
    60             sumAll(array) :
    61             defaultSumAll(array);
    62         // END: design.sidemeanings.arith.the.question
    63     }
    64 
    65     boolean openUpToSubclasses = true;
    66     boolean openUpToSubclasses() {
    67         return openUpToSubclasses;
    68     }
    69 
    70 
    71     // BEGIN: design.sidemeanings.arith.factory
    72     public static Arithmetica create() {
    73         return new Arithmetica.Impl();
    74     }
    75     private static class Impl extends Arithmetica {
    76         @Override
    77         protected int overridableSumTwo(int one, int second) {
    78             return defaultSumTwo(one, second);
    79         }
    80 
    81         @Override
    82         protected int overridableSumAll(int... numbers) {
    83             return defaultSumAll(numbers);
    84         }
    85 
    86         @Override
    87         protected int overridableSumRange(int from, int to) {
    88             return defaultSumRange(from, to);
    89         }
    90     }
    91     // END: design.sidemeanings.arith.factory
    92 
    93 }
    94 // END: design.sidemeanings.arith