Let's say I have an object A with a public method bool Foo(arg). Foo is potentially a complex algorithm with nested rules (if's). I don't want Foo to have all the code, I want several intermediate functions to make my code more expressive but I face a dilemma.
Here is a simple example: Let's say Foo could be written:
public bool Foo(arg) {
if (arg.attr1) {
if (arg.attr2) return false;
else if (arg.attr3) return false;
}
return true;
}
However what is tested is more complexe and are in fact business rules. So a more expressive way to write the code is:
bool Rule1(arg) {
if (arg.attr1) return false;
return true;
}
bool Ruel2(arg) {
if (arg.attr2) return false;
return true;
}
bool Rule3(arg) {
if (arg.attr3) return false;
return true;
}
public bool Foo(arg) {
if (Rule1) return false;
if (Ruel2) return false;
if (Rule2) return false;
return true;
}
My dilemma is that rule 2 and 3 are only true after validation of rule 1. Since only Foo is public no client can misuse the individual rule functions however an other developer could get a new requirement and use rule 2 or 3 without first checking for rule 1. I could however test for rule 1 inside both rule 2 and 3 but it seems redundant.
Can I assume some properties in internal functions or should I still do the necessary checks in each functions?
Edit: Not a duplicate of How to tackle a 'branched' arrow head anti-pattern?. I have already tackle the arrow effect with early return. The question is more about the use of inner method for more expressiveness and what to test in each method.
Edit The two solution may not have equivalent result. I'm sorry about this but don't worry about this assume that it'll be the case in real life.
Rule# names will be more expressive in the end with proper business name (like IsBleu, IsAntique, ...)
if (arg.attr2) are overly simplified test. Real code can compare data in data base, dates, compare with global const values...
attr1
is true but neitherattr2
norattr3
are, then the first returnstrue
and the secondfalse
.Ruel2
doesn't exist andRule3
is never used