Model Principle (MP)

Variants and Alternative Names

Context

Principle Statement

The object structure of the software should model and mirror those concepts and actions of the real world, that the software supports.

Description

The software should model and mirror the “real world”. This first of all means, that the structure of the software—to some extend—models the structure of the problem. When the “real world action” that the software should support comprises certain entities like e.g. customers, products, and orders, then there should be one object for each customer, product and order. Furthermore there should be one class for each concept. And if there is a certain relationship between customers, orders, and products, there should also be an association between the corresponding classes and references between the objects. So the object structure models the structure of the real world concepts.

Real world actions are then mirrored in the software system. This means that each action in the real world triggers a corresponding action in the model world which ensures that the model stays consistent with the real world. So the software is a kind of a simulation of what actually happens. If customer orders some product, the software reacts by creating an order object, which is connected to the customer and the product objects corresponding to the customer and the product involved in the real world action.

more detailed description

Rationale

When the structures in the software roughly correspond to the structures of the problem domain, a developer doesn't have to learn both of them. Knowing the problem domain is inevitably necessary. Any further structure of the software has to be learned and understood in addition. So creating a direct mapping between them, makes understanding the software easier, which improves maintainability. In such a system for most functionality there is a “natural”, i.e. an intuitively clear place to implement it. This makes structuring the software easier and helps finding the implementation for a given functionality.

Strategies

Create a class for each relevant real-world concept (“natural classes”)

For artificial behavior that cannot be mapped to a natural class at least create a metaphor or an artificial model (like for example a state machine)

Caveats

This principle may lead to the problem of modeling the real world in too great detail. This complicates the design without giving any further benefits. Especially a wrong understanding of inheritance may lead to taxomania, where an inheritance relation and the respective classes are only introduced because there seems to be such a taxonomy in the “real world”3). But inheritance should only be used on purpose, not just because it is possible. A special form of this problem is called vapor classes, which are useless abstractions which are never used4).

Origin

The root of this principle is the very beginning of object-orientation itself. The idea behind Simula, the first object-oriented programming language, was to view program executions as simulations. Kristen Nygaard, one of the creators of Simula defines object orientation as follows:

“Object-oriented programming. A program execution is regarded as a physical model, simulating the behavior of either a real or imaginary part of the world.”5).

Although this view is disputed as a definition for object-oriented programming, it became the key idea of object-oriented analysis. In 6) Grady Booch clearly states that objects “directly reflect our model of reality”.

Evidence

Accepted: Virtually every introduction to object-oriented analysis roughly explains this but mostly without stating it as a principle. Bertrand Meyer explains this principle in his book Object-Oriented Software Construction

Questioned: The value of this principle is disputed. It is questioned whether objects in the OOP sense nicely map to real-world objects7). Furthermore there is the typical object-relational impedance mismatch8) and the observation that business rules are sometimes cross-cutting9). There also is not one single obvious model for the “real world”. A model is subjective to the one creating the model. So it is not enough to model the “real world” but it is important to think about how to model it10).

Relations to Other Principles

Generalizations

Specializations

Contrary Principles

Encapsulate the Concept that Varies (ECV): Sometimes there are “concepts that vary” which are not directly related to a real-world concept. So ECV demands having an artificial class.

Keep It Simple Stupid (KISS): There are often simpler ways to build a software system than to model and mirror the real world behavior, which frequently means having more objects and more complicated structures.

Examples

Example 1: Object Structure (Library)

In a software system for a library, there will be a classes like Book, Reader, and Lending. A reader has a name, a book has a title and the reader must return the book after some date of expiry. So the corresponding classes will have attributes describing these properties. The reader may borrow and return a book, so the Reader class will have methods borrow() and return(). Classes, attributes, and methods are directly inferred from the problem domain.

Example 2: Swing

GUI frameworks like Java Swing typically have classes corresponding to the types of controls that can be used to build graphical user interfaces. So Swing for example has classes like JButton, JCheckBox, and JTextField.

Furthermore buttons, check boxes, text fields, and the like are also models of concepts in the real world. Buttons are typical controls of machines and check boxes and text fields are parts of a typical (paper-based) form. So the class JCheckBox is a model for a check box on the screen which itself is a model for a check box on a paper-based form.

Example 3: Dependencies

MP also tells which modules may depend on which others. Suppose we have a software comprising a parser for mathematical functions. Obviously there will be classes Parser and Function. MP tells that dependencies between these classes shall be according to the model. Logically a parser parses a string and creates Function objects. It is impossible to think about a Parser without Functions. So Parser may naturally depend on Function.

On the other hand our intuitive model of parsers and functions tells us that a Function does not need a Parser to be a meaningful entity. One can easily think of Functions created by using builder functions instead of a parser. And even if that wasn't true and there would only be the possibility to create functions by using parsers, a Function object logically can work without knowing that there are parsers which have created it. In an imaginary hierarchy of modules Parser would be a module on a higher scale than Function. So MP forbids that Function depends on Parser.