Search code examples
ooptell-dont-ask

Does "tell, don't ask" apply to user input validation?


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.


Solution

  • I agree with AviewAview, but would only throw exceptions if the user tells (not if he asks):

    public Foo
    {
      bool Validate(Baz bar)
      {
            if(!is_number(bar)) return false;
            return true;
      }
    
      AssignBar(Baz bar)
      {
            if (!Validate(bar)) throw numberexception();
      }
    }
    

    Tell:

    try
    {
      foo.AssignBar(bar);
    }
    catch(numberexception e)
    {
      alert('Not a number!');
    }
    

    Ask:

    if (foo.Validate(bar)
    {
      foo.AssignBar(bar);
    }
    else
    {
      alert('Not a number!');
    }
    

    So AssignBar expects a VALID bar and throws an exception if it is not, but we also provide a method to Validate which does not throw an exception.