2

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 ago

source

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?

  • 1
    recommended reading: Discuss this ${blog} – gnat Jan 28 '15 at 8:39
  • 2
    But you did follow the criticism by breaking your Car class so that it became a composition of Wheel, Engine and FuelTank 😃 – alfasin Jan 28 '15 at 8:47
  • When doing so makes your program more complicated or less correct. – immibis Jan 28 '15 at 9:24
  • @gnat, but the Question I quote at the top is unrelated to the quoted discussion below. How can I improve my question? – Vorac Jan 28 '15 at 11:24
  • for a start, consider editing the question to explain why do you think this design good – gnat Jan 28 '15 at 12:11
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.

  • Thanks for the point of view! Btw here, Fig.1 they talk about some concept of collaborations, with different collaborations (use cases) exposing different aspects of an object. I hope I understand that some day. – Vorac Jan 28 '15 at 15:27
5

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.

3

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.

3

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?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.