Home | History | Annotate | Download | only in util
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html#License
      3 /*
      4  ******************************************************************************
      5  * Copyright (C) 2005-2012, International Business Machines Corporation and    *
      6  * others. All Rights Reserved.                                               *
      7  ******************************************************************************
      8 */
      9 package com.ibm.icu.util;
     10 
     11 /**
     12  * Provides a flexible mechanism for controlling access, without requiring that
     13  * a class be immutable. Once frozen, an object can never be unfrozen, so it is
     14  * thread-safe from that point onward. Once the object has been frozen,
     15  * it must guarantee that no changes can be made to it. Any attempt to alter
     16  * it must raise an UnsupportedOperationException exception. This means that when
     17  * the object returns internal objects, or if anyone has references to those internal
     18  * objects, that those internal objects must either be immutable, or must also
     19  * raise exceptions if any attempt to modify them is made. Of course, the object
     20  * can return clones of internal objects, since those are safe.
     21  * <h2>Background</h2>
     22  * <p>
     23  * There are often times when you need objects to be objects 'safe', so that
     24  * they can't be modified. Examples are when objects need to be thread-safe, or
     25  * in writing robust code, or in caches. If you are only creating your own
     26  * objects, you can guarantee this, of course -- but only if you don't make a
     27  * mistake. If you have objects handed into you, or are creating objects using
     28  * others handed into you, it is a different story. It all comes down to whether
     29  * you want to take the Blanche Dubois approach (&quot;depend on the kindness of
     30  * strangers&quot;) or the Andy Grove approach (&quot;Only the Paranoid
     31  * Survive&quot;).
     32  * </p>
     33  * <p>
     34  * For example, suppose we have a simple class:
     35  * </p>
     36  *
     37  * <pre>
     38  * public class A {
     39  *      protected Collection b;
     40  *
     41  *      protected Collection c;
     42  *
     43  *      public Collection get_b() {
     44  *              return b;
     45  *      }
     46  *
     47  *      public Collection get_c() {
     48  *              return c;
     49  *      }
     50  *
     51  *      public A(Collection new_b, Collection new_c) {
     52  *              b = new_b;
     53  *              c = new_c;
     54  *      }
     55  * }
     56  * </pre>
     57  *
     58  * <p>
     59  * Since the class doesn't have any setters, someone might think that it is
     60  * immutable. You know where this is leading, of course; this class is unsafe in
     61  * a number of ways. The following illustrates that.
     62  * </p>
     63  *
     64  * <pre>
     65  *  public test1(SupposedlyImmutableClass x, SafeStorage y) {
     66  *    // unsafe getter
     67  *    A a = x.getA();
     68  *    Collection col = a.get_b();
     69  *    col.add(something); // a has now been changed, and x too
     70  *
     71  *    // unsafe constructor
     72  *    a = new A(col, col);
     73  *    y.store(a);
     74  *    col.add(something); // a has now been changed, and y too
     75  *  }
     76  * </pre>
     77  *
     78  * <p>
     79  * There are a few different techniques for having safe classes.
     80  * </p>
     81  * <ol>
     82  * <li>Const objects. In C++, you can declare parameters const.</li>
     83  * <li>Immutable wrappers. For example, you can put a collection in an
     84  * immutable wrapper.</li>
     85  * <li>Always-Immutable objects. Java uses this approach, with a few
     86  * variations. Examples:
     87  * <ol>
     88  * <li>Simple. Once a Color is created (eg from R, G, and B integers) it is
     89  * immutable.</li>
     90  * <li>Builder Class. There is a separate 'builder' class. For example,
     91  * modifiable Strings are created using StringBuffer (which doesn't have the
     92  * full String API available). Once you want an immutable form, you create one
     93  * with toString().</li>
     94  * <li>Primitives. These are always safe, since they are copied on input/output
     95  * from methods.</li>
     96  * </ol>
     97  * </li>
     98  * <li>Cloning. Where you need an object to be safe, you clone it.</li>
     99  * </ol>
    100  * <p>
    101  * There are advantages and disadvantages of each of these.
    102  * </p>
    103  * <ol>
    104  * <li>Const provides a certain level of protection, but since const can be and
    105  * is often cast away, it only protects against most inadvertent mistakes. It
    106  * also offers no threading protection, since anyone who has a pointer to the
    107  * (unconst) object in another thread can mess you up.</li>
    108  * <li>Immutable wrappers are safer than const in that the constness can't be
    109  * cast away. But other than that they have all the same problems: not safe if
    110  * someone else keeps hold of the original object, or if any of the objects
    111  * returned by the class are mutable.</li>
    112  * <li>Always-Immutable Objects are safe, but usage can require excessive
    113  * object creation.</li>
    114  * <li>Cloning is only safe if the object truly has a 'safe' clone; defined as
    115  * one that <i>ensures that no change to the clone affects the original</i>.
    116  * Unfortunately, many objects don't have a 'safe' clone, and always cloning can
    117  * require excessive object creation.</li>
    118  * </ol>
    119  * <h2>Freezable Model</h2>
    120  * <p>
    121  * The <code>Freezable</code> model supplements these choices by giving you
    122  * the ability to build up an object by calling various methods, then when it is
    123  * in a final state, you can <i>make</i> it immutable. Once immutable, an
    124  * object cannot <i>ever </i>be modified, and is completely thread-safe: that
    125  * is, multiple threads can have references to it without any synchronization.
    126  * If someone needs a mutable version of an object, they can use
    127  * <code>cloneAsThawed()</code>, and modify the copy. This provides a simple,
    128  * effective mechanism for safe classes in circumstances where the alternatives
    129  * are insufficient or clumsy. (If an object is shared before it is immutable,
    130  * then it is the responsibility of each thread to mutex its usage (as with
    131  * other objects).)
    132  * </p>
    133  * <p>
    134  * Here is what needs to be done to implement this interface, depending on the
    135  * type of the object.
    136  * </p>
    137  * <h3><b>Immutable Objects</b></h3>
    138  * <p>
    139  * These are the easiest. You just use the interface to reflect that, by adding
    140  * the following:
    141  * </p>
    142  *
    143  * <pre>
    144  *  public class A implements Freezable<A> {
    145  *   ...
    146  *   public final boolean isFrozen() {return true;}
    147  *   public final A freeze() {return this;}
    148  *   public final A cloneAsThawed() { return this; }
    149  *   }
    150  * </pre>
    151  *
    152  * <p>
    153  * These can be final methods because subclasses of immutable objects must
    154  * themselves be immutable. (Note: <code>freeze</code> is returning
    155  * <code>this</code> for chaining.)
    156  * </p>
    157  * <h3><b>Mutable Objects</b></h3>
    158  * <p>
    159  * Add a protected 'flagging' field:
    160  * </p>
    161  *
    162  * <pre>
    163  * protected boolean immutable;
    164  * </pre>
    165  *
    166  * <p>
    167  * Add the following methods:
    168  * </p>
    169  *
    170  * <pre>
    171  * public final boolean isFrozen() {
    172  *      return frozen;
    173  * };
    174  *
    175  * public A freeze() {
    176  *      frozen = true;
    177  *      return this;
    178  * }
    179  * </pre>
    180  *
    181  * <p>
    182  * Add a <code>cloneAsThawed()</code> method following the normal pattern for
    183  * <code>clone()</code>, except that <code>frozen=false</code> in the new
    184  * clone.
    185  * </p>
    186  * <p>
    187  * Then take the setters (that is, any method that can change the internal state
    188  * of the object), and add the following as the first statement:
    189  * </p>
    190  *
    191  * <pre>
    192  * if (isFrozen()) {
    193  *      throw new UnsupportedOperationException(&quot;Attempt to modify frozen object&quot;);
    194  * }
    195  * </pre>
    196  *
    197  * <h4><b>Subclassing</b></h4>
    198  * <p>
    199  * Any subclass of a <code>Freezable</code> will just use its superclass's
    200  * flagging field. It must override <code>freeze()</code> and
    201  * <code>cloneAsThawed()</code> to call the superclass, but normally does not
    202  * override <code>isFrozen()</code>. It must then just pay attention to its
    203  * own getters, setters and fields.
    204  * </p>
    205  * <h4><b>Internal Caches</b></h4>
    206  * <p>
    207  * Internal caches are cases where the object is logically unmodified, but
    208  * internal state of the object changes. For example, there are const C++
    209  * functions that cast away the const on the &quot;this&quot; pointer in order
    210  * to modify an object cache. These cases are handled by mutexing the internal
    211  * cache to ensure thread-safety. For example, suppose that UnicodeSet had an
    212  * internal marker to the last code point accessed. In this case, the field is
    213  * not externally visible, so the only thing you need to do is to synchronize
    214  * the field for thread safety.
    215  * </p>
    216  * <h4>Unsafe Internal Access</h4>
    217  * <p>
    218  * Internal fields are called <i>safe</i> if they are either
    219  * <code>frozen</code> or immutable (such as String or primitives). If you've
    220  * never allowed internal access to these, then you are all done. For example,
    221  * converting UnicodeSet to be <code>Freezable</code> is just accomplished
    222  * with the above steps. But remember that you <i><b>have</b></i> allowed
    223  * access to unsafe internals if you have any code like the following, in a
    224  * getter, setter, or constructor:
    225  * </p>
    226  *
    227  * <pre>
    228  * Collection getStuff() {
    229  *      return stuff;
    230  * } // caller could keep reference &amp; modify
    231  *
    232  * void setStuff(Collection x) {
    233  *      stuff = x;
    234  * } // caller could keep reference &amp; modify
    235  *
    236  * MyClass(Collection x) {
    237  *      stuff = x;
    238  * } // caller could keep reference &amp; modify
    239  * </pre>
    240  *
    241  * <p>
    242  * These also illustrated in the code sample in <b>Background</b> above.
    243  * </p>
    244  * <p>
    245  * To deal with unsafe internals, the simplest course of action is to do the
    246  * work in the <code>freeze()</code> function. Just make all of your internal
    247  * fields frozen, and set the frozen flag. Any subsequent getter/setter will
    248  * work properly. Here is an example:
    249  * </p>
    250  *
    251  * <pre>
    252  * public A freeze() {
    253  *      if (!frozen) {
    254  *              foo.freeze();
    255  *              frozen = true;
    256  *      }
    257  *      return this;
    258  * }
    259  * </pre>
    260  *
    261  * <p>
    262  * If the field is a <code>Collection</code> or <code>Map</code>, then to
    263  * make it frozen you have two choices. If you have never allowed access to the
    264  * collection from outside your object, then just wrap it to prevent future
    265  * modification.
    266  * </p>
    267  *
    268  * <pre>
    269  * zone_to_country = Collections.unmodifiableMap(zone_to_country);
    270  * </pre>
    271  *
    272  * <p>
    273  * If you have <i>ever</i> allowed access, then do a <code>clone()</code>
    274  * before wrapping it.
    275  * </p>
    276  *
    277  * <pre>
    278  * zone_to_country = Collections.unmodifiableMap(zone_to_country.clone());
    279  * </pre>
    280  *
    281  * <p>
    282  * If a collection <i>(or any other container of objects)</i> itself can
    283  * contain mutable objects, then for a safe clone you need to recurse through it
    284  * to make the entire collection immutable. The recursing code should pick the
    285  * most specific collection available, to avoid the necessity of later
    286  * downcasing.
    287  * </p>
    288  * <blockquote>
    289  * <p>
    290  * <b>Note: </b>An annoying flaw in Java is that the generic collections, like
    291  * <code>Map</code> or <code>Set</code>, don't have a <code>clone()</code>
    292  * operation. When you don't know the type of the collection, the simplest
    293  * course is to just create a new collection:
    294  * </p>
    295  *
    296  * <pre>
    297  * zone_to_country = Collections.unmodifiableMap(new HashMap(zone_to_country));
    298  * </pre>
    299  *
    300  * </blockquote>
    301  * @stable ICU 3.8
    302  */
    303 public interface Freezable<T> extends Cloneable {
    304     /**
    305      * Determines whether the object has been frozen or not.
    306      * @stable ICU 3.8
    307      */
    308     public boolean isFrozen();
    309 
    310     /**
    311      * Freezes the object.
    312      * @return the object itself.
    313      * @stable ICU 3.8
    314      */
    315     public T freeze();
    316 
    317     /**
    318      * Provides for the clone operation. Any clone is initially unfrozen.
    319      * @stable ICU 3.8
    320      */
    321     public T cloneAsThawed();
    322 }
    323