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.

I'll use C# as an example, but it should apply globally. Say I have a string value that should be one of a few constants, but I also want the client to set which string value to use so:

private int foo;
private string bar;

public int Foo {
    get { return foo; }
    set
    {
        foo = value;
        bar = getStringValueFromDatabase(value);
    }
}

public string Bar { get { return bar; } }

I use this technique quite a lot and want to know if it's considered as any formal concept.

share|improve this question
3  
I'll also throw out there that accessing the database in that location (property setter), is almost certainly violating all sorts of guiding principles (may I recommend SOLID if you are not already familiar with it: en.wikipedia.org/wiki/Solid_%28object-oriented_design%29 ) –  qes Nov 15 '10 at 23:25
    
In reply to comments about getting the string from the database directly: it's not really what I was getting at. I just wanted to show that the bar is not set by the client but is instead set as a result of setting foo. –  anthony-arnold Nov 16 '10 at 4:19
    
Just need to ask: Are Foo and Bar methods or classes? I'm not very familiar with C#. –  gablin Nov 16 '10 at 12:19
    
It's the access methods (get/set) for the class fields(variables). C# has a special syntax for creating get/set methods. –  Michael K Nov 17 '10 at 15:34
add comment

5 Answers

up vote 11 down vote accepted

It's perfectly valid OO technique, though I think it can be made a bit more efficient if the lazy-loading (which is what this effectively is) is deferred until the Bar value is actually needed.

private int foo;
private string bar;

public int Foo 
{
    get { return foo; }
    set
    {
        foo = value;
        bar = null;
    }
}

public string Bar
{ 
    get 
    { 
        if(bar == null) 
            bar = getStringValueFromDatabase(Foo);
        return bar; 
    } 
}

Edit: I think that's an improvement on the original code though as others have observed, even better would be to abstract the data access into a separate layer.

share|improve this answer
    
This structure will not case an error like the original questions code if bar is requested before foo, which could happen at some stage in the future. So this is a better way to structure the program. –  adam f Jan 1 '12 at 22:31
add comment

The concept that I think of is something similar to a database foreign key, an association between two entities where one entity refers to the other through a handle (the key). More generally, you can call it an indirect association.

There are two time dependent aspects to this:

  1. Setting the handle, thus creating the association
  2. Retrieving the associated entity through that handle

There're many ways to code this, with eager or lazy loading, by fetching the related entity every time it's requested, by using a proxy, with or without temporal coupling, and also whose responsibility it is to carry out the two aspects above (could be the referring entity or the client code), which could potentially turn it into a direct association from the referring entity to the referred-to entity (the indirection would only be know to the client code).

share|improve this answer
add comment

If possible, it's safer to pass foo in the constructor, and make it readonly/final. Then you've created an object with dependencies. when you call the Bar getter, then use the captured state to compute the value if you want to do it lazily.

share|improve this answer
add comment

Say I have a string value that should be one of a few constants, but I also want the client to set which string value to use so:

  1. A constant that is changed? Eh?

  2. What you're doing is changing a property which is backed by a data store. It's not a constant. It might be a configuration variable.

  3. The Patterns name might be Facade or Decorator or somesuch similar. If my code works, and is maintainable, I don't bother myself with the pattern names.

My comment on your code is you should have another layer of indirection - a function that manages the data storage/restoration. That will abstract it away from the database call.

share|improve this answer
2  
"... should be one of a few constants." So no, it's not a constant that is changed. –  anthony-arnold Nov 16 '10 at 4:48
    
It is obvious the OP meant that the value being set is one of a set of enumerated values. It could be a string value from a set of strings, or an enum value from an enum, it makes no difference. The OP also clarified that he was not interested in the way bar is actually set, but rather in the fact that it is set as a result of setting foo. –  Umar Farooq Khawaja Jun 6 '11 at 16:08
add comment

Well, it is similar in a way to Lazy Loading, but it's not exactly that. At first glance, it actually seems a tad dangerous, in that setting a property has side effects. I believe that's generally frowned upon, but this is hardly an egregious violation.

share|improve this answer
1  
I think if the getter modified state, that's a problem with side effects. You expect the state of an object to change when you call a setter. If I set the Width property of a rectangle, I'd expect the Area property to change. –  Scott Whitlock Nov 15 '10 at 23:37
    
It would definitely be an issue if a getter modified state. As for a setter, I guess I think unless it's very obvious that one property is the result of another, like your example with Rectangle, that changing other properties in a setter is likely a poor choice. Obviousness/discoverability/etc.. –  qes Nov 15 '10 at 23:46
    
Indeed. Visual Studio actually requires getters to be side-effect free, since it may actually call them at quasi-random times (for example when using the watch window while debugging). –  Jörg W Mittag Nov 20 '10 at 15:24
    
Area should really be returned from a method then. –  Morgan Herlocker Oct 19 '11 at 17:39
add comment

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.