Does Object Oriented Programming Really Model The Real World? [closed]
also
“Firstly, A represents an object in the physical world, which is a strong argument for not splitting the class up.” I was, unfortunately, told this when I started programming. It took me years to realize that it’s a bunch of horse hockey. It’s a terrible reason to group things. I can’t articulate what are good reasons to group things (at least to my satisfaction), but that one is one you should discard right now. The end all, be all of “good code” is that it works right, is relatively easy to understand, and is relatively easy to change (i.e., changes don’t have weird side effects). – jpmc26 8 hours ago
“Firstly, A represents an object in the physical world, which is a strong argument for not splitting the class up.”
I disagree with this. For example, if I had a class that represents a car, I would definitely want to split it up, because I surely want a smaller class to represent the tires. – jpmc26 11 hours agosource
Until now, I considered the following a good design, because it emphasizes physical hierarchy among the objects. I would expect that to be easier to understand, than some abstractions e.g.class ViewManager
, class WheelsFascade
.
class Car
{
public:
void start() {assert(!m_fuel_tank.empty()); m_engine.start();};
private:
std::vector<Wheel> m_wheels;
Engine m_engine;
FuelTank m_fuel_tank;
}
Am I understanding correctly the above criticism that this is not a good design? If so, what are the actual problems? If not, what is being criticized?
5
It is impossible to answer the question of whether the code you present is a good design without a good understanding of what and who the code is for. Why, exactly, do you have such a class in your application? What are its clients? Who specified the behaviours that are implemented by it? How likely are those specifications to change in future? Which aspects of the specification are likely to change together, and which are likely to change at different times?
Real software rarely does something identical to a real world object, so breaking it up along similar divisions is not necessarily the best approach. Even if what we are doing is simulating a real system, it may be best to either merge components that are conceptually distinct in the real world into a single abstraction (perhaps because we don’t need to model the interactions between then, but only the end result of those interactions: your model has 4 separate wheel objects, but it may make more sense to consider two wheels and an axle as a single unit, for example) or split a single real component into multiple roles (because that component does multiple things and we need to model those in different ways: a car’s wheels steer the car and impart forwards motion, which we may decide is easier to handle separately than together).
What we can say with certainty is that the dogma that modelling objects should be based strictly on the division of components in real world objects is clearly wrong. We should split our code into objects for pragmatic reasons, rather than to conform to ideals that have no practical basis, which is what this suggestion appears to be.
1
Let’s say you had a software company where you wrote software for any and all things related to cars. Should you have one Car
object that is reused in all your software? Of course not:
- On a sales floor, a
Car
has retail and wholesale values. - To a mechanic, a
Car
consists of a bunch of replaceable parts. - To an engine computer, a
Car
consists of a bunch of sensors and controls. - To a navigation system, a
Car
is a little triangle with a position, heading, and velocity. - To a racetrack, a
Car
has a driver, a time, and a place (first place, second place, etc.)
Sometimes developers get stuck on the real-world definition, and inappropriately create one large object instead of splitting it up into appropriate contexts. This also happens with inheritance hierarchies, perhaps the most famous example being that a square is considered a special kind of rectangle in the real world, but a rectangle object is usually better modeled as a special kind of square object.
By all means, start by modeling your classes after real world objects. It’s a very reasonable default. Just don’t get stuck there and let it blind you to better alternatives.
To answer the question in the title, it is not acceptable to model real-world items with classes if those real-world items do not play a role in your problem domain.
To give an extreme example, it is not good to have a class House
when you are modelling a railway network.
The criticism in the question you linked to was that the asker stated (paraphrased): “Car
is a real-world object and therefore I shouldn’t divide it further”.
As you show in the question, real-world objects can be composed of other real-world objects, like a car has wheels, an engine and a fuel tank, and that composition can be reflected in the class design.
The first problem with trying to be true to the real world is that we don’t understand it completely. There are still plenty of open problems in physics. To solve a problem tied to the real world you must first pick a model of it, and any choice will be incomplete and to a certain extent inaccurate.
The second problem is that even if you did understand the real world, you don’t have the resources to simulate it.
The third problem is that in all likelihood you don’t actually want to. Let’s say you want to find out how long it’ll take for two cars to collide; do you really care about modeling every atomic interaction involved and getting an answer to an infinite level of precision? No; you’ll probably just treat both cars like points, use velocity and distance measurements that are only accurate to a handful of decimal places, and either disregard or use very simplified models of friction and wind resistance. And that’ll probably be accurate enough.
You say you like your design because it “emphasizes physical hierarchy among the objects”, but is a physical hierarchy even relevant to your problem? There are plenty of other relationships between real world entities that aren’t physical. If it is relevant, which physical hierarchy have you emphasized, is it accurate enough, and is it simple enough?