Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Given a mutable property, it generally makes sense to only hold/store that property in a single place. When the data needs to change you only need to update a single field, and you can completely avoid bugs where the different fields get out of sync.

An extremely simple example could be:

The 'right' approach:

class Owner {
    String name;
}

class Dog {
    Owner owner;

    String getOwnersName() {
        return owner.name;
    }
}

The 'wrong' approach:

class Owner {
    String name;
}

class Dog {
    Owner owner;
    String ownerName;

    String getOwnersName() {
        return ownerName;
    }
}

Experience has taught me that it's very seldom a good idea to break this rule of thumb. The risk of bugs being introduced and the increased effort required to understand the code almost always outweighs any benefit.

My question is, is there a name for this rule/principle?

Bonus points for linking to articles/blogs/etc. which make the argument for this clearly. Double bonus points for counter-arguments!

share|improve this question
    
Are you referring to the Singleton Pattern? –  Mike Brown Jan 16 '13 at 14:44
1  
@MikeBrown Definitely not! –  Baqueta Jan 16 '13 at 15:27
    
@Baqueta are you talking about on-disk persistence, or in-memory run-time persistence? If you're talking about in the code's run-time, you are talking about global state (which is the singleton). Please explain how you aren't talking about global state? –  Jimmy Hoffa Jan 16 '13 at 15:32
    
@JimmyHoffa If there's a concept which covers both, then both. If you're going to make me pick, then in-memory. I'm not talking about global state though. There might be many values to store, but I only want to store each value once. –  Baqueta Jan 16 '13 at 15:40
    
@Baqueta Your description is the definition of the singleton pattern. –  Jimmy Hoffa Jan 16 '13 at 15:49

3 Answers 3

up vote 7 down vote accepted

It's called a Single Source of Truth. As far as counterarguments go, that article points out its main drawback, which is difficulty scaling. However, even in large distributed systems, you want to have a single source of truth locally.

share|improve this answer
    
No, Single Source of Truth is about a single API location for info when talking impersistent, but more commonly refers to data in persistence where it refers to normalization. He very specifically is referring to the singleton pattern here because he wants the element to exist only once in the whole application's memory space. –  Jimmy Hoffa Jan 16 '13 at 15:53
1  
The question was awkwardly worded, but he very specifically ruled out the singleton pattern. Taking from his example code, singleton would mean only one Owner instance in the entire system. He is talking about having as many Owners as needed, in non-global scopes, but that the owner name isn't redundant between the Owner and Dog classes. In other words, there is only a single owner name field in the system, even though there may be many Owner instances. That is SSOT, not singleton. –  Karl Bielefeldt Jan 16 '13 at 16:21
    
Yeah, his edit made clear he's referring to a single place in the data model not a single place in memory. My mistake. Can't remove my downvote, sorry, but you are right. –  Jimmy Hoffa Jan 16 '13 at 16:28
    
Sorry for the confusion. I don't post questions very often, so it sometimes takes me a couple of tries to make things clear. –  Baqueta Jan 17 '13 at 9:20

This is a facet of Don't repeat yourself, and arguably the single most important meta-principle of computer programming.

share|improve this answer

Database people call it Normalization. Good system designs tend to start with only normalized data and only make exceptions as needed.

One counter-example not mentioned in the Normalization article is concurrent programming. When two or more processes access the same piece of mutable data, there are all sorts of issues where process A starts a read, then process B performs a write, which value does process A read? The old one, or the new one? If your data is a complex object, A may get a pointer to a new, but uninitialized object and start using it before it is fully created.

When you have to share mutable data across processes, it is often better to make (immutable) defensive copies of your data. That way process A can fully guarantee that process B reads a correct, fully initialized value and that process B cannot then accidentally or intentionally change the value of A's data (or vice-versa).

This is the reason that Java has the convention of using those annoying get/set methods. If you expose a field with a get/set, then later discover an issue where a client of your class is changing your class's underlying behavior in an unsafe way, then without changing your class's interface you can:

  • Make the underlying data immutable
  • Return a defensive copy from the get() method
  • Add synchronization to the get/set methods

Immutable data is the simplest and most reliable solution when it's practical to design your class so that the data in it does not change. If the object has a small memory footprint and will not be created so many times as to fill memory with tiny copies of itself, then a defensive copy is probably more efficient than synchronization. If the underlying object is expensive to create, has a large memory footprint, or needs to be created so many times that it would fill memory quickly, then synchronization may be better than defensive copies.

Newer languages like Ruby and Scala generate implicit get/set methods for you so that it looks like you are accessing the fields directly, but you can later override the default get/set methods as described above. Functional languages like Scala, Clojure, or Haskell assume all data is immutable unless you specify otherwise.

Even within a single process it's very easy to pass myObject to different methods or use it on different pages of code within the same procedure and one place it sets myObject.color = BLUE and somewhere else it sets myObject.color = RED and each place expects myObject to retain its color. It's easy to make this kind of programming error whenever code becomes complicated enough.

share|improve this answer
    
+1 for the great write-up, even if most of it is somewhat tangential! –  Baqueta Jan 17 '13 at 9:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.