# HG changeset patch # User Jaroslav Tulach # Date 1213430283 -7200 # Node ID 8a1e5fd8e077347e857b683618a13ae0d3971410 # Parent 7bb92c7ec747fcc0de3acb81e8c9087f2f74757a Adding example with factory method for unsynchronized StringBuffer diff -r 7bb92c7ec747 -r 8a1e5fd8e077 samples/composition/src-api2.0-enum/api/Arithmetica.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/composition/src-api2.0-enum/api/Arithmetica.java Sat Jun 14 09:58:03 2008 +0200 @@ -0,0 +1,59 @@ +package api; + +/** Class to simplify arithmetical operations, improved version to compute + * the sum for ranges, but only if one uses the new constructor to indicate + * need for new version. + * + * @author Jaroslav Tulach + * @version 2.0 + */ +// BEGIN: design.composition.arith2.0.enum +public class Arithmetica { + private final Version version; + public enum Version { VERSION_1_0, VERSION_2_0 } + + public Arithmetica() { + this(Version.VERSION_1_0); + } + public Arithmetica(Version version) { + this.version = version; + } + + public int sumRange(int from, int to) { + switch (version) { + case VERSION_1_0: + return sumRange1(from, to); + case VERSION_2_0: + return sumRange2(from, to); + default: + throw new IllegalStateException(); + } + } +// END: design.composition.arith2.0.enum + + public int sumTwo(int one, int second) { + return one + second; + } + + public int sumAll(int... numbers) { + int sum = numbers[0]; + for (int i = 1; i < numbers.length; i++) { + sum = sumTwo(sum, numbers[i]); + } + return sum; + } + + + private int sumRange1(int from, int to) { + int len = to - from; + int[] array = new int[len + 1]; + for (int i = 0; i <= len; i++) { + array[i] = from + i; + } + return sumAll(array); + } + + private int sumRange2(int from, int to) { + return (from + to) * (to - from + 1) / 2; + } +} diff -r 7bb92c7ec747 -r 8a1e5fd8e077 samples/individualsamples/src/org/apidesign/samples/StringBuffer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/individualsamples/src/org/apidesign/samples/StringBuffer.java Sat Jun 14 09:58:03 2008 +0200 @@ -0,0 +1,56 @@ +package org.apidesign.samples; + +import java.util.ArrayList; +import java.util.List; + +public class StringBuffer { + private List all = new ArrayList(); + + public StringBuffer() { + // prevent subclassing from 3rd party code + if (getClass() != StringBuffer.class && getClass() != StringBufferUnsynch.class) { + throw new IllegalStateException(); + } + } + + // BEGIN: string.buffer.factory + public static StringBuffer createUnsynchronized() { + return new StringBufferUnsynch(); + } + // END: string.buffer.factory + + public synchronized StringBuffer append(String s) { + return appendImpl(s); + } + + @Override + public synchronized String toString() { + return toStringImpl(); + } + + final String toStringImpl() { + String ret = ""; + for (String s : all) { + ret += s; + } + return ret; + } + + + final StringBuffer appendImpl(String s) { + all.add(s); + return this; + } + + + private static final class StringBufferUnsynch extends StringBuffer { + @Override + public StringBuffer append(String s) { + return appendImpl(s); + } + @Override + public String toString() { + return toStringImpl(); + } + } +} diff -r 7bb92c7ec747 -r 8a1e5fd8e077 samples/individualsamples/test/org/apidesign/samples/StringBufferTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/individualsamples/test/org/apidesign/samples/StringBufferTest.java Sat Jun 14 09:58:03 2008 +0200 @@ -0,0 +1,69 @@ +package org.apidesign.samples; + +import java.util.logging.Level; +import java.util.logging.Logger; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +public class StringBufferTest { + @Test + public void createRegular() { + StringBuffer sb = new StringBuffer(); + assertAddAndToString(sb); + } + + @Test + public void createUnsynchronized() throws InterruptedException { + final StringBuffer sb = StringBuffer.createUnsynchronized(); + + class Lock extends Thread { + int state; + + @Override + public void run() { + synchronized (sb) { + try { + state = 1; + sb.notifyAll(); + sb.wait(); + state = 2; + } catch (InterruptedException ex) { + Logger.getLogger(StringBufferTest.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + public void waitLocked() throws InterruptedException { + synchronized (sb) { + for (;;) { + if (state == 1) { + return; + } + sb.wait(); + } + } + } + } + Lock lock = new Lock(); + lock.start(); + lock.waitLocked(); + + assertEquals("result is really locked", 1, lock.state); + + assertAddAndToString(sb); + + assertEquals("result is still locked", 1, lock.state); + } + + private void assertAddAndToString(StringBuffer sb) { + sb.append("Hello").append(" "); + sb.append("API").append(" Design!"); + + assertEquals("Hello API Design!", sb.toString()); + } + +} \ No newline at end of file