2

Most OO guides say not to store things in instance variables if they can be easily calculated, because the state might become inconsistent, and there is more code to maintain. I am trying to come up with a general guideline of how to decide this issue.

For example, if I have a simple object like Rectangle, I could store only the side lengths, or I could also store some easily calculated values like Area and Perimeter, which would be updated any time a side length was changed. The area and perimeter properties (accessors) would be read-only. In a second example, more complex computations such as employee Deductions based on pay might be made. Use Instance variables or calculate whenever needed? (In all cases I would not store calculated values in a database, so that is not related to this question... Unless you mean a Data Warehouse, which throws all the relational rules out the window anyhow.)

Is there an overall outlook on how this should be decided? Are there references that actually distinguish different answers, not just make a blanket recommendation? Thank you.

In in case it makes a difference I'm using C#.
Also, I am aware of DRY (don't repeat yourself - don't duplicate code), so I am asking about a situation where the calculation is one place in the code: either in the setter for the instance variable which defines it (Sides define the Area), or in a getter for Area itself, with Area not being stored. In both cases Area will not have a setter.

1
  • There can be a good reason for storing calculated values. If the calculation is relatively expensive and you can expect the value to be obtained often, it can improve performance if you calculate it only when the value is asked for and the object is "dirty". In most scenario's though this kind of performance will not be an issue. Jan 21, 2016 at 21:48

3 Answers 3

4

I would not store calculated values in a database, so that is not related to this question

Or is it?

The reason for not storing calculated values in your class is the same as the reason for not storing them in your database. It creates additional complexity where none is required. Essentially, it means that the same information is now being stored in multiple places, which requires that you keep that information updated manually in your logic.

Consider this:

public double Radius { get; set; }

public double Area
{
    get { return Math.PI * Radius * Radius; }
}

vs this:

private double _radius;
public double Radius
{
    get { return _radius; }
    set
    {
        _radius = value;
        _area = Math.PI * value * value;
    }
}

private double _area;
public double Area
{
    get { return _area; }
    set
    {
        _area = value;
        _radius = Math.Sqrt(value / Math.PI);
    }
}

Which is simpler and easier to maintain? Which carries less risk of bugs?

Any given element of information should exist in one place. As soon as you duplicate information, you assume the responsibility of keeping it synchronized. In most cases, that's a responsibility you don't want.

6
  • I would not allow the calculated values to be Set. So in your case, only the Radius could be set. If that is true, then it is the same amount of code to store the Area and calculate when the Radius changes as to calculate it every time it is requested.
    – user186205
    Jan 21, 2016 at 16:06
  • 2
    @nocomprende: It would still be a line or two of additional unnecessary code in that case. It's a very small example of the concept, of course. But it illustrates the point. You'd be storing the same value in multiple places. As the complexity of the system grows, the potential for bugs grows faster. Anybody working in that code needs to manually remember to keep all of the values synchronized, and humans aren't good at doing that. Exceptions can be made for very expensive calculations, but those are rare.
    – David
    Jan 21, 2016 at 16:09
  • This brings up the topic of immutability, which seems to my uneducated understanding to be either a contradiction, or a denial of what programming is all about. If nothing changes, why are we bothering to use a computer at all? Shooting fish in a barrel does not require any skills.
    – user186205
    Feb 4, 2016 at 18:35
  • @nocomprende: I'm not sure how you leapt from "don't repeat information" to "don't use a computer at all"... I'm simply suggesting that one maintains a single source of truth in any given context for any given piece of information. The proposed alternative, manually keeping different sources of truth synchronized, is highly error-prone and overly-complex.
    – David
    Feb 4, 2016 at 18:40
  • I didn't leap, I followed the bridge of immutability. If nothing in a program changes, then the source of truth is before it began executing. So the answer is there, in the initial conditions. I said I probably don't understand it. But if I do... You need not take me seriously.
    – user186205
    Feb 4, 2016 at 18:49
1

Actually there is no point in storing something/somevalue which can be computed/calculated at any time with the available information. These are called computed values. Example: Age, have you seen someone storing values for age in database table (say student).

NO, cause that can be calculated at anytime from the available values of DOB and current datetime. Per database concept these are known as Computed columns.

3
  • It very much depends on the business context. For instance "Age at time of order" may be relevant for age-dependent products; you could back-calculate the persons age using their DOB and the Order Date but such a system is fragile and requires the programmer/database to retain information such as a past customers DOB well beyond the need to retain it, and this may have problems with data protection legislation in various countries. Additionally a calculated field might not be able to be indexed by various RDBMS/BLOB databases, so again there are valid reasons for storing it.
    – PhillipH
    Jan 21, 2016 at 16:03
  • @PhillipH, Nope, DOB is a basic PI information and as you said order date and other dates will be maintained for analytical/history maintaining purposes and age at of time order can be calculated easily from there. In general, information like Age are never stored rather computed while fetching the data say for display/report purpose. At least, till date I haven't seen anyone storing such information. Moreover, my answer is generic and not re-strain itself to c# or so ...
    – Rahul
    Jan 21, 2016 at 16:07
  • When you said, "Actually there is no point in storing something / some value which can be computed / calculated at any time with the available information." I was thinking: OK, so we store the initial conditions of the Universe, then just recalculate every time something happens... ha ha. I still struggle with the idea that something like a bank balance is never stored. If I have years of history and thousands of transactions, does it make sense to recompute the balance every time from the beginning? Doesn't it reconcile at some point and we go forward from there? Like a "restore point"?
    – user186205
    Feb 4, 2016 at 18:29
1

Clearly not something for which there is a definite answer, but as a guide I suggest;

1) Don't store things which can be calculated.

2) Don't calculate things whose value in the past must be known in the future (i.e. balances).

3) Don't add calculations until you have a need for them - the programmer can always add extension methods.

4) If your calculation requires coupling to another class, don't calculate it but store it, otherwise you built up excessive dependency.

1
  • I am fuzzy on the meaning of "don't calculate it but store it."
    – user186205
    Feb 4, 2016 at 18:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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