views:

125

answers:

5

I've just finished a six hour debugging session for a weird UI effect where I found that my favorite framework's implementation of an interface function called "getVisibleRegion" disabled some UI feature (and apparently forgot to restore it).

I've filed a bug with the framework, but this made me think about proper design: under what conditions is it legitimate to have any side-effects on an operation with a name that implies a mere calculation/getting operation?

For those interested in the actual details: I had a report on a bug where my plug-in kept breaking Eclipse's code folding so that the folding bar disappeared and it was impossible to "unfold" or see folded code . I traced it down to a call to getVisibleRegion() on an ITextViewer whose type represents a source code viewer. Now, ITextViewer's documentation does state that "Viewers implementing ITextViewerExtension5 may be forced to change the fractions of the input document that are shown, in order to fulfill this contract". The actual implementation, however, took this a little too liberally and just disabled projection (folding) permanently, never to bring it back.

+3  A: 

I would say None.

Tim
A: 

obj.getBusyDoingStuff()

Gwildore
+2  A: 

This may be such an edge case that it doesn't even qualify as a side effect, but if the result of the calculation is cached in the object, then that would be acceptable. Even so, it shouldn't make a difference to the caller.

Bill the Lizard
Or the side effect of get() may be reading the value from the database in the first place.
jalf
That's not really a side effect, since it doesn't change the state of anything. Unless you're talking about reading it from the database, then caching it in the object...
Bill the Lizard
+2  A: 

The biggest reason I can think of is caching results.

grepsedawk
Yea, I admit I do that too, though I'm generally careful to document it, and to make sure it's the only access route to values.
Uri
+1  A: 

I would say only if it's very obvious that the side effect will occur. Here is a quick example:

  MakeMyLifeEasyObject mmleo = new MakeMyLifeEasyObject(x, y, z, default, 12, something);

  Object uniqueObjectOne = mmleo.getNewUniqueObject();
  Object uniqueObjectTwo = mmleo.getNewUniqueObject();

  System.out.println(uniqueObjectOne.getId() == uniqueObjectTwo.getId()); // Prints "false"

Now in my theory here, the MakeMyLifeEasyObject has some internal counter (like a primary key on a DB table). There is a side effect of the get. I can also come up with the idea of something like this:

  Object thing = list.getNextObjectAndRemoveFromList();

That would make sense too.

Now the caveat of these is that in both cases, it's just better to rename the method.

The first one would probably be better as createNewUniqueObject(), while in the second a different name (in this case pop()) would be better.

When it's not some semi-contrived example like I gave above, I'd say the ONLY side effects that should be going on is creating/updating some cache if the value takes a long time to create or may be used quite a bit and needs to be sped up.

An example of this would be an object that holds a bunch of strings. You have a method, getThingToPrint() that needs to concatenate a bunch together. You could create a cache when that's called, and that would be a side effect. When you update one of the strings that things are based on, the set would invalidate the cache (or update it).

Something like what you described? Definatly sounds like a bug. I can't think of a situation where that would be a good idea. If that is an intended behavior and not a bug, then it should be renamed to something else (i.e. disableThingAndGetVisibleRegion()).

MBCook