I somehow must have overlooked the "tell, don't ask" OOP principle all these years because I just learned about it a couple days ago for the first time.
But the context was a discussion about validation code that had been moved out of an ASP.NET web form page and into a data/business object, and there was no "Validate()" method, just a save method that itself did validation and (supposedly) raised an exception. I asked why this was designed in this way and I was directed to OOP's "tell, don't ask" principle, which I'd never heard of, so then we looked together at Google and I was immediately educated. ;)
Still, something doesn't smell right, shouldn't data be scrubbed before it gets handed off away from the user and into the business layer where it is processed and/or collected, rather than the other way around? I'm confused as to how this makes for good design.
It seems like the rule of "tell, don't ask" pertains to the idea that you shouldn't ask the target object about the target object's state, and that the principle was never really meant to apply to the data being passed to the target object.
I thought it sounded like a load of "Best Practices" and "Design Methodologies" gone wrong, but now it kind of makes sense to me. Look at it this way:
Imagine putting validation in the Business Object, but the "what do I do if validation fails' in the presentation layer. This would allow multiple different presentation layers to reuse the same validation logic, but handle errors differently.
public Foo { Validate(Baz bar) { if(!is_number(bar)) throw numberexception(); } AssignBar(Baz bar) { Validate(bar); } } //... try { foo.AssignBar(bar); } catch(numberexception e) { alert('Not a number!'); }
n.b. you can argue all you want about throwing exceptions, it was meant as an example. Return states, bools, whatever you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With