Regarding your second paragraph, you're going to find that you'll need to go into checkSeats() anyway upon input, as your data could have changed. Other users could have reserved or cancelled, and that could change your total number of available contiguous seats by the time any other user finalizes his or her selection. Certainly, running some checks up front to limit the inputs can be of value, but it doesn't absolve you of the need to check afterwards.
In more general terms of your first paragraph, I view it like this: if you have a public method, that method should verify (or delegate the task of verifying) the inputs for logical correctness. I don't care if another public method elsewhere has validated those same inputs -- by nature of the method being public, anybody can call it, so you can't guarantee input vectors. The last thing you want is your code to blow up because you didn't take a moment to validate against a null or a negative number or some other invalid argument. Your private methods should then not need to worry about validation (unless, of course, validation is their job) (this is assuming your code is well designed and that you trust
yourself to give
yourself good values -- and by "yourself," I really mean the class, not the author of it).
At the same time, if you're calling into a public method and you haven't already validated the inputs you're using (such as, you got them from a user or even a database), then validate before even calling. Look at it as if you're consuming a library, ignoring for a moment that you might have been the author of it. If you know that the library could potentially bomb because of what you pass it, you want to validate what you're passing. The last thing you want is for your program to fail unexpectedly, and quite often a source of failure is invalid data.
It might sound as if I'm saying have validation code all over the place, repeatedly, and I'm really not. If your program is well designed, your validation will be isolated. I simply advocate that the code being consumed validate arguments before working with them, and the consuming code validate parameters before sending them, particularly when the source of those parameters can't be trusted (as in, the data came from an external source).
In code terms, if you have a method that looks like (examples provided in C#/.NET):
Code:
public int Divide(int numerator, int denominator)
{
if (denominator == 0) throw new ArgumentException("Denominator cannot be 0.");
return numerator / denominator;
}
This is public method that will blow up with a particular input. If you're consuming that method, you do not want to provide that input! So you validate beforehand
Code:
int numerator = GetNumeratorFromSomewhere();
int denominator = GetDenominatorFromSomewhere();
int quotient;
if (denominator > 0)
{
quotient = someObject.Divide(numerator, denominator);
}
This is what I mean by validation on both sides. You don't want to accept bad arguments, but you also want to be good citizen and not send them.