If you've been designing software for any length of time, you've probably run into the concept of a "deep copy," usually contrasted with a "shallow copy." Wikipedia has a nice explanation.
Shallow copies are pretty straightforward. Most programming languages have a mechanism to make a shallow copy of an arbitrary object without any help from the implementor of the class. In C#, Object.MemberwiseClone does the trick.
Deep copies are a bit trickier. The usual approach in languages like C++, C#, and Java is for the class implementor to write a public Clone method which calls a protected copy constructor. The protected copy constructor recurses the copy operation on any reference or pointer fields in the class. This approach has two main problems. One of the problems has to do with copying graphs of objects. The problem (and an elegant solution) is described nicely here.
The other problem is it is often difficult for the class implementor to decide whether a referenced object should be copied (deep copy) or if that particular object should be shared between the old instance and the new (shallow copy). Sure, this object is being deep copied, but that doesn't mean that every referenced object should be copied as well. Imagine making a copy of a Satellite object where the satellite has a reference to two other objects: one representing its solar panels and the other representing the central body (or planet) that it is orbiting. When copying the satellite, you probably do want to copy its solar panels, but you don't want to copy Mars.
Worse, the choice of which sub-objects to copy and which to share sometimes depends on the intended use of the copy. In other words, the class implementor has no idea what to do. Only the caller of the Clone method knows just how deep the deep copy should be.
Dynamic Geometry Library (DGL) uses a novel (?) approach to object copying that solves both of the usual deep copying problems. I like to think of the pattern as 'copy ballast' because it allows the depth of a copy to be controlled by the user of the class rather than exclusively by its implementor. Even better, it does so without violating encapsulation.
Read on for more information about how this works.
Continue reading 'Copy Ballast: Deep copy or shallow copy? Let the user decide!'
Recent Comments