<rdf:RDF
    xmlns:s='http://snipsnap.org/rdf/snip-schema#'
    xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
    xml:base='http://wiki.moredesignpatterns.com/rdf'>
    <s:Snip rdf:about='http://wiki.moredesignpatterns.com/rdf#Value+Object+Implementation'
         s:oUser=''>
        <s:name>Value Object Implementation</s:name>
        <s:content>__Superseded by [Value Object Implementation v2].__&#xD;&#xA;&#xD;&#xA;A Value Object class is implemented like a regular immutable class. Query methods (getters, boolean query methods, etc.) simply return the requested state information. Command methods (setters, etc.) carry out the requested computation using method-local fields. They return a new instance of the Value Object class that gets initialized with the results of the computation taken from the method-local fields.&#xD;&#xA;&#xD;&#xA;There are a variety of implementation issues to be considered.&#xD;&#xA;&#xD;&#xA;* ~~Immutability.~~ Making an object immutable means that there are no state changing operations published to clients. You can make your life substantially easier (and your programs safer) if you can mark the fields of a value object class as final. This way, the compiler can catch any attempts to change a value object’s state after initialization has taken place. It also makes your immutable classes thread-safe.&#xD;&#xA;&#xD;&#xA;* ~~Identity, equality, and hash codes.~~ Values don’t have identity, so it is important to properly implement anything that has to do with equality. In Java, this means to implement the equals() and hashcode() methods. Two value objects that are distinct objects may still mean the same value, and equality checking needs to realize this. In contrast to this, two regular objects that are distinct are never equal (otherwise they would be values).&#xD;&#xA;&#xD;&#xA;* ~~Dropping synchronization.~~ With value objects, you can drop all synchronization code from your Value implementation. Please note that this does not hold true if you are sharing value objects to make sure that there is only one instance, see the discussion on value object sharing below.&#xD;&#xA;&#xD;&#xA;* ~~Separating concerns with the Body/Handle idiom.~~ In some languages, it is easy to separate the copying of the value from a method’s computation. In particular, in C++, using the Body/Handle idiom [Cop92], you can use a copy-on-write policy to create a copy on the fly so the Value’s body implementation itself does not have to worry about making the copy. Rather the handle object does it for its body. This makes implementation easier.&#xD;&#xA;&#xD;&#xA;* ~~Mapping values to database tables.~~ For persistence, you can (and usually should) map complex values to one or more columns of an enclosing table. For example, the ACCOUNT table in an RDBMS should have both a BALANCE_CURRENCY column and a BALANCE_AMOUNT column to hold an account’s balance. As you can see from the prefix BALANCE, we are mapping the balance attribute to two technically separate but conceptually related columns.&#xD;&#xA;&#xD;&#xA;* ~~Dealing with heavyweight value types.~~ For heavyweight value objects, you sometimes give up on immutability. The problem here is that depending on how they are used, a lot of heavyweight value objects may be created only to be dropped quickly, because they are only an intermediate computation result. Such programming may put a significant burden on the garbage collector and downgrade performance in general. In such cases, it may be best to let the client handle the copying. This puts the burden of watching over possibly unwanted side-effects on the client. In spirit, this is still a value type, even though it may look like just a regular class.&#xD;&#xA;&#xD;&#xA;* ~~Higher-order value types.~~ Some value types are best viewed as instantiations of value type constructors. A value type constructor is a value type that needs to be configured to give you a concrete value type. Traditional exam-ples are ranges as in Pascal or Modula-2 (and many other programming languages). To get a datatype that accepts only integers in the range of 1..12 you write this: {code}INTEGER MONTHS= INTEGER[1..12];{code} Another example are subsets. Unfortunately, Java supports neither range nor subset definitions.&#xD;&#xA;&#xD;&#xA;* ~~Language support.~~ Structured or object-oriented programming languages typically don’t support first-class value types. However, some well-known concepts can be used for value types. In Java 5, for example, you can use enums now to have an easily recognizable value type of finite cardinality. You still have to make sure your enum class is immutable, for example, by making its fields final---the compiler doesn’t help you ensure it.&#xD;&#xA;&#xD;&#xA;An important strategy for improving Value Object performance is sharing value objects (Value instances). Sharing value objects means making sure only one instance (or a defined pool) of any given value exists in the system. If you manage to efficiently share value objects, you can get a variety of performance benefits, for example, checking for object equality can be reduced to checking for object identity. Also, memory consumption and garbage collection can be reduced significantly.&#xD;&#xA;&#xD;&#xA;* ~~Using Factory and Flyweight.~~ For sharing, you typically have a factory create and track the Value instances, much like an Abstract Factory creates objects, and much like a Flyweight tracks its instances [GOF95]. It is common to hide the Value constructors and require clients to go through factory methods for new objects.&#xD;&#xA;&#xD;&#xA;* ~~Retrieving vs. creating.~~ Retrieving a shared object is typically more expensive than creating a new object. This is because you usually need to initialize an empty value object with the data used to retrieve the shared instance to create a hash code. In some circumstances, if the hash code is trivial, this may not be a problem.&#xD;&#xA;&#xD;&#xA;* ~~Reintroducing synchronization.~~ Sharing makes your life more complicated though. It reintroduces synchronization, because you can&apos;t have two Value instances denoting the same value in the system. Hence, in the retrieval process for the shared value object you need to synchronize if you are about to create a new Value instance because none existed yet for the requested value. So you take a speed penalty.&#xD;&#xA;&#xD;&#xA;* ~~Distinguishing by value type cardinality.~~ Sharing makes most sense if the value type’s cardinality (possible number of Value instances) is finite. Currency has a finite cardinality, Money has not. As a consequence, at some point of time, you have created all the Currency objects and can rest assured that this is the upper limit for memory consumption. With Money objects, of which there may be any number, you don’t know this.&#xD;&#xA;&#xD;&#xA;* ~~Improving performance through eager initialization.~~ If you know that your application makes extensive use of a specific finite-cardinality value type, then it makes sense create all instances when the system starts up; otherwise you should initialize them on-demand. A hybrid strategy, employed by the JDK’s BigInteger class is to create a frequently used subset during system startup and to create further instances on-demand.</s:content>
        <s:cUser>Dirk Riehle</s:cUser>
        <s:mUser>Dirk Riehle</s:mUser>
        <s:mTime>2006-09-19 06:49:23.888</s:mTime>
        <s:cTime>2006-07-10 16:16:24.632</s:cTime>
        <s:comments>
            <rdf:Bag>
                <rdf:li>
                    <s:Comment rdf:about='http://wiki.moredesignpatterns.com/rdf#comment-Value+Object+Implementation-1'
                         s:oUser=''>
                        <s:name>comment-Value Object Implementation-1</s:name>
                        <s:content>From [Johannes Brodwall]&#xD;&#xA;&#xD;&#xA;* You talk about mapping objects to the database. Another interesting aspect is mapping objects to the UI.&#xD;&#xA;&#xD;&#xA;* For languages other than Java, operator overloading is often used to simplify use of value objects. Consider something like: &quot;Date.today + 5.days&quot;. (Ruby)&#xD;&#xA;&#xD;&#xA;* You mention overriding equals and hashCode. In Java, you often want to implement Comparable as well.  </s:content>
                        <s:cUser>Dirk Riehle</s:cUser>
                        <s:mUser>Dirk Riehle</s:mUser>
                        <s:mTime>2006-07-17 15:00:38.176</s:mTime>
                        <s:cTime>2006-07-17 14:59:25.88</s:cTime>
                        <s:commentedSnip rdf:resource='http://wiki.moredesignpatterns.com/rdf#Value+Object+Implementation'/>
                    </s:Comment>
                </rdf:li>
            </rdf:Bag>
        </s:comments>
        <s:snipLinks>
            <rdf:Bag>
                <rdf:li rdf:resource='http://wiki.moredesignpatterns.com/rdf#Value Object'/>
                <rdf:li rdf:resource='#GOF95'/>
                <rdf:li rdf:resource='http://wiki.moredesignpatterns.com/rdf#Value Object Sample Code'/>
                <rdf:li rdf:resource='http://wiki.moredesignpatterns.com/rdf#Value Object Implementation v2'/>
                <rdf:li rdf:resource='http://wiki.moredesignpatterns.com/rdf#Dirk Riehle'/>
                <rdf:li rdf:resource='http://wiki.moredesignpatterns.com/rdf#Value Object Applicability v2'/>
                <rdf:li rdf:resource='#snipsnap-index'/>
                <rdf:li rdf:resource='http://wiki.moredesignpatterns.com/rdf#Value Object Collaborations'/>
            </rdf:Bag>
        </s:snipLinks>
        <s:attachments
             rdf:type='http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag'/>
    </s:Snip>
</rdf:RDF>
