Deep copy 2026-10-24
A copy that duplicates the relevant reachable mutable structure instead of sharing all original references. A Memento pattern snapshot containing mutable arrays must preserve their saved contents against subsequent mutation, whether by a suitable deep copy or by an immutable persistent representation. The intended ownership graph and any permitted sharing must be specified; blindly copying one outer object is only a shallow copy.
Defensive copying 2026-10-24
Protect an owned mutable representation by copying mutable data received from clients and by returning independent copies instead of internal mutable objects. Copying only on entry leaves an accessor leak; copying only on exit leaves the constructor argument aliased. For an object containing only primitive fields, a field-by-field copy suffices. Nested mutable references can require a deep copy, immutable components or a stronger ownership contract.
The correctness argument follows aliases: after copying, no client-held reference reaches the owned mutable fields, and every public mutation goes through operations preserving the owner's representation invariant. Copying is one technique for encapsulation, not a substitute for deciding which state is meant to remain mutable.
Memento pattern 2026-10-24
A design in which an originator creates an opaque snapshot of its state, a caretaker retains it, and the originator can later restore it. Encapsulation prevents the caretaker from depending on internal state representation. A memento must freeze the relevant state: references to mutable objects can require a deep copy, while immutable values can safely be shared. Scala's access controls and path-dependent types can restrict snapshot construction and associate it with its originating instance.
Make defensive copies on both entry and exit, while keeping the supplied The private stored dimensions have no aliases exposed to the caller and are never changed. Mutating the constructor argument affects only the caller's object; mutating a returned
Dimension class unchanged:class Frame(d: Dimension) {
require(d != null)
private val saved = new Dimension(d.width, d.height)
private val savedArea = saved.width * saved.height
def area: Int = savedArea
def dimension: Dimension = new Dimension(saved.width, saved.height)
def isPortrait: Boolean = saved.height >= saved.width
}Dimension affects only a fresh copy. Consequently the stored area is calculated once and stays equal to the stored dimensions' product. This defensive copying is sufficient because Dimension contains only primitive fields; a more deeply nested mutable structure could require a deep copy or an immutable representation.The multiplication above deliberately retains the supplied class's
Int arithmetic and accessor type. If an exact mathematical area outside that range is required, compute once with saved.width.toLong * saved.height.toLong and expose Long instead; avoiding aliases and avoiding integer overflow are separate concerns.The Memento pattern supports saving and later restoring an object's state while preserving encapsulation. The originator creates a snapshot and knows how to restore it; the memento stores that snapshot; the caretaker retains mementos and decides when to request restoration, without depending on their representation. Undo history is a typical use.
Scala's nested class in object-oriented programming definitions, access qualifiers, immutable values and path-dependent types help keep snapshots opaque and associated with their originator. For example:
final class Editor {
private var text = ""
final class Snapshot private[Editor] (
private[Editor] val saved: String
)
def current: String = text
def edit(next: String): Unit = { text = next }
def save(): Snapshot = new Snapshot(text)
def restore(s: Snapshot): Unit = { text = s.saved }
}
val editor = new Editor
editor.edit("first version")
val saved: editor.Snapshot = editor.save()
editor.edit("later version")
editor.restore(saved)
assert(editor.current == "first version")The caretaker can retain
saved but cannot inspect its private contents or construct an arbitrary snapshot. editor.Snapshot is a type tied to the stable editor value; a snapshot from a different Editor is not interchangeable without an explicit type escape. An immutable string is safe to share in this example. If the originator held mutable arrays or mutable nodes, storing only references to them would not freeze their contents; the memento would need a deep copy or a persistent immutable representation.[ref]Scala 2.13 classes and objects specification. Qualified private and constructor access
[ref]Scala 2.13 types specification. Paths, stable identifiers and path-dependent types