What are the best resources for learning how to avoid side effects and state in OOP?
Asked Answered
L

4

13

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]
Lanfranc answered 27/7, 2009 at 13:43 Comment(6)
I don't exactly understand what kind of side effects you mean and what you mean with state (in REST state belongs to the protocol, not the programming paradigm) in that context.Baluchi
"Avoiding" side effects and state is not really what you mean, I think.Primer
What do you mean by "state", exactly? The values of instance members of an object at any given point, plus the values of any static members of the object's class? Because that's a very important part of OOP, unless you intend to store all your data in global variables.Norsworthy
@Cat: for "state" I'm pretty sure the OP means "mutable state."Micro
@Primer - not sure what you mean. You can, for example, write a completely functional app in an OOP language without any state or side effects (see Clojure). In practice, some side effects ARE needed or you just have "a black box that just gets hot" so you instead try to clearly mark them when used. What are the strategies for "clearly marking them"/containing them/minimizing them in an OOD is my questionLanfranc
@Baluchi - exactly, so state has been minimized, though not removed. That's fine. So instead of having a Session carry state through multiple requests, state is minimized to individual requests. Result, less bugs since there are less combinations of state held for less time, easier to test, since each request is independent and I don't need some complex setUp() of state to run a test, and easier to maintain since each request is more loosely coupled. REST is a great example of the type of strategies I'm looking forLanfranc
M
7

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.

Micro answered 27/7, 2009 at 14:12 Comment(0)
D
5

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.

Dissepiment answered 27/7, 2009 at 13:48 Comment(1)
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.Dissepiment
R
4

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.

Revis answered 27/7, 2009 at 14:53 Comment(1)
I like the suggestion of making objects immutable. I found this reference: javapractices.com/topic/TopicAction.do?Id=29Lanfranc
C
3

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.

Covarrubias answered 27/7, 2009 at 14:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.