|
I'm a little different on that: I prefer to do all validation at the top of the method and if it fails, exit immediately.
For example:
DateTime dob;
if (!DateTime.TryParse(tbDOB.Text, out dob))
{
... report problem to user ...
return;
}
double itemPrice;
if (!Double.TryParse(tbItemPrice.Text, out itemPrice))
{
... report problem to user ...
return;
}
... The alternative to this is to nest the ifs:
DateTime dob;
if (!DateTime.TryParse(tbDOB.Text, out dob))
{
... report problem to user ...
}
else
{
double itemPrice;
if (!Double.TryParse(tbItemPrice.Text, out itemPrice))
{
... report problem to user ...
}
else
{
...
}
} Which starts to get the "meat" of the function pushed out well to the right, which I don't like at all.
Once you are into the main function, then yes: single entry, single exit is preferable if possible.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Validation usually ends the function right there, I was speaking of the core of the function. In the end, for uniformity, I often change validation too to a single poit of exit - but once the code is something like
int function(...){
bool condition_ok = true;
int returnvalue = ERR_OK;
if (condition_ok) {
if (failed) then {
condition_ok = false;
returnvalue = errcode1;
}
}
if (condition_ok) {
if (failed) then {
condition_ok = false;
returnvalue = errcode2;
}
}
...
return returnvalue;
}
Then for uniformity it comes very easy to add validation also in this form. Functions like this are usually hardware initialization, connections, communications with retries and manual error corrections...
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
Surely validation would be in its own class rather than inside methods doing other things? Single responsibility and all that?
var validator = new MyValidator();
if (validator.Validate(objectToValidate).IsValid)
{
}
return;
Ah, I see you have the machine that goes ping. This is my favorite. You see we lease it back from the company we sold it to and that way it comes under the monthly current budget and not the capital account.
modified 31-Aug-21 21:01pm.
|
|
|
|
|
NO NO NO NO. Each method is responsible of validating its input data. Always.
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
So there are never cases when you'd want to do the same validation in more than one place?
[Edit] You might find life easier passing objects and using something like FluentValidation
Ah, I see you have the machine that goes ping. This is my favorite. You see we lease it back from the company we sold it to and that way it comes under the monthly current budget and not the capital account.
modified 31-Aug-21 21:01pm.
|
|
|
|
|
The same validation in different places calls for a function - or method, it's the same - of course, this is just plain old code reusability. But every function should validate its input parameters and the data it has access to before using them, unless extreme circumstances (i.e a hyper fast customized SIMD function).
And that carries over to checking pointers for non nullity before using them alongside the use of exceptions (where supported) and so on.
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
den2k88 wrote: every function should validate its input parameters and the data it has access to before using them
I agree with that, the question is what method you use to check them. If you're passing over one or two type parameters, then a null check is okay, but for anything other than that I'd pass an object and have a separate validator for that object type.
FluentValidation is a pretty good library for abstracting validation away from your methods. Your method should really focus on what it's supposed to be doing, not extraneous tasks.
Just my two cents anyway
Ah, I see you have the machine that goes ping. This is my favorite. You see we lease it back from the company we sold it to and that way it comes under the monthly current budget and not the capital account.
modified 31-Aug-21 21:01pm.
|
|
|
|
|
Brent Jenkins wrote: Your method should really focus on what it's supposed to be doing, not extraneous tasks. Checking if it's going to plunge to a horrible and toothy death is very well part of its responsibility. Adding classes on classes on classes for a couple of operations that strongly depend on what the method is about to do on data* is a good way to create OOP spaghetti code. Been there done that got the t-shirt and I'm still maintaining that frigging mess, whose debug caused me a lot of lost hair and temper.
* I may have a parameter that should be != 0 but to the current method it does not matter, or on the other hand each other method would accept a != 0 but he needs it to be strictly > threshold. Adding a validator class and method for its conditions only is overkill. Just check them and go on. Also it help to contextualize logging and debugging wherever reflection is not an option.
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
den2k88 wrote: I may have a parameter that should be != 0 but to the current method it does not matter, or on the other hand each other method would accept a != 0 but he needs it to be strictly > threshold.
Sounds like an inconsistent architecture to me, but whatever works for you is fine
Ah, I see you have the machine that goes ping. This is my favorite. You see we lease it back from the company we sold it to and that way it comes under the monthly current budget and not the capital account.
modified 31-Aug-21 21:01pm.
|
|
|
|
|
I skipped a detail, sorry: I'm mixing private methods with public ones. For public methods a validator or similar construct is the cleanest solution. What I said before, if applied to interface methods, would be inconsistent at best!
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
For me it comes down to how many times I'm writing the same code.
If it's more than once, then it should probably be in a method in a class of it's own unless it's complete unavoidable because of the limitations of the language/framework. To me, that's SOP for OOP code.
Ah, I see you have the machine that goes ping. This is my favorite. You see we lease it back from the company we sold it to and that way it comes under the monthly current budget and not the capital account.
modified 31-Aug-21 21:01pm.
|
|
|
|
|
Thanks for the link, Brent; looks like a valuable resource.
cheers, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
|
|
|
|
|
Just use lots of GOTOs, to go to the end of the function.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
Sometimes, when code gets too nested and adding a nest causes me pain, I actually consider that.
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
I do parameter validation at the top of a method and throw exceptions if necessary. After that, one exit to rule them all.
".45 ACP - because shooting twice is just silly" - JSOP, 2010
- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Ah that could be a solution but I can't throw exceptions in my code as we use Win32 APIs so we're stich with SEH and then we have a master controller in VB6, so return codes are the best solution, also most of the code is 10-15 years old written by a chemist turned programmer.
Also I came to respect the return-value based flow control as most of the times in the fields I work on is the most reasonable way to proceed. Of course on a strictly OOP environment exceptions make the rule!
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
|
My daughter bought a photo, taken by one of those critical-moment-snap-on-rollercoaster cameras, where everyone in the cars fore and aft is screaming, and I'm gazing off nonchalantly to my left as if nothing interesting is happening.
That's pretty much normal, for me. If there's no real danger, what is there to be afraid of?
My daughter is screaming in the picture, too. Must be her mother's bad genes.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
Mark_Wallace wrote: If there's no real danger, what is there to be afraid of? Someone with bad genes might puke all over you... That's my biggest concern in rollercoasters
|
|
|
|
|
OK, That I could be scared of!
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
Mark_Wallace wrote: If there's no real danger, what is there to be afraid of? I present to you, real danger[^].
The United States invariably does the right thing, after having exhausted every other alternative. -Winston Churchill
America is the only country that went from barbarism to decadence without civilization in between. -Oscar Wilde
Wow, even the French showed a little more spine than that before they got their sh*t pushed in.[^] -Colin Mullikin
|
|
|
|
|
Nah, taking a shower is riskier.
This[^], on the other hand...
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
A little while back I went to a theme park with she-who-must-be-obeyed. It was a little tame so we sauntered about. Stopped for lunch and then decided to do the rollercoaster.
Big, big, big mistake. I came off green: how I held my lunch down I have no idea. Moral of that tale: wait till after to eat!
Still, it was fun... until the after the first drop...
|
|
|
|
|
One funfair thing I did enjoy was a simple tower-thingy, that just shoots you straight up in the air, then drops you down again -- it's probably less than 1.5G on the way up, but it made me smile.
Nutter for linear acceleration, me.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
R. Giskard Reventlov wrote: or you come off and go green
I start going green before stepping on one of those contraptions invented by the devil.
Marc
|
|
|
|