OOT is a mini series on writing maintainable code without pulling your hair out. Object Oriented Functions have . At times they change the state of the system when you least expect them to and wreak all kinds of havoc. It’s difficult to get rid of all in an Object Oriented programming paradigm. We just need to make sure to manage them so that they don’t bite us when we aren’t looking. side-effects side-effects Managing Side Effects One of the good ways to manage is to create a strong separation between and queries. In this context, a changes the system, it has a side effect. A returns the value of a computation or the observable state of the system. side-effects commands command query Example When you call a function , you expect it to just return the amount and not change state of the system. It would be horrific if it did. Similarly, when you call , it will have and you expect it to change the state of the system. But what do you expect to return? Probably nothing. getAmount() setAmount() side-effects setAmount() Formal Definition Command Query Separation formalises this by saying: Functions that change state should not return values and functions that return values should not change state. This term was coined by Bertrand Meyer in his book . Object Oriented Software Construction Advantages One of the advantages of following this separation is that you can easily recognize whether or not a function has a side-effect. int m(); // queryvoid n(); // command Violation Take a look at the call below. Is it a command or a query? Clearly, it changes the state of the system. User u = UserService.login(username, password); What about the user object? Why was it returned? Are you supposed to manage it? Are you supposed to call logout on it at some point in the future? Shouldn’t it rather be a simple getter? User u = UserService.getUser(); Error Handling Maybe returned the so it could return when it failed? We are tempted to return error codes from a command if it fails to change state. But it’s better to throw an exception, maintaining the convention that commands return . login() User null void Gotchas Though CQS works well most of the times, there are exceptions. Popping a stack is an example of a function that modifies state and returns a result like a query. Element e = Stack<Element>.pop(); // stateful query Summary Commands return and queries return values. void Use exceptions rather than returning and checking for error states. As Martin Fowler said, it would be nice if the language itself would support this notion. The language could detect state changing methods, or at least allow the programmer to mark them. has made a handy tool to help you with this. Check it out . Anup Cowkur here What are your views? Let’s chat on . Twitter Read . trick #2 here If you liked this post, please hit the little heart! ❤ Originally posted on the AnDevCon . blog
Share Your Thoughts