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-2016, 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&lt;A&gt; {
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 volatile boolean frozen; // WARNING: must be volatile
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;  // WARNING: must be final statement before return
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  * <p><b>Warning!</b> The 'frozen' boolean MUST be volatile, and must be set as the last statement
251  * in the method.</p>
252  * <pre>
253  * public A freeze() {
254  *      if (!frozen) {
255  *              foo.freeze();
256  *              frozen = true;
257  *      }
258  *      return this;
259  * }
260  * </pre>
261  *
262  * <p>
263  * If the field is a <code>Collection</code> or <code>Map</code>, then to
264  * make it frozen you have two choices. If you have never allowed access to the
265  * collection from outside your object, then just wrap it to prevent future
266  * modification.
267  * </p>
268  *
269  * <pre>
270  * zone_to_country = Collections.unmodifiableMap(zone_to_country);
271  * </pre>
272  *
273  * <p>
274  * If you have <i>ever</i> allowed access, then do a <code>clone()</code>
275  * before wrapping it.
276  * </p>
277  *
278  * <pre>
279  * zone_to_country = Collections.unmodifiableMap(zone_to_country.clone());
280  * </pre>
281  *
282  * <p>
283  * If a collection <i>(or any other container of objects)</i> itself can
284  * contain mutable objects, then for a safe clone you need to recurse through it
285  * to make the entire collection immutable. The recursing code should pick the
286  * most specific collection available, to avoid the necessity of later
287  * downcasing.
288  * </p>
289  * <blockquote>
290  * <p>
291  * <b>Note: </b>An annoying flaw in Java is that the generic collections, like
292  * <code>Map</code> or <code>Set</code>, don't have a <code>clone()</code>
293  * operation. When you don't know the type of the collection, the simplest
294  * course is to just create a new collection:
295  * </p>
296  *
297  * <pre>
298  * zone_to_country = Collections.unmodifiableMap(new HashMap(zone_to_country));
299  * </pre>
300  *
301  * </blockquote>
302  * @stable ICU 3.8
303  */
304 public interface Freezable<T> extends Cloneable {
305     /**
306      * Determines whether the object has been frozen or not.
307      * @stable ICU 3.8
308      */
isFrozen()309     public boolean isFrozen();
310 
311     /**
312      * Freezes the object.
313      * @return the object itself.
314      * @stable ICU 3.8
315      */
freeze()316     public T freeze();
317 
318     /**
319      * Provides for the clone operation. Any clone is initially unfrozen.
320      * @stable ICU 3.8
321      */
cloneAsThawed()322     public T cloneAsThawed();
323 }
324