views:

141

answers:

4

I've been playing with functional programming lately and there are pretty good treatments on the topic of side effects, why they should be contained, etc. In projects where OOP is used, I'm looking for some resources which lay out some strategies for minimizing side effect and/or state.

A good example of this is the book RESTful Web Services which gives you strategies for minimizing state in a web application. What others exist?

Remember I'm not looking for another OOP analysts/design patterns book (though good encapsulation and loose coupling help avoid side effects) but rather a resource where the topic itself is state/side effects.

Some compiled answers

  • OOP programmers who mostly care about state do so because of concurrency, so read Java Concurrency in Practice. [exactly what I was looking for]
  • Use TDD to make side effects more visible [I like it, example: the bigger your setUps are, the more state you need in place to run your tests = good warning]
  • Command-query separation [Good stuff, prevents the side effect of changing a function argument which is generally confusing]
  • Methods do only one thing, perhaps use descriptive names if they change the state of their object so it's simple and clear.
  • Make objects immutable [I really like this]
  • Pass values as parameters, instead of storing them in member variables. [I don't link this; it clutters up function prototype and is actively discouraged by Clean Code and other books, though I do admit it helps the state issue]
  • Recompute values instead of storing and updating them [I also really like this; in the apps I work on performance is a minor concern]
  • Similarly, don't copy state around if you can avoid it. Make one object responsible for keeping it and let others access it there. [Basic OOP principle, good advice]
+2  A: 

I think the rules are quite simple: methods should only ever do one thing, and the intent should be communicated clearly in the method name.

Methods should either query or change data, but never both.

jkp
I remember that chapter in Clean Code.. good book
rcampbell
Heh, I've not read that one but I've read it elsewhere. It's frustrating when you see people not following the rule as things get so hard to understand and then they wonder why their code is not behaving as it should.
jkp
+3  A: 

I don't think you'll find a lot current material in the OO world on this topic, simply because OOP (and most imperative programming, for that matter) relies on state and side effects. Consider logging, for instance. It's pure side-effect, yet in any self-respecting J2EE app, it's everywhere. Hoare's original QuickSort relies on mutable state, since you have to swap values around a pivot, and yet it too is everywhere.

This is why many OO programmers have trouble wrapping their heads around functional programming paradigms. They try to reassign the value of "x," discover that it can't be done (at least not in the way it can in every other language they've worked in), and they throw up their hands and shout "This is impossible!" Eventually, if they're patient, they learn recursion and currying and how the map function replaces the need for loops, and they calm down. But the learning curve can be very steep for some.

The OO programmers these days who care most about avoiding state are those working on concurrency. The reasons for this are obvious -- mutable state and side effects cause huge headaches when you're trying to manage concurrency between threads. As a result, the best discussion I've seen in the OO world about avoiding state is Java Concurrency in Practice.

rtperson
+1  A: 

One way to isolate side-effects in OO is to let operations only return a description object of the side-effects to cause.

Command-query separation is a pattern that is close to this idea.

By practising TDD (or at least writing unit tests) one will typically be much more aware of side-effects and use them more sparingly, and also separate them from other side-effect free expressions that are easy to write data driven (expected, actual) unit-tests for.

Christian
+1  A: 

Some small things I do:

  • Prefer immutable state, it is relatively benign. E.g. in Java I make member variables final and set them in the constructor wherever possible.

  • Pass around values as parameters, instead of storing them in member variables.

  • Recompute values instead of storing and updating them, if that can be done cheaply enough. This helps to avoid inconsistent data by forgetting to update it.

  • Similarly, don't copy state around if you can avoid it. Make one object responsible for keeping it and let others access it there.

starblue
I like the suggestion of making objects immutable. I found this reference: http://www.javapractices.com/topic/TopicAction.do?Id=29
rcampbell