Adding example with factory method for unsynchronized StringBuffer
authorJaroslav Tulach <jtulach@netbeans.org>
Sat, 14 Jun 2008 09:58:03 +0200
changeset 1518a1e5fd8e077
parent 150 7bb92c7ec747
child 152 eb6f29070331
Adding example with factory method for unsynchronized StringBuffer
samples/composition/src-api2.0-enum/api/Arithmetica.java
samples/individualsamples/src/org/apidesign/samples/StringBuffer.java
samples/individualsamples/test/org/apidesign/samples/StringBufferTest.java
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/samples/composition/src-api2.0-enum/api/Arithmetica.java	Sat Jun 14 09:58:03 2008 +0200
     1.3 @@ -0,0 +1,59 @@
     1.4 +package api;
     1.5 +
     1.6 +/** Class to simplify arithmetical operations, improved version to compute
     1.7 + * the sum for ranges, but only if one uses the new constructor to indicate
     1.8 + * need for new version.
     1.9 + *
    1.10 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    1.11 + * @version 2.0
    1.12 + */
    1.13 +// BEGIN: design.composition.arith2.0.enum
    1.14 +public class Arithmetica {
    1.15 +    private final Version version;
    1.16 +    public enum Version { VERSION_1_0, VERSION_2_0 }
    1.17 +    
    1.18 +    public Arithmetica() {
    1.19 +        this(Version.VERSION_1_0);
    1.20 +    }
    1.21 +    public Arithmetica(Version version) {
    1.22 +        this.version = version;
    1.23 +    }
    1.24 +
    1.25 +    public int sumRange(int from, int to) {
    1.26 +        switch (version) {
    1.27 +            case VERSION_1_0:
    1.28 +                return sumRange1(from, to);
    1.29 +            case VERSION_2_0:
    1.30 +                return sumRange2(from, to);
    1.31 +            default:
    1.32 +                throw new IllegalStateException();
    1.33 +        }
    1.34 +    }
    1.35 +// END: design.composition.arith2.0.enum
    1.36 +    
    1.37 +    public int sumTwo(int one, int second) {
    1.38 +        return one + second;
    1.39 +    }
    1.40 +    
    1.41 +    public int sumAll(int... numbers) {
    1.42 +        int sum = numbers[0];
    1.43 +        for (int i = 1; i < numbers.length; i++) {
    1.44 +            sum = sumTwo(sum, numbers[i]);
    1.45 +        }
    1.46 +        return sum;
    1.47 +    }
    1.48 +    
    1.49 +
    1.50 +    private int sumRange1(int from, int to) {
    1.51 +        int len = to - from;
    1.52 +        int[] array = new int[len + 1];
    1.53 +        for (int i = 0; i <= len; i++) {
    1.54 +            array[i] = from + i;
    1.55 +        }
    1.56 +        return sumAll(array);
    1.57 +    }
    1.58 +    
    1.59 +    private int sumRange2(int from, int to) {
    1.60 +        return (from + to) * (to - from + 1) / 2;
    1.61 +    }
    1.62 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/samples/individualsamples/src/org/apidesign/samples/StringBuffer.java	Sat Jun 14 09:58:03 2008 +0200
     2.3 @@ -0,0 +1,56 @@
     2.4 +package org.apidesign.samples;
     2.5 +
     2.6 +import java.util.ArrayList;
     2.7 +import java.util.List;
     2.8 +
     2.9 +public class StringBuffer {
    2.10 +    private List<String> all = new ArrayList<String>();
    2.11 +    
    2.12 +    public StringBuffer() {
    2.13 +        // prevent subclassing from 3rd party code
    2.14 +        if (getClass() != StringBuffer.class && getClass() != StringBufferUnsynch.class) {
    2.15 +            throw new IllegalStateException();
    2.16 +        }
    2.17 +    }
    2.18 +    
    2.19 +    // BEGIN: string.buffer.factory
    2.20 +    public static StringBuffer createUnsynchronized() {
    2.21 +        return new StringBufferUnsynch();
    2.22 +    }
    2.23 +    // END: string.buffer.factory
    2.24 +    
    2.25 +    public synchronized StringBuffer append(String s) {
    2.26 +        return appendImpl(s);
    2.27 +    }
    2.28 +    
    2.29 +    @Override
    2.30 +    public synchronized String toString() {
    2.31 +        return toStringImpl();
    2.32 +    }
    2.33 +    
    2.34 +    final String toStringImpl() {
    2.35 +        String ret = "";
    2.36 +        for (String s : all) {
    2.37 +            ret += s;
    2.38 +        }
    2.39 +        return ret;
    2.40 +    }
    2.41 +    
    2.42 +    
    2.43 +    final StringBuffer appendImpl(String s) {
    2.44 +        all.add(s);
    2.45 +        return this;
    2.46 +    }
    2.47 +    
    2.48 +    
    2.49 +    private static final class StringBufferUnsynch extends StringBuffer {
    2.50 +        @Override
    2.51 +        public StringBuffer append(String s) {
    2.52 +            return appendImpl(s);
    2.53 +        }
    2.54 +        @Override
    2.55 +        public String toString() {
    2.56 +            return toStringImpl();
    2.57 +        }
    2.58 +    }
    2.59 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/samples/individualsamples/test/org/apidesign/samples/StringBufferTest.java	Sat Jun 14 09:58:03 2008 +0200
     3.3 @@ -0,0 +1,69 @@
     3.4 +package org.apidesign.samples;
     3.5 +
     3.6 +import java.util.logging.Level;
     3.7 +import java.util.logging.Logger;
     3.8 +import org.junit.After;
     3.9 +import org.junit.AfterClass;
    3.10 +import org.junit.Before;
    3.11 +import org.junit.BeforeClass;
    3.12 +import org.junit.Test;
    3.13 +import static org.junit.Assert.*;
    3.14 +
    3.15 +public class StringBufferTest {
    3.16 +    @Test
    3.17 +    public void createRegular() {
    3.18 +        StringBuffer sb = new StringBuffer();
    3.19 +        assertAddAndToString(sb);
    3.20 +    }
    3.21 +
    3.22 +    @Test
    3.23 +    public void createUnsynchronized() throws InterruptedException {
    3.24 +        final StringBuffer sb = StringBuffer.createUnsynchronized();
    3.25 +        
    3.26 +        class Lock extends Thread {
    3.27 +            int state;
    3.28 +            
    3.29 +            @Override
    3.30 +            public void run() {
    3.31 +                synchronized (sb) {
    3.32 +                    try {
    3.33 +                        state = 1;
    3.34 +                        sb.notifyAll();
    3.35 +                        sb.wait();
    3.36 +                        state = 2;
    3.37 +                    } catch (InterruptedException ex) {
    3.38 +                        Logger.getLogger(StringBufferTest.class.getName()).log(Level.SEVERE, null, ex);
    3.39 +                    }
    3.40 +                }
    3.41 +            }
    3.42 +            
    3.43 +            public void waitLocked() throws InterruptedException {
    3.44 +                synchronized (sb) {
    3.45 +                    for (;;) {
    3.46 +                        if (state == 1) {
    3.47 +                            return;
    3.48 +                        }
    3.49 +                        sb.wait();
    3.50 +                    }
    3.51 +                }
    3.52 +            }
    3.53 +        }
    3.54 +        Lock lock = new Lock();
    3.55 +        lock.start();
    3.56 +        lock.waitLocked();
    3.57 +        
    3.58 +        assertEquals("result is really locked", 1, lock.state);
    3.59 +        
    3.60 +        assertAddAndToString(sb);
    3.61 +        
    3.62 +        assertEquals("result is still locked", 1, lock.state);
    3.63 +    }
    3.64 +
    3.65 +    private void assertAddAndToString(StringBuffer sb) {
    3.66 +        sb.append("Hello").append(" ");
    3.67 +        sb.append("API").append(" Design!");
    3.68 +        
    3.69 +        assertEquals("Hello API Design!", sb.toString());
    3.70 +    }
    3.71 +
    3.72 +}
    3.73 \ No newline at end of file