| /* |
| ****************************************************************************** |
| * Copyright (C) 2005-2012, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ****************************************************************************** |
| */ |
| package com.ibm.icu.util; |
| |
| /** |
| * Provides a flexible mechanism for controlling access, without requiring that |
| * a class be immutable. Once frozen, an object can never be unfrozen, so it is |
| * thread-safe from that point onward. Once the object has been frozen, |
| * it must guarantee that no changes can be made to it. Any attempt to alter |
| * it must raise an UnsupportedOperationException exception. This means that when |
| * the object returns internal objects, or if anyone has references to those internal |
| * objects, that those internal objects must either be immutable, or must also |
| * raise exceptions if any attempt to modify them is made. Of course, the object |
| * can return clones of internal objects, since those are safe. |
| * <h2>Background</h2> |
| * <p> |
| * There are often times when you need objects to be objects 'safe', so that |
| * they can't be modified. Examples are when objects need to be thread-safe, or |
| * in writing robust code, or in caches. If you are only creating your own |
| * objects, you can guarantee this, of course -- but only if you don't make a |
| * mistake. If you have objects handed into you, or are creating objects using |
| * others handed into you, it is a different story. It all comes down to whether |
| * you want to take the Blanche Dubois approach ("depend on the kindness of |
| * strangers") or the Andy Grove approach ("Only the Paranoid |
| * Survive"). |
| * </p> |
| * <p> |
| * For example, suppose we have a simple class: |
| * </p> |
| * |
| * <pre> |
| * public class A { |
| * protected Collection b; |
| * |
| * protected Collection c; |
| * |
| * public Collection get_b() { |
| * return b; |
| * } |
| * |
| * public Collection get_c() { |
| * return c; |
| * } |
| * |
| * public A(Collection new_b, Collection new_c) { |
| * b = new_b; |
| * c = new_c; |
| * } |
| * } |
| * </pre> |
| * |
| * <p> |
| * Since the class doesn't have any setters, someone might think that it is |
| * immutable. You know where this is leading, of course; this class is unsafe in |
| * a number of ways. The following illustrates that. |
| * </p> |
| * |
| * <pre> |
| * public test1(SupposedlyImmutableClass x, SafeStorage y) { |
| * // unsafe getter |
| * A a = x.getA(); |
| * Collection col = a.get_b(); |
| * col.add(something); // a has now been changed, and x too |
| * |
| * // unsafe constructor |
| * a = new A(col, col); |
| * y.store(a); |
| * col.add(something); // a has now been changed, and y too |
| * } |
| * </pre> |
| * |
| * <p> |
| * There are a few different techniques for having safe classes. |
| * </p> |
| * <ol> |
| * <li>Const objects. In C++, you can declare parameters const.</li> |
| * <li>Immutable wrappers. For example, you can put a collection in an |
| * immutable wrapper.</li> |
| * <li>Always-Immutable objects. Java uses this approach, with a few |
| * variations. Examples: |
| * <ol> |
| * <li>Simple. Once a Color is created (eg from R, G, and B integers) it is |
| * immutable.</li> |
| * <li>Builder Class. There is a separate 'builder' class. For example, |
| * modifiable Strings are created using StringBuffer (which doesn't have the |
| * full String API available). Once you want an immutable form, you create one |
| * with toString().</li> |
| * <li>Primitives. These are always safe, since they are copied on input/output |
| * from methods.</li> |
| * </ol> |
| * </li> |
| * <li>Cloning. Where you need an object to be safe, you clone it.</li> |
| * </ol> |
| * <p> |
| * There are advantages and disadvantages of each of these. |
| * </p> |
| * <ol> |
| * <li>Const provides a certain level of protection, but since const can be and |
| * is often cast away, it only protects against most inadvertent mistakes. It |
| * also offers no threading protection, since anyone who has a pointer to the |
| * (unconst) object in another thread can mess you up.</li> |
| * <li>Immutable wrappers are safer than const in that the constness can't be |
| * cast away. But other than that they have all the same problems: not safe if |
| * someone else keeps hold of the original object, or if any of the objects |
| * returned by the class are mutable.</li> |
| * <li>Always-Immutable Objects are safe, but usage can require excessive |
| * object creation.</li> |
| * <li>Cloning is only safe if the object truly has a 'safe' clone; defined as |
| * one that <i>ensures that no change to the clone affects the original</i>. |
| * Unfortunately, many objects don't have a 'safe' clone, and always cloning can |
| * require excessive object creation.</li> |
| * </ol> |
| * <h2>Freezable Model</h2> |
| * <p> |
| * The <code>Freezable</code> model supplements these choices by giving you |
| * the ability to build up an object by calling various methods, then when it is |
| * in a final state, you can <i>make</i> it immutable. Once immutable, an |
| * object cannot <i>ever </i>be modified, and is completely thread-safe: that |
| * is, multiple threads can have references to it without any synchronization. |
| * If someone needs a mutable version of an object, they can use |
| * <code>cloneAsThawed()</code>, and modify the copy. This provides a simple, |
| * effective mechanism for safe classes in circumstances where the alternatives |
| * are insufficient or clumsy. (If an object is shared before it is immutable, |
| * then it is the responsibility of each thread to mutex its usage (as with |
| * other objects).) |
| * </p> |
| * <p> |
| * Here is what needs to be done to implement this interface, depending on the |
| * type of the object. |
| * </p> |
| * <h3><b>Immutable Objects</b></h3> |
| * <p> |
| * These are the easiest. You just use the interface to reflect that, by adding |
| * the following: |
| * </p> |
| * |
| * <pre> |
| * public class A implements Freezable<A> { |
| * ... |
| * public final boolean isFrozen() {return true;} |
| * public final A freeze() {return this;} |
| * public final A cloneAsThawed() { return this; } |
| * } |
| * </pre> |
| * |
| * <p> |
| * These can be final methods because subclasses of immutable objects must |
| * themselves be immutable. (Note: <code>freeze</code> is returning |
| * <code>this</code> for chaining.) |
| * </p> |
| * <h3><b>Mutable Objects</b></h3> |
| * <p> |
| * Add a protected 'flagging' field: |
| * </p> |
| * |
| * <pre> |
| * protected boolean immutable; |
| * </pre> |
| * |
| * <p> |
| * Add the following methods: |
| * </p> |
| * |
| * <pre> |
| * public final boolean isFrozen() { |
| * return frozen; |
| * }; |
| * |
| * public A freeze() { |
| * frozen = true; |
| * return this; |
| * } |
| * </pre> |
| * |
| * <p> |
| * Add a <code>cloneAsThawed()</code> method following the normal pattern for |
| * <code>clone()</code>, except that <code>frozen=false</code> in the new |
| * clone. |
| * </p> |
| * <p> |
| * Then take the setters (that is, any method that can change the internal state |
| * of the object), and add the following as the first statement: |
| * </p> |
| * |
| * <pre> |
| * if (isFrozen()) { |
| * throw new UnsupportedOperationException("Attempt to modify frozen object"); |
| * } |
| * </pre> |
| * |
| * <h4><b>Subclassing</b></h4> |
| * <p> |
| * Any subclass of a <code>Freezable</code> will just use its superclass's |
| * flagging field. It must override <code>freeze()</code> and |
| * <code>cloneAsThawed()</code> to call the superclass, but normally does not |
| * override <code>isFrozen()</code>. It must then just pay attention to its |
| * own getters, setters and fields. |
| * </p> |
| * <h4><b>Internal Caches</b></h4> |
| * <p> |
| * Internal caches are cases where the object is logically unmodified, but |
| * internal state of the object changes. For example, there are const C++ |
| * functions that cast away the const on the "this" pointer in order |
| * to modify an object cache. These cases are handled by mutexing the internal |
| * cache to ensure thread-safety. For example, suppose that UnicodeSet had an |
| * internal marker to the last code point accessed. In this case, the field is |
| * not externally visible, so the only thing you need to do is to synchronize |
| * the field for thread safety. |
| * </p> |
| * <h4>Unsafe Internal Access</h4> |
| * <p> |
| * Internal fields are called <i>safe</i> if they are either |
| * <code>frozen</code> or immutable (such as String or primitives). If you've |
| * never allowed internal access to these, then you are all done. For example, |
| * converting UnicodeSet to be <code>Freezable</code> is just accomplished |
| * with the above steps. But remember that you <i><b>have</b></i> allowed |
| * access to unsafe internals if you have any code like the following, in a |
| * getter, setter, or constructor: |
| * </p> |
| * |
| * <pre> |
| * Collection getStuff() { |
| * return stuff; |
| * } // caller could keep reference & modify |
| * |
| * void setStuff(Collection x) { |
| * stuff = x; |
| * } // caller could keep reference & modify |
| * |
| * MyClass(Collection x) { |
| * stuff = x; |
| * } // caller could keep reference & modify |
| * </pre> |
| * |
| * <p> |
| * These also illustrated in the code sample in <b>Background</b> above. |
| * </p> |
| * <p> |
| * To deal with unsafe internals, the simplest course of action is to do the |
| * work in the <code>freeze()</code> function. Just make all of your internal |
| * fields frozen, and set the frozen flag. Any subsequent getter/setter will |
| * work properly. Here is an example: |
| * </p> |
| * |
| * <pre> |
| * public A freeze() { |
| * if (!frozen) { |
| * foo.freeze(); |
| * frozen = true; |
| * } |
| * return this; |
| * } |
| * </pre> |
| * |
| * <p> |
| * If the field is a <code>Collection</code> or <code>Map</code>, then to |
| * make it frozen you have two choices. If you have never allowed access to the |
| * collection from outside your object, then just wrap it to prevent future |
| * modification. |
| * </p> |
| * |
| * <pre> |
| * zone_to_country = Collections.unmodifiableMap(zone_to_country); |
| * </pre> |
| * |
| * <p> |
| * If you have <i>ever</i> allowed access, then do a <code>clone()</code> |
| * before wrapping it. |
| * </p> |
| * |
| * <pre> |
| * zone_to_country = Collections.unmodifiableMap(zone_to_country.clone()); |
| * </pre> |
| * |
| * <p> |
| * If a collection <i>(or any other container of objects)</i> itself can |
| * contain mutable objects, then for a safe clone you need to recurse through it |
| * to make the entire collection immutable. The recursing code should pick the |
| * most specific collection available, to avoid the necessity of later |
| * downcasing. |
| * </p> |
| * <blockquote> |
| * <p> |
| * <b>Note: </b>An annoying flaw in Java is that the generic collections, like |
| * <code>Map</code> or <code>Set</code>, don't have a <code>clone()</code> |
| * operation. When you don't know the type of the collection, the simplest |
| * course is to just create a new collection: |
| * </p> |
| * |
| * <pre> |
| * zone_to_country = Collections.unmodifiableMap(new HashMap(zone_to_country)); |
| * </pre> |
| * |
| * </blockquote> |
| * @stable ICU 3.8 |
| */ |
| public interface Freezable<T> extends Cloneable { |
| /** |
| * Determines whether the object has been frozen or not. |
| * @stable ICU 3.8 |
| */ |
| public boolean isFrozen(); |
| |
| /** |
| * Freezes the object. |
| * @return the object itself. |
| * @stable ICU 3.8 |
| */ |
| public T freeze(); |
| |
| /** |
| * Provides for the clone operation. Any clone is initially unfrozen. |
| * @stable ICU 3.8 |
| */ |
| public T cloneAsThawed(); |
| } |