Suppose I've the following classes in my project:
- class Is // validation class
- class Math // number manipulation class
Now, if I want to validate a given number for primality where would be the logical place to insert my Prime() method? I can think of the following options:
- Is_Math::Prime()
- Math_Is::Prime()
I hate these ambiguities, the slow down my thinking process and often induce me in errors. Some more examples:
- Is::Image() or Image::Is() ?
- Is_Image::PNG() or Image_Is::PNG() ?
- Is_i18n_US::ZipCode() or i18n_Is_US::ZipCode() or i18n_US_Is::ZipCode() ?
In the Image example the first choice makes more sense to me while in the i18n example I prefer the last one. Not having a standard makes me feel like the whole code base is messy.
Is there a holy grail solution for organizing classes? Maybe a different paradigm?
I don't think it's ambiguous at all. "Is" should be first in every one of those examples, and I'll tell you why: "Is" is the superset of validation operations in which Is::Math is a member.
In the case of Is::Math, what are you doing? Are you doing math operations? Or are you validating mathematical entities? The latter, obviously, otherwise it'd just be "Math".
Which of those two operations has the greater scope? Is? Or Math? Is, obviously, because Is is conceptually applicable to many non-Math entities, whereas Math is Math specific. (Likewise in the case of Math::Factor, it wouldn't be Factor::Math, because Math is the superset in which Factor belongs.)
The whole purpose of this type of OOPing is to group things in a manner that makes sense. Validation functions, even when they apply to wildly different types of entities (Prime numbers vs. PNG images) have more similarities to each other than they do to the things they are comparing. They will return the same types of data, they are called in the same kind of situations.