In reality we are never designing classes for a bookstore, shapes, or animals. Often times the problem is new and the classes go through an iterative lifecycle of design/refactor.
Book authors should spend more time thinking about examples. I see this in almost every oo book.
> In reality we are never designing classes for a bookstore, shapes, or a animals.
This 100x. Anyone who has tried to solve real world problems finds out a very small amount of code written fits the model where a class corresponds to a family of physical objects, and probably much less even fits the model of polymorphism.
95% of classes end up just being fairly random containers for data and behaviour and OO just does not offer anything of value.
That's OK. As long as you're constantly refactoring.
If you step back and look at how you're manipulating your data and you're like, "Ok, data comes in and I first turn it right, then I turn it left, then I flip it over... Ah! I might be able to use Pipes and Filters here!" You can then refactor your classes to be more organized.
OOP should be thought of as a way to structure your code, not as a way to model the problem domain. When used properly, it can give pretty good results, yet introductions to OO usually start with objects/classes representing real-world entities.
OOP is an abstraction tool. When you have a problem you need to divide it into sub problems and represent each sub problem as an abstraction. The end result is that the collection of abstractions should model the problem domain.
> The end result is that the collection of abstractions should model the problem domain.
Sure, but that doesn't imply that individual objects/classes should model individual abstractions 1-to-1, as would be the case for the typical Vehicle, Car, Boat example classes.
Are you refering to simulations of physical phenomena? If so, then I disagree: You'll fare much better with large arrays of dumb structs, which enable immense performance improvements on today's computing architectures.
If you need to incorporate flexibility in the environment, with agents displaying lots of different behaviors (such as with video games), the large arrays of dumb structs will be much harder to organize.
I agree that those structures are easier to make efficient, but for handling the hierarchy of different types of objects with different but related behaviors, you'll basically have to reimplement a limited form of object-orientation and message passing.
Did you look at the linked book? The first two examples are of a coffee product and a GPS location. Of course real-world code often is bigger than textbook examples, but this complaint is hardly applicable here.
Is there a functional-programming-first curriculum? Even though knowing OOP is important (if even just for the vocabulary), I wonder if a lot of pain could be sidestepped by talking about data as a separate concern than ADTs, and state as a fact rather than a place. [1]
I find that it helps me to think of objects as tiny machines rather than places to hold data.
It then becomes easier to reason about which classes make sense and which don't. A "User" class doesn't make sense, but UserTable (machine to access the users) and Authenticator (machine to authenticate them) do. A BlogPost class doesn't make sense, but a PostRenderer (machine to render blog posts) does.
OOP then becomes about decomposing computers into smaller communicating computers, not about lumping together data and all the possible code related to that data. Which incidentally means that there will be things that are pretty much just dumb data / facts (e.g. User)
I highly recommend the Domain Driven Design approach.
But I've found it a lot harder to comprehend and make others give it a try (probably orders of magnitude harder than object oriented design or design patterns or normal refactorings).
I like to think about designing classes and aranging them in packets/modules/applications more like creating birocratic systems.
You have to think in general terms what an institution/building does, what is its core activity, what it is authoritative over, then you design each room/department with its own mini-authority, make sure there is no duplication of authority/data between rooms, make sure each person inside a room does/knows about only the stuff in that room so they can really perform by being specialized and not commuting between rooms with their arms full of customer/citizen's files.
Make sure, as much as possible that each room knows about adjacent rooms only (or maybe at least at the same floor).
At the same time you have to think how the regular citizens use these institutions and what interfaces you provide them with to solve their requests.
You don't want a taxpayer modifying his own tax file, you probably want a clerk to do that; you also don't want a taxpayer visiting 100 rooms to submit his tax files.
Then you have to think about how many customers you would serve, how wide the coridors should be made, what kind of security you need at the entrance and so on.
Yes, there are many books that start with functional programming. If I remember correctly.
"Concepts, Techniques, and Models of Computer Programming" start with pure functional program, and define objects as function with state. An other one is "Essentials of programming languages". Also Pierce's "Types and Programming languages"....
This book is designed to be taught in the second course of a CS curriculum, after students take a functional-first course based on How To Design Programs.
Book authors should spend more time thinking about examples. I see this in almost every oo book.