I've seen this a lot, and is often made worse by attaching a load of unnecessary baggage/repurposing to classes.
For example, I've worked on PHP projects which, over time, have gained coding standards like:
- All classes should be in separate files, named to match the class name
- All classes should be built from a PHPSpec specification
- All classes should have their own test class
- No class can instantiate another, unless it's a "Manager" class which does only that. Everything else is dependency injected.
- Test classes can only instantiate their associated class; everything else must be mocked
And so on.
Now, each of these has its merits, but as each new practice was added, it increased the 'fear of adding classes', even if just subconsciously. Refactoring to break up classes became less and less common, since a simple code change would require:
- Whole new test classes (OK)
- New files (seems a bit like Java-envy, but OK)
- Injecting new instances wherever the old class was used (seems a bit overkill...)
- Mocking the behaviour of the first class in tests for the second, and vice versa (this is getting a bit silly...)
- Creating 'Manager' classes to instantiate the new classes (hmm...)
- Creating new test classes for these managers (erm...)
- Mocking the dependencies of the managers...
In the end, it was just far easier to just throw all new logic into existing classes, which grew and grew.
I've worked on a codebase where objects inherited from a class named "Abstract" which contained, apparently, methods used in more than one class, regardless of purpose.
Other fun anti-pattern: make a Facade class hiding services. Then:
- add logic directly in your facade
- make the services using the facade depend themselves on the facade (circular dependencies FTW)
This an excellent way of ensuring your code will NOT be reused.
I've seen this a lot, and is often made worse by attaching a load of unnecessary baggage/repurposing to classes.
For example, I've worked on PHP projects which, over time, have gained coding standards like:
- All classes should be in separate files, named to match the class name
- All classes should be built from a PHPSpec specification
- All classes should have their own test class
- No class can instantiate another, unless it's a "Manager" class which does only that. Everything else is dependency injected.
- Test classes can only instantiate their associated class; everything else must be mocked
And so on.
Now, each of these has its merits, but as each new practice was added, it increased the 'fear of adding classes', even if just subconsciously. Refactoring to break up classes became less and less common, since a simple code change would require:
- Whole new test classes (OK)
- New files (seems a bit like Java-envy, but OK)
- Injecting new instances wherever the old class was used (seems a bit overkill...)
- Mocking the behaviour of the first class in tests for the second, and vice versa (this is getting a bit silly...)
- Creating 'Manager' classes to instantiate the new classes (hmm...)
- Creating new test classes for these managers (erm...)
- Mocking the dependencies of the managers...
In the end, it was just far easier to just throw all new logic into existing classes, which grew and grew.