This is very important. You can't build software given only knowledge of a domain. You also need requirements.
The classic OOP educational example of `class Dog extends Pet` is a case in point. In what sense is a dog like a pet? The only way to know the answer to that is to look at it through the lens of our requirements. Are we building a vet appointment booking app, or a video game?
Educational examples can be misleading due to lacking real requirements, and lead programmers to reproduce oversimplified structures.
I wrote a more fleshed-out example of what I'm talking about on Reddit[1], but to save you the click through I'll reproduce it here:
[begin quote]
> [OOP] also make you have to think heavly about design, as you'll get yourself thinking about stupid things like "Does a buyer sell the goods, or does the customer buy the goods? What if we’re firing someone? Does a manager fire the person? Does the person fire themself? What if HR initiated the process, not the manager?"
This smells like very poor application of OOP. Let's take the firing example, it sounds like you're trying to design code like this:
employee1.fire(employee2);
But that's almost never what you want to do. Instead of designing classes that map to "things" like employees, it's likely your classes should be modelling business use cases like EmployeeTerminationProcess. To make up a bunch of stuff,
let process = EmployeeTerminationProcess.create({
initiator: employee1,
toBeFired: employee2,
}).begin();
// later,
if (process.hasEnoughDocumentationBeenProvided()) {
mailer.send(process.makeTerminationEmail());
}
// or maybe,
if (process.isComplete()) {
process.archiveAllMaterials();
}
`create` might even be a factory which returns instances of different specialised classes for different processes. Say if the documentation requirements are different when the process is initiated by a manager or by HR.
Trying to fit the colloquial English phrase "Bob was fired by Janet" directly into a line of code results in weirdness; instead of modelling English, you should be modelling the business process itself.
The problems you have with classes are common, and a result of crappy education and crappy existing codebases. It seems like industry and academia have gone through a wave of "let's model tangible objects as classes" which was never a good idea.
With any luck, the rise of functional programming will remind practitioners in OOP languages that abstractions are real (as David Deutsch described it) and that every tutorial containing class Dog extends Animal needs to be put in a bin.
That kind of thing is hideous and should be adopted only when the system is showing stress from the simpler, direct function-that-does-something approach.
On the other hand, fixing the messes left over by people with a penchant for overengineering keeps me rich. So have at it.
The classic OOP educational example of `class Dog extends Pet` is a case in point. In what sense is a dog like a pet? The only way to know the answer to that is to look at it through the lens of our requirements. Are we building a vet appointment booking app, or a video game?
Educational examples can be misleading due to lacking real requirements, and lead programmers to reproduce oversimplified structures.