Fact-checked by Grok 2 weeks ago

Value object

A value object is a core building block in (), representing a descriptive aspect of the that lacks conceptual identity and is defined solely by its attributes and associated behavior. Introduced by Eric Evans in his seminal work on DDD, value objects encapsulate values such as coordinates, monetary amounts, or addresses, where equality between instances is determined by matching attribute values rather than unique identifiers. Unlike entities, which maintain over time and track changes to that , value objects are interchangeable if their attributes align, promoting a focus on the intrinsic properties of the they represent. They are designed to be immutable, meaning their state cannot be modified after creation; instead, any required change results in a new instance, which avoids side effects and simplifies reasoning about the object's behavior. This immutability enhances code reliability, enables safe sharing across different parts of the system, and supports optimization in scenarios with high instance volumes, such as caching or . In practice, value objects often serve as components within larger aggregates, referencing entities without owning them, and their operations are typically pure functions that compute results based on attributes without relying on external mutable state. By distinguishing value objects from entities, DDD practitioners can reduce model complexity, clarify domain intent, and foster more expressive, maintainable software architectures. Common examples include a Money object with amount and currency attributes or an Address comprising street, city, and postal code, both of which are treated as immutable descriptors rather than trackable entities.

Overview

Definition

In , particularly within (DDD), a is a representing an immutable object that is defined solely by its attributes, lacking a unique conceptual identity. Two value objects are considered equal if all their corresponding attributes match, emphasizing their role as descriptors rather than distinguishable entities. This pattern originates in domain modeling, where value objects capture concepts such as measurements, quantities, or descriptors that hold meaning through their properties alone, without requiring lifecycle tracking or unique identification. Value objects encapsulate related data and associated behavior in a cohesive unit, ensuring operations on them produce no side effects and maintain through immutability—a trait that supports their equality-based comparison without altering state. For instance, a monetary amount might be modeled as a value object with attributes for currency and value, where equality is determined by matching these attributes, allowing interchangeable instances without identity concerns. Similarly, a point in a , defined by x and y values, exemplifies this: two point objects are equivalent if their coordinates align, regardless of their creation or memory location.

Historical Development

The value object pattern was formally introduced by Eric Evans in his 2003 book Domain-Driven Design: Tackling Complexity in the Heart of Software, where it forms one of the core tactical patterns of (DDD). Evans described value objects as domain elements distinguished by their attributes rather than by conceptual identity, enabling developers to model aspects of the domain that are interchangeable based on descriptive characteristics. This pattern's emphasis on structural equality and immutability echoes concepts from , particularly algebraic data types pioneered in the 1970s and 1980s with languages such as (introduced in 1973). Post-2003, the value object pattern gained traction in amid the expansion of agile methodologies, which encouraged iterative refinement of domain models through collaborative practices. Its adoption accelerated around 2010 alongside the rise of architectures, where value objects supported stateless, composable services by encapsulating domain invariants in lightweight, shareable forms. Notable integrations occurred in major frameworks during this period; for instance, the in , evolving through versions in the mid-2000s, facilitated value object usage in and persistence layers for DDD-based applications. Similarly, Microsoft's , launched in 2008 with .NET Framework 3.5 SP1, incorporated support for complex types resembling value objects to enable flexible in object-relational scenarios.

Core Concepts

Equality and Identity

In object-oriented design, particularly within , value objects are compared using , where two instances are considered equal if all their attribute values match, irrespective of their memory addresses or unique identifiers. This approach contrasts with , which relies on reference comparison or a distinct identifier to determine if two objects represent the same instance, a method typically reserved for objects with ongoing lifecycles or persistence requirements. The conceptual foundation for value equality in value objects stems from their role as interchangeable descriptors in the , lacking any inherent identity or need for tracking across time or contexts; thus, objects with identical values are treated as equivalent to simplify reasoning and avoid unnecessary distinctions. For instance, in , this is achieved by overriding the equals() and hashCode() methods to compare attribute values, ensuring that two Money objects both representing 10 USD are deemed equal regardless of when or how they were instantiated. This value-based comparison is reliably supported by the immutability of value objects, which prevents state changes that could invalidate equality checks.

Immutability and Thread Safety

In , value objects are required to be immutable, meaning their state cannot be altered after creation to preserve conceptual integrity and ensure that their identity—derived solely from attributes—remains consistent throughout their lifecycle. This immutability is enforced through design choices such as the absence of setter methods and the use of final or read-only fields in object-oriented languages, with all initialization occurring via constructors or factory methods that validate and set attributes atomically. As Eric Evans notes, "Immutability is a great simplifier in an , making and passing safe. It is also consistent with the meaning of a value." The inherent immutability of value objects confers , allowing multiple threads to access and share instances concurrently without the risk of corruption or the need for mechanisms like locks. Since no operations can modify the object's fields post-construction, concurrent reads pose no issues, simplifying concurrent programming and reducing the potential for conditions in multi-threaded environments. Value objects are instantiated using constructors for simple cases or static factory methods for more complex validations and derivations, ensuring that invariants are upheld from the outset. Any apparent "modification," such as updating an attribute, results in the creation and return of a new value object instance rather than altering the existing one, which maintains and avoids side effects. A representative example is an immutable Address value object, comprising attributes like street, city, and ; to reflect a change, such as a new street address, a fresh Address instance is constructed with the updated values, while the original remains unaltered for ongoing use elsewhere in the system. This approach aligns with comparisons based on attribute values, as the unchanged state guarantees consistent behavioral equivalence across instances.

Versus Entities

In (DDD), entities and value objects represent two fundamental building blocks for modeling domain concepts, distinguished primarily by the presence or absence of . Entities are objects defined not by their attributes but by a unique that persists through changes in their state, allowing them to be tracked over their lifecycle. For instance, a entity might be identified by a unique ID, enabling the system to follow its history even as details like address evolve. This is typically implemented as a or a conceptual identifier meaningful to the domain. In contrast, value objects lack any conceptual and are instead defined solely by the values of their attributes, making them interchangeable if those attributes match. They are designed to be immutable, meaning once created, their state cannot be modified; instead, a new value object is instantiated for any required changes. A classic example is an value object embedded within the aforementioned : two addresses with identical , , and details are considered equivalent, regardless of how they were created, and the object can be safely discarded and recreated without loss of meaning. This immutability promotes and simplifies reasoning about the object's behavior, as there is no need to manage ongoing . The key decision criteria for choosing between entities and value objects revolve around whether the domain concept requires continuity and historical tracking or merely descriptive attributes. Entities are appropriate for objects whose identity matters independently of their current state, such as those involved in processes that span time, like a whose balance changes but whose account number endures. Value objects, however, suit attributes that describe or qualify other domain elements without needing or uniqueness, reducing complexity by avoiding unnecessary . Equality for value objects is determined by structural comparison of attributes, aligning with their lack of , whereas entities rely on for distinction. A practical in an domain is an , which maintains a to track its status from placement to fulfillment, containing mutable details like shipping status. Within this , for LineItems serve as objects: a of 5 units is indistinguishable from another 5 units based solely on , and changes (e.g., updating to 6) result in a new object rather than modification, ensuring immutability and facilitating operations like subtotal calculations without concerns. This distinction enhances model clarity by reserving for lifecycle-managed concepts while leveraging objects for pure descriptors.

Versus Data Transfer Objects

Data Transfer Objects (DTOs) are simple structures designed to carry data across process boundaries, such as between layers in an application or over a network, primarily to minimize the number of remote method calls and optimize for formats like . They typically consist of public properties or fields with no associated behavior, focusing solely on for transport, and are often mutable to allow easy population during transfer. In contrast, value objects, as defined in (), represent domain concepts whose equality is determined by their attribute values rather than identity, and they encapsulate behavior relevant to the domain, such as validation or operations. For instance, a value object like a Money type might include methods for conversion or arithmetic, ensuring domain invariants are maintained through immutability. The key distinction lies in their purposes: DTOs address technical concerns of data transport and serialization, lacking domain semantics or logic, while value objects embody business rules and are integral to the . DTOs do not enforce domain validation or provide methods beyond getters and setters, making them unsuitable for logic. Value objects, being immutable, promote and predictability in concurrent environments, a property not inherent to DTOs. Although there can be superficial overlap—such as both using simple data structures—misusing DTOs as value objects or vice versa blurs architectural boundaries, leading to anemic domain models where behavior is separated from data. To maintain clean architecture, DTOs should remain as passive carriers without domain logic, while value objects stay within the domain layer. For example, a DTO might represent a as a flat structure with fields like name, email, and age for , allowing mutation during mapping but offering no validation. In comparison, an EmailAddress value object would include methods to validate format and normalize the address, rejecting invalid inputs and remaining immutable once created, thus enforcing domain rules.

Benefits and Applications

Design Advantages

Value objects simplify equality testing by defining equivalence based solely on their attribute values rather than object identity, thereby eliminating common bugs arising from unintended identity-based comparisons in software systems. This approach ensures that two value objects with identical attributes are treated as interchangeable, reducing errors in domain logic where developers might otherwise confuse distinct instances with the same conceptual value. The use of value objects enhances testability in domain models, as their immutability allows for straightforward creation of test instances without the need to mock or manage unique identities, facilitating reliable tests focused on behavioral . Equality assertions become precise and deterministic, enabling developers to validate domain rules efficiently without simulating complex state changes or dependencies. Value objects promote composition within domain-driven designs by serving as lightweight, interchangeable building blocks that encapsulate descriptive aspects of more complex entities, fostering modular and expressive models. For instance, attributes like addresses or monetary amounts can be composed into larger structures, enhancing the clarity and reusability of the overall domain language without introducing unnecessary identity concerns. By eschewing mutable shared state, value objects reduce between components in a software system, leading to more modular code that is easier to maintain and refactor over time. Their immutability prevents unintended side effects from shared references, allowing independent evolution of domain elements while preserving system integrity.

Real-World Use Cases

In applications, value objects such as encapsulate monetary amounts with their associated , enabling safe arithmetic operations like and while enforcing invariants such as preventing operations across different currencies. This modeling prevents common pitfalls in pricing and transaction processing, as demonstrated in implementations for online retail systems. Similarly, serves as a value object for inventory , combining a numeric value with units (e.g., units or kilograms) and built-in validation to ensure non-negative values, thereby maintaining during stock updates and . In geospatial applications, coordinates are modeled as value objects defined solely by their x and y properties, where equality is determined by these attributes rather than unique , facilitating precise location comparisons in software. Ranges, such as geographic bounds or route segments, as composite value objects comprising start and end points, supporting immutable representations of spatial extents in and GIS systems without the overhead of entity lifecycle management. Financial systems leverage date ranges as value objects to represent periods for calculations like interest accrual or reporting intervals, composed of start and end dates with methods to validate overlap or containment. Percentages are implemented as value objects with embedded validation to constrain values between 0 and 100, ensuring accurate handling in scenarios such as risk assessments or return computations while promoting type safety over primitive numeric types. In healthcare applications, measurements like are encapsulated as value objects that pair systolic and diastolic values with units (e.g., mmHg), providing built-in validation for physiological ranges and operations such as comparison to norms, which enhances data reliability in patient records and clinical decision support.

Implementation Strategies

General Principles

Value objects in () represent descriptive aspects of the domain that lack conceptual identity, focusing instead on their attributes and associated behavior. These objects are defined by the values of their properties, making them interchangeable if those values match, which simplifies modeling by eliminating the need to track unique identifiers. Key design rules for value objects emphasize simplicity and reliability. They must include no identity fields, such as unique IDs, to avoid the complexities of lifecycle management. is determined solely by comparing attribute values, requiring overrides of default equality methods to ensure two instances with identical values are treated as equivalent. Additionally, value objects should always validate their attributes during creation to enforce invariants, preventing invalid states from entering the system. Immutability is a core principle, with objects designed without setters and operations that return new instances rather than modifying existing ones, thereby avoiding side effects and issues. For integration into broader systems, value objects are typically composed within entities to encapsulate domain concepts, such as using an value object to describe a entity's location without assigning it a separate . Complex value object creation often employs factory methods or dedicated factory classes to handle validation logic and ensure objects are instantiated correctly, promoting encapsulation and reusability. This composition approach contrasts with entities, which maintain identity and lifecycle, allowing value objects to focus purely on descriptive roles. Testing value objects centers on verifying their behavioral contracts rather than object references. Assertions should compare attribute values directly, leveraging the value-based equality to confirm correctness, while unit tests must also validate immutability by ensuring operations do not alter the original instance. This reference-agnostic testing aligns with their design, enabling reliable checks on creation validation and side-effect-free methods without dependency on specific object instances. In terms of , value objects are particularly advantageous in distributed systems due to their immutability and lack of , which eliminate the need for mechanisms like locking or state coordination across nodes. This design facilitates easier replication and sharing in architectures, reducing overhead and improving overall system throughput by minimizing challenges inherent in mutable, identity-bound objects.

Language-Specific Examples

In programming languages that support object-oriented paradigms, value objects are typically implemented as immutable types where equality is determined by the values of their components rather than identity. This section illustrates idiomatic implementations across several languages, emphasizing equality semantics and immutability enforcement. Java
In Java, prior to version 14, value objects are commonly implemented as classes that override the equals and hashCode methods to compare component values, ensuring immutability through final fields and no setters. For example, a Money value object might be defined as follows:
java
public class Money {
    private final int amount;
    private final String currency;

    public Money(int amount, String currency) {
        this.amount = amount;
        this.currency = currency;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Money money = (Money) obj;
        return amount == money.amount && Objects.equals(currency, money.currency);
    }

    @Override
    public int hashCode() {
        return Objects.hash(amount, currency);
    }

    // Getters only
    public int getAmount() { return amount; }
    public String getCurrency() { return currency; }
}
Records, introduced as a preview feature in Java 14 and standardized in Java 16, provide a concise way to define immutable value objects, automatically generating equals, hashCode, and toString based on components, with all fields being final. An equivalent Money record is:
java
public record Money(int amount, String currency) {}
This approach reduces boilerplate while enforcing value-based equality. C#
In C#, value objects are implemented by inheriting from a base class or directly defining classes that implement IEquatable<T> for typed equality, combined with immutable properties using readonly fields or private setters. Records, introduced in C# 9, offer a modern alternative similar to Java's, providing built-in immutability and value equality. For a traditional class-based Money value object:
csharp
using System;

public class Money : IEquatable<Money>
{
    public int Amount { get; }
    public string Currency { get; }

    public Money(int amount, string currency)
    {
        Amount = amount;
        Currency = currency;
    }

    public bool Equals(Money other)
    {
        if (other is null) return false;
        if (ReferenceEquals(this, other)) return true;
        return Amount == other.Amount && Currency == other.Currency;
    }

    public override bool Equals(object obj) => Equals(obj as Money);

    public override int GetHashCode() => HashCode.Combine(Amount, Currency);
}
Using C# records for the same:
csharp
public record Money(int Amount, string Currency);
This ensures structural equality without manual overrides. Python
Python's dataclasses module, introduced in version 3.7, simplifies value object creation with the @dataclass decorator, which generates __init__, __repr__, and __eq__ methods by default. Setting frozen=True enforces immutability by raising exceptions on attribute assignment post-initialization. For a Money value object:
python
from dataclasses import dataclass

@dataclass(frozen=True)
class [Money](/page/Money):
    amount: [int](/page/INT)
    currency: [str](/page/€STR)
This automatically provides value-based :
python
m1 = [Money](/page/Money)(100, "USD")
m2 = [Money](/page/Money)(100, "USD")
print(m1 == m2)  # True
m1.amount = 200  # Raises FrozenInstanceError
For more control, __eq__ can be overridden manually in a non-dataclass or customized dataclass. Kotlin
Kotlin's data classes, marked with the data keyword, are designed for value objects, automatically generating equals, hashCode, and toString based on properties in the primary constructor. Immutability is achieved by declaring properties as val (read-only) rather than var. A [Money](/page/Money) data class example:
kotlin
data class Money(val amount: Int, val currency: String)
Usage demonstrates value equality:
kotlin
val m1 = Money(100, "USD")
val m2 = Money(100, "USD")
println(m1 == m2)  // true
Properties must be in the primary constructor for inclusion in generated methods; secondary constructors can initialize them. C++
In C++, value objects are often represented as plain structs with manually overloaded operator== for component-wise equality, and const members for immutability. No built-in language feature automates this, but standard library utilities like std::tie can simplify comparisons. For a Money struct (C++11+):
cpp
#include <string>
#include <tuple>

struct Money {
    const int amount;
    const std::string currency;

    bool operator==(const Money& other) const {
        return std::tie(amount, currency) == std::tie(other.amount, other.currency);
    }
};
Instances are immutable if no non-const methods modify members, aligning with value semantics.

Challenges and Considerations

Common Pitfalls

One common pitfall in implementing value objects is accidentally introducing mutability, such as by providing public setters or allowing internal state changes after construction. This undermines the core principle that value objects should remain immutable to ensure thread-safety, predictability, and equality based solely on attributes, as mutability can lead to inconsistent behavior across shared instances. To avoid this, enforce immutability through private constructors, final fields, and defensive copying in any methods that return internal components, treating the object as a fixed descriptor rather than a modifiable structure. Another frequent error is implementing the equals method without correspondingly overriding hashCode, which can cause subtle bugs in collections like HashSet or HashMap where objects with equivalent values are treated as distinct. In , value objects rely on value —comparing attributes rather than references—so inconsistent hashCode implementations violate the required for reliable hashing and can result in data duplication or failed lookups. Developers should always generate hashCode based on the same attributes used in equals, ensuring consistency to prevent these collection-related issues. Overusing identity in value objects, such as by adding unique IDs or lifecycle tracking, blurs the distinction from entities and introduces unnecessary , as value objects are defined by their structural attributes without conceptual . This mistake often stems from persistence concerns leaking into the , leading to objects that behave like entities despite representing interchangeable values like addresses or measurements. To mitigate this, rigorously assess whether is domain-relevant; if two objects with identical attributes are semantically equivalent, omit IDs and focus on attribute-based equality. Nesting mutable objects within value objects compromises overall immutability, as changes to the inner object can indirectly alter the outer one's state, defeating the purpose of treating the composite as a fixed . For instance, embedding a mutable collection or inside a object risks side effects that propagate unexpectedly. The is to compose objects exclusively from other immutable objects or primitives, validating and freezing nested structures during construction to maintain the of unchangeability.

Performance Implications

Value objects, being immutable by design, introduce specific trade-offs in memory usage. While mutating a value object requires creating a new instance rather than modifying an existing one, this can lead to higher rates of object allocation and potential collection pressure in scenarios involving frequent updates. However, immutability enables safe sharing of instances across different parts of the without risk of unintended modifications, thereby reducing the need for defensive copying and minimizing aliasing-related overhead. This sharing capability often results in net savings, particularly for small, frequently used value objects, as identical values can the same instance. In terms of computational efficiency, value objects rely on structural equality comparisons based on their attributes, which are generally more expensive than the reference equality checks used for entities. Attribute-based equality involves iterating over fields to verify sameness, incurring a cost proportional to the object's complexity, whereas reference equality is a simple pointer comparison. Similarly, generating hash codes for value objects typically requires computing a value from all attributes, though this can be precomputed and cached at construction time due to immutability, avoiding repeated calculations. These operations add overhead in collections or hash-based structures but are often offset by the predictability and simplicity of immutable designs. To mitigate performance costs, caching strategies such as interning or can be applied to value objects, promoting reuse of common instances. For example, in , the String.intern() method maintains a of unique string instances, allowing identical values to share memory and enabling faster equality checks via reference comparison (==) instead of value-based equals(). This approach reduces both and comparison time for high-frequency value objects like identifiers or coordinates, though it introduces lookup overhead in the . Such techniques are particularly beneficial in domain-driven designs where value objects represent primitive-like descriptors. Overall, while value objects may impose a modest computational burden in high-volume or hashing scenarios, their immutability supports thread-safe sharing without costs, enhancing concurrency performance in multi-threaded environments.

References

  1. [1]
    [PDF] Domain-‐Driven Design Reference
    Cluster the entities and value objects into aggregates and define boundaries around each. Choose one entity to be the root of each aggregate, and allow ...
  2. [2]
    Value Object - Martin Fowler
    Nov 14, 2016 · Objects that are equal due to the value of their properties, in this case their x and y coordinates, are called value objects.
  3. [3]
    Implementing value objects - .NET - Microsoft Learn
    Sep 20, 2022 · A value object can reference other entities. For example, in an application that generates a route that describes how to get from one point to another, that ...Important characteristics of... · Value object implementation in...<|control11|><|separator|>
  4. [4]
    Evans Classification - Martin Fowler
    Dec 14, 2005 · Value Object: Objects that matter only as the combination of their attributes. Two value objects with the same values for all their attributes ...
  5. [5]
    Domain Driven Design - Martin Fowler
    Apr 22, 2020 · The book introduced the notion of classifying objects into Entities, Value Objects, and Service Objects - what I call the Evans Classification ...
  6. [6]
    Domain modeling by Algebraic Data Types (part 1) - Thoughtworks
    Apr 7, 2022 · We usually use algebraic data types to model the business. ADT is a structured type formed from a composite of other types.
  7. [7]
    Algebraic API Design - Types, Functions, Properties - Typelevel
    Feb 6, 2019 · In functional programming algebras are expressed with types, functions and properties; This relates nicely to types of entities and value ...
  8. [8]
    Best Practice - An Introduction To Domain-Driven Design
    In this article, I'll cover the basic concepts and design patterns germane to DDD. Think of this article as a gentle introduction to designing and evolving rich ...
  9. [9]
    Microservices - Martin Fowler
    The microservice architectural style 1 is an approach to developing a single application as a suite of small services, each running in its own process.
  10. [10]
    Using @Value :: Spring Framework
    @Value is typically used to inject externalized properties: · With the following configuration: · A default lenient embedded value resolver is provided by Spring.
  11. [11]
    Achieve Flexible Data Modeling with the Entity Framework
    First introduced as ADO.NET vNext in 2006, the framework is now ready for prime time with the upcoming release of Visual Studio® 2008 SP1. After a couple of ...
  12. [12]
    Value Object - Martin Fowler
    Value Object. A small simple object, like money or a date range, whose equality isn't based on identity. With object systems of various kinds, I've found it ...
  13. [13]
    [PDF] Domain-driven design: Tackling complexity in the heart of software
    This pattern is most often applied to the operations of a VALUE OBJECT. Since the lifecycle of an ENTITY has significance in the domain, so you can't just ...
  14. [14]
    Domain-Driven Design: Tackling Complexity in the Heart of Software
    30-day returnsAug 20, 2003 · Domain-Driven Design: Tackling Complexity in the Heart of Software ... ENTITY FACTORIES Versus VALUE OBJECT FACTORIES. Reconstituting ...
  15. [15]
    Data Transfer Object - Martin Fowler
    An object that carries data between processes in order to reduce the number of method calls. When you're working with a remote interface, such as Remote Facade ...
  16. [16]
    DTO vs Value Object vs POCO - Enterprise Craftsmanship
    Apr 13, 2015 · It conforms to the same rules as Entity. The only difference between Value Object and Entity is that Value Object doesn't have its own identity.
  17. [17]
    Difference Between POJO, JavaBeans, DTO and VO | Baeldung
    Jan 16, 2024 · In this tutorial, we'll learn what Data Transfer Object (DTO), Value Object (VO), Plain Old Java Object (POJO), and JavaBeans are.
  18. [18]
    Value Object vs. Data Transfer Object (VO vs. DTO) - adam bien's blog
    Aug 19, 2009 · The pattern which is known today as Data Transfer Object was mistakenly (see this definition) called Value Object in the first version of the Core J2EE ...
  19. [19]
  20. [20]
    Domain-Driven Design Case Study: So We Thought We Knew Money
    Feb 22, 2007 · The first issue they come across is feature creep within a class. This is only the start. These value objects are now widely used in the system.
  21. [21]
    Domain Driven Design and Development In Practice - InfoQ
    Jun 12, 2008 · Domain objects should be designed using Plain Java Classes and Interfaces by taking advantage of OOP concepts like inheritance, encapsulation, ...
  22. [22]
    Domain Driven Design (DDD) - Delivery Playbooks - Rise8
    Value Objects: Objects that describe characteristics but have no identity ... Better handling of distributed systems; More straightforward to scale specific ...
  23. [23]
    6 Record Classes - Java - Oracle Help Center
    Record classes, which are a special kind of class, help to model plain data aggregates with less ceremony than normal classes.
  24. [24]
    dataclasses — Data Classes — Python 3.14.0 documentation
    This module provides a decorator and functions for automatically adding generated special methods such as __init__() and __repr__() to user-defined classes.Dataclasses -- Data Classes · Module Contents · Mutable Default Values
  25. [25]
    Data classes | Kotlin Documentation
    Oct 2, 2025 · Data classes in Kotlin are primarily used to hold data. For each data class, the compiler automatically generates additional member functions.Note · Properties Declared In The... · Copying
  26. [26]
    Implementing Domain-Driven Design - InformIT
    30-day returnsImplementing Domain-Driven Design presents a top-down approach to understanding domain-driven design (DDD) in a way that fluently connects strategic patterns.
  27. [27]
    Immutability Changes Everything - ACM Queue
    Jan 20, 2016 · As immutability is leveraged in all these ways, there are tradeoffs to be managed. Denormalized documents help with read performance at the ...
  28. [28]
    String (Java Platform SE 8 )
    ### Summary of String.intern() from https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#intern()