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