# HG changeset patch # User Jaroslav Tulach # Date 1238182239 -3600 # Node ID 4553c2885ce6454d647c298eaa933078d7c74491 # Parent a9ad091ed0690655515016969c1d0ac0d95aa157 Arithmetica example with fuzzy modifiers eliminated diff -r a9ad091ed069 -r 4553c2885ce6 samples/sidemeanings/src/org/apidesign/sidemeanings/math/Arithmetica.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/sidemeanings/src/org/apidesign/sidemeanings/math/Arithmetica.java Fri Mar 27 20:30:39 2009 +0100 @@ -0,0 +1,94 @@ +package org.apidesign.sidemeanings.math; + +/** Rewrite of original + * + * Arithmetica + * class from the composition project + * to follow the eliminate fuzzy modifiers rule. + * + * @author Jaroslav Tulach + * @version 5.0 + */ +// BEGIN: design.sidemeanings.arith +public abstract class Arithmetica { + // BEGIN: design.sidemeanings.arith.sumTwo + public final int sumTwo(int one, int second) { + return overridableSumTwo(one, second); + } + protected abstract int overridableSumTwo(int one, int second); + protected final int defaultSumTwo(int one, int second) { + return one + second; + } + // END: design.sidemeanings.arith.sumTwo + + public final int sumAll(int... numbers) { + return overridableSumAll(numbers); + } + protected abstract int overridableSumAll(int... numbers); + protected final int defaultSumAll(int... numbers) { + if (numbers.length == 0) { + return 0; + } + int sum = numbers[0]; + for (int i = 1; i < numbers.length; i++) { + // do I want to call sumTwo or defaultSumTwo? That is a question! + sum = openUpToSubclasses() ? + sumTwo(sum, numbers[i]) : + defaultSumTwo(sum, numbers[i]); + } + return sum; + } + + public final int sumRange(int from, int to) { + return overridableSumRange(from, to); + } + protected abstract int overridableSumRange(int from, int to); + protected final int defaultSumRange(int from, int to) { + int len = to - from; + if (len < 0) { + len = -len; + from = to; + } + int[] array = new int[len + 1]; + for (int i = 0; i <= len; i++) { + array[i] = from + i; + } + // BEGIN: design.sidemeanings.arith.the.question + // Again, an API author has to ask what sumAll one wants to call? + // Am I about to open up to subclasses or do I want default impl? + return openUpToSubclasses() ? + sumAll(array) : + defaultSumAll(array); + // END: design.sidemeanings.arith.the.question + } + + boolean openUpToSubclasses = true; + boolean openUpToSubclasses() { + return openUpToSubclasses; + } + + + // BEGIN: design.sidemeanings.arith.factory + public static Arithmetica create() { + return new Arithmetica.Impl(); + } + private static class Impl extends Arithmetica { + @Override + protected int overridableSumTwo(int one, int second) { + return defaultSumTwo(one, second); + } + + @Override + protected int overridableSumAll(int... numbers) { + return defaultSumAll(numbers); + } + + @Override + protected int overridableSumRange(int from, int to) { + return defaultSumRange(from, to); + } + } + // END: design.sidemeanings.arith.factory + +} +// END: design.sidemeanings.arith diff -r a9ad091ed069 -r 4553c2885ce6 samples/sidemeanings/test/org/apidesign/sidemeanings/math/ArithmeticaTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/sidemeanings/test/org/apidesign/sidemeanings/math/ArithmeticaTest.java Fri Mar 27 20:30:39 2009 +0100 @@ -0,0 +1,44 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.apidesign.sidemeanings.math; + +import org.junit.Before; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Jaroslav Tulach + */ +public class ArithmeticaTest { + Arithmetica instance; + + public ArithmeticaTest() { + } + + @Before + public void setUp() { + instance = Arithmetica.create(); + } + + @Test + public void testSumTwo() { + assertEquals("+", 5, instance.sumTwo(3, 2)); + } + + @Test + public void testSumAll() { + assertEquals("+", 6, instance.sumAll(3, 2, 1)); + } + + @Test + public void testSumRange() { + assertEquals("1+2+3=6", 6, instance.sumRange(1, 3)); + assertEquals("sum(1,10)=55", 55, instance.sumRange(1, 10)); + assertEquals("sum(1,1)=1", 1, instance.sumRange(1, 1)); + assertEquals("sum(10,1)=55", 55, instance.sumRange(10, 1)); + } +} \ No newline at end of file diff -r a9ad091ed069 -r 4553c2885ce6 samples/sidemeanings/test/org/apidesign/sidemeanings/math/Factorial.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/sidemeanings/test/org/apidesign/sidemeanings/math/Factorial.java Fri Mar 27 20:30:39 2009 +0100 @@ -0,0 +1,27 @@ +package org.apidesign.sidemeanings.math; + +/** + */ +// BEGIN: design.sidemeanings.arith.factorial +public final class Factorial extends Arithmetica { + public int factorial(int n) { + return sumRange(1, n); + } + + @Override + protected int overridableSumTwo(int one, int second) { + return one * second; + } + + @Override + protected int overridableSumAll(int... numbers) { + return defaultSumAll(numbers); + } + + @Override + protected int overridableSumRange(int from, int to) { + return defaultSumRange(from, to); + } +} +// END: design.sidemeanings.arith.factorial + diff -r a9ad091ed069 -r 4553c2885ce6 samples/sidemeanings/test/org/apidesign/sidemeanings/math/FactorialNotPossibleInNotOpenedModeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/sidemeanings/test/org/apidesign/sidemeanings/math/FactorialNotPossibleInNotOpenedModeTest.java Fri Mar 27 20:30:39 2009 +0100 @@ -0,0 +1,29 @@ +package org.apidesign.sidemeanings.math; + +import org.junit.Before; +import org.junit.Test; + +/** + * + * @author Jaroslav Tulach + */ +public class FactorialNotPossibleInNotOpenedModeTest extends FactorialTest { + @Before @Override + public void setUp() { + instance = new Factorial(); + instance.openUpToSubclasses = false; + } + + @Test @Override + public void testFactorial4() { + if (Boolean.getBoolean("no.failures")) return; + super.testFactorial4(); + } + + @Test @Override + public void testFactorial5() { + if (Boolean.getBoolean("no.failures")) return; + super.testFactorial5(); + } + +} diff -r a9ad091ed069 -r 4553c2885ce6 samples/sidemeanings/test/org/apidesign/sidemeanings/math/FactorialTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/sidemeanings/test/org/apidesign/sidemeanings/math/FactorialTest.java Fri Mar 27 20:30:39 2009 +0100 @@ -0,0 +1,38 @@ +/* + * Žluťoučký kůň je naše hříbátko. + * and open the template in the editor. + */ + +package org.apidesign.sidemeanings.math; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * + * @author Jaroslav Tulach + */ +public class FactorialTest { + Factorial instance; + + @Before + public void setUp() { + instance = new Factorial(); + } + + @Test + public void testFactorial3() { + Assert.assertEquals(6, instance.factorial(3)); + } + + @Test + public void testFactorial4() { + Assert.assertEquals(24, instance.factorial(4)); + } + + @Test + public void testFactorial5() { + Assert.assertEquals(120, instance.factorial(5)); + } +}