In his book Domain Driven Design Eric Evans shows the value in keeping functions which are 'Side-Effect-Free' from commands which alter some state in the program. Prior to understanding this, it was common for me to have some method like so:
public double Total
{
get
{
this.total = property1 + property2;
return this.total;
}
}
As lame as this was, it worked :(
The problem with this was I was producing state changes to my objects when all I wanted was some calculated value based on their state. Changing my code to provide functions which simply performed the calculation without changing state helped me today with a new requirement that was slipped in.
The Subject Matter Expert (SME) decided to wait until a great deal of coding was done to bring up that different rounding rules should be applied to the calculations of certain objects to determine Pass/Fail status on their results. However, there are default rounding requirements that should still be used to present to the user...even though the specs are potentially considering a different value altogether.
Since the functions on my objects do this (waaaay simplified):
public double CalcTotal()
{
return property1 + property2;
}
I could safely consume my objects however the new specs required without worrying about any unintended side-effects on other members of the host object. This also avoided having forces which have nothing to do with my aggregate root from getting implicitly introduced; ie, introducing some kind of Calculation that rounds with different precisions. Keeping functions side-effect-free places the responsibility of the calculation's relevance on the client, not the target.
As basic as this is, strict adherence to this principle across many objects which perform complex calculations allowed me to slip in the solution to my SME's oversight in a matter of hours and with confidence that my objects are always in a valid state.
Posted
02-19-2008 2:58 PM
by
Michael Nichols