90 likes | 118 Views
Learn about data abstraction operations including Creators, Producers, Mutators, and Observers. Discover the adequacy of APIs, examples like Polynomials and Complex Numbers, transformation from mutable to immutable objects, and the importance of controlling object creation through caching strategies like the Flyweight Pattern. Explore the balance between mutable and immutable classes for performance optimization.
E N D
Mutability SWE 332 Fall 2015 Paul Ammann
Data Abstraction Operation Categories • Creators • Create objects of a data abstraction • Producers • Create objects of their type based on existing objects • Typically used in immutable data types • Mutators • Modify objects of their type • Typically used in mutable data types • Observers • Take objects of their type as inputs and return results of other types
Adequacy of a API • Should provide enough operations so that users can manipulate objects conveniently and efficiently • Should have at least three of the four category operations • Should be fully populated • Possible to obtain every possible abstract object state
Some Examples • Polynomials – We’ve already seen this Poly.java • Complex numbers (pp 74-75 in Bloch) Complex.java • Note use of producers instead of mutators
Mutable/Immutable Transform • Mutable Stack example in Bloch (page 56) • Stack.java • Goal: Transform to an immutable version ImmutableStack s = new ImmutableStack(); s = s.push(“cat”); s = s.push(“dog”); • What do these objects look like?
Mutator Producer Consider a void mutator method in class C: public void mutator1(…) Corresponding producer method: public C producer1(…) Consider a non-void mutator method in class C: public S mutator2(…) Corresponding observer/producer methods are: public S observerPart(…) public C producerPart(…) Note that non-void mutator needs to be split into two methods. Example: pop() in Stack vs. pop(), top() in ImmutableStack
Typical Transformation • Typical method in mutable class Foo: public void foo(T1 t1, T2, t2, …) {modify “this”} • Immutable version of Foo: public Foo foo(T1 t1, T2, t2, …) { Foo f = … … return f; } • Functional programming vs. procedural programming.
Disadvantage: Performance • Typical approach: • Provide immutable class • Provide mutable companion class for situations where performance is an issue • Clients choose on performance needs • Example in Java Library: • String (Immutable) • StringBuilder (Companion Mutable Class) • Static factories can cache frequently used items
Caching Frequently Used Items • Goals: • Control creation of immutable objects • Limit occurrence of given object to 0 or 1 • Return existing object if possible, • Else construct new object • Flyweight Pattern • Requires a table of existing items • Table design is a key decision • Requires hiding constructors • Enables “fast” equals(), hashCode() • Memory leakage may be an issue