3

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.

4
  • 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 ) Commented Nov 15, 2010 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
    Commented Nov 16, 2010 at 4:19
  • Just need to ask: Are Foo and Bar methods or classes? I'm not very familiar with C#.
    – gablin
    Commented Nov 16, 2010 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
    Commented Nov 17, 2010 at 15:34

5 Answers 5

11

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.

1
  • 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
    Commented Jan 1, 2012 at 22:31
3

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.

4
  • 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. Commented Nov 15, 2010 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.. Commented Nov 15, 2010 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). Commented Nov 20, 2010 at 15:24
  • Area should really be returned from a method then.
    – user3792
    Commented Oct 19, 2011 at 17:39
2

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).

1

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.

0

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.

2
  • 2
    "... should be one of a few constants." So no, it's not a constant that is changed.
    – Anthony
    Commented Nov 16, 2010 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. Commented Jun 6, 2011 at 16:08

Your Answer

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

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