User Tools

Site Tools


principles:model_principle

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
principles:model_principle [2021-09-02 12:34] – old revision restored (2021-05-19 11:19) 65.21.179.175principles:model_principle [2021-09-02 12:34] – old revision restored (2021-05-11 22:08) 65.21.179.175
Line 3: Line 3:
 ===== Variants and Alternative Names ===== ===== Variants and Alternative Names =====
  
-  * Direct Mapping(({{page>resources:Object-Oriented Software Construction#reference}})) +  * Direct Mapping((Bertrand Meyer//[[http://en.wikipedia.org/wiki/Object-Oriented%20Software%20Construction|Object-Oriented Software Construction]]//)) 
-  * Low Representational Gap (LRG)((Craig Larman: //[[resources:Applying UML and Patterns]]//, p 281)) +  * Low Representational Gap (LRG)((Craig Larman: //Applying UML and Patterns – An Introduction to Object-Oriented Analysis and Design and Iterative Development//, p 281))
 ===== Context ===== ===== Context =====
 /* fill in contexts here: */ /* fill in contexts here: */
Line 25: Line 24:
 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. 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.
  
-Be precise with semantics. An operation ''cancelOrder()'' should get an ''Order'' or ''OrderId'' as a parameter. In some cases you might be inclined to supply a ''Product'' instead, maybe because you already have a variable with that object at hand. This might work totally fine in the concrete situation but in fact it only works "by accident". Similarly you might be inclined to invoke ''cancelOrder()'' in a situation when you want to delete the order from the repository. This might work as expected but actually ''cancelOrder'' is semantically slightly different from ''deleteOrder''. So even if ''cancelOrder'' currently does nothing but to call ''deleteOrder'' you should call the method on the correct abstraction level that has precisely the right semantics.+FIXME more detailed description
  
-Keep sure that your software models the reality by invoking the method that has the correct semantics and supplying it with the parameters that are needed from a requirements perspective. 
  
 ===== Rationale ===== ===== Rationale =====
Line 33: Line 31:
 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. 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.
  
-Moreover if something works accidentally, it breaks accidentally. In the example above supplying a ''Product'' to the ''cancelOrder'' method only works because by some circumstance it is made sure that  when ''cancelOrder'' is called, there is only one order for that particular product. It's a hidden precondition. As the software is changed, this hidden precondition may not be guaranteed anymore. This results in a non-obvious bug in a part of the system you haven't directly touched. Similarly in the ''deleteOrder'' example: The ''cancelOrder'' operation might get enhanced by creating a reverse invoice, a credit note, or a message to the customer. But an order might have to be deleted for purely technical reasons (migration to a new order system, etc.). So if you call ''cancelOrder'' instead of ''deleteOrder'' this will produce nasty bugs if ''cancelOrder'' gets enhanced as described.+
 ===== Strategies ===== ===== Strategies =====
  
Line 39: Line 37:
   * Create methods corresponding to real-world actions   * Create methods corresponding to real-world actions
   * Map additionally necessary behavior to natural classes instead of creating artificial classes   * Map additionally necessary behavior to natural classes instead of creating artificial classes
-  * For artificial behavior that cannot be mapped to a natural class at least create a metaphor or an artificial model (like a state machine) +  * 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) 
-  * Be precise with semantics. If you have an operation that currently does what you need but for slightly different reasons because it's an operation on the wrong abstraction level, create a new operation with the correct semantics. Have that new operation call the existing one as an implementation detail (e.g. have a ''cancelOrder'' method call the ''deleteOrder'' method).+
  
 ===== Caveats ===== ===== 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 [[anti-patterns:taxomania]], where an inheritance relation and the respective classes are only introduced because there seems to be such a taxonomy in the "real world"(({{page>resources:Object-Oriented Software Construction#reference}})). But inheritance should only be used on purpose, not just because it is possible. A special form of this problem is called [[anti-patterns:vapor classes]], which are useless abstractions which are never used((Robert C. Martin: //[[http://www.objectmentor.com/resources/articles/CoffeeMaker.pdf|Heuristics and Coffee]]//)).+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 [[anti-patterns:taxomania]], where an inheritance relation and the respective classes are only introduced because there seems to be such a taxonomy in the "real world"((Bertrand Meyer//[[http://en.wikipedia.org/wiki/Object-Oriented%20Software%20Construction|Object-Oriented Software Construction]]//)). But inheritance should only be used on purpose, not just because it is possible. A special form of this problem is called [[anti-patterns:vapor classes]], which are useless abstractions which are never used((Robert C. Martin: //[[http://www.objectmentor.com/resources/articles/CoffeeMaker.pdf|Heuristics and Coffee]]//)).
  
 See also section [[#contrary principles]]. See also section [[#contrary principles]].
Line 54: Line 52:
 > "**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."((see for example Ole Lehrmann Madsen, Birger Møller-Pedersen and Kristen Nygaard: //[[ftp://ftp.daimi.au.dk/pub/beta/betabook/betabook.pdf|Object-Oriented Programming in the BETA Programming Language]]//)). > "**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."((see for example Ole Lehrmann Madsen, Birger Møller-Pedersen and Kristen Nygaard: //[[ftp://ftp.daimi.au.dk/pub/beta/betabook/betabook.pdf|Object-Oriented Programming in the BETA Programming Language]]//)).
  
-Although this view is disputed as a definition for object-oriented programming, it became the key idea of object-oriented analysis. In ((Grady Booch: //[[resources:Object-Oriented Design with Applications]]//, p. 191)) Grady Booch clearly states that objects "directly reflect our model of reality".+Although this view is disputed as a definition for object-oriented programming, it became the key idea of object-oriented analysis. In ((Grady Booch: //Object Oriented Design with Applications//, p. 191)) Grady Booch clearly states that objects "directly reflect our model of reality".
  
 ===== Evidence ===== ===== Evidence =====
Line 62: Line 60:
  
   * [[wiki: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//   * [[wiki: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//
-  * [[wiki:Questioned]]: The value of this principle is disputed. It is questioned whether objects in the OOP sense nicely map to real-world objects((Lambda the Ultimate: //[[http://lambda-the-ultimate.org/node/3265|Why are objects so unintuitive?]]//, B. Jacobs: //[[http://www.geocities.com/tablizer/model.htm|OOP and "Modeling the Real World"]]//)). Furthermore there is the typical object-relational impedance mismatch((FIXME cite)) and the observation that business rules are sometimes cross-cutting(([[wiki>OopNotForDomainModeling]])). 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 it((Bertrand Meyer: //[[resources:Object-Oriented Software Construction]]//, p.694)).+  * [[wiki:Questioned]]: The value of this principle is disputed. It is questioned whether objects in the OOP sense nicely map to real-world objects((Lambda the Ultimate: //[[http://lambda-the-ultimate.org/node/3265|Why are objects so unintuitive?]]//, B. Jacobs: //[[http://www.geocities.com/tablizer/model.htm|OOP and "Modeling the Real World"]]//)). Furthermore there is the typical object-relational impedance mismatch((FIXME cite)) and the observation that business rules are sometimes cross-cutting(([[wiki>OopNotForDomainModeling]])). 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 it((Bertrand Meyer: //[[http://en.wikipedia.org/wiki/Object-Oriented%20Software%20Construction|Object-Oriented Software Construction]]//, p.694)).
  
  
Line 84: Line 82:
   * **[[Tell, don't Ask/Information Expert]] (TdA/IE)**: TdA/IE tells how to distribute functionality among the natural classes which are created according to the Model Principle.   * **[[Tell, don't Ask/Information Expert]] (TdA/IE)**: TdA/IE tells how to distribute functionality among the natural classes which are created according to the Model Principle.
   * [[Low Coupling]] (LC): When designing a model for a software, it has to be borne in mind that structures with low coupling are desirable.   * [[Low Coupling]] (LC): When designing a model for a software, it has to be borne in mind that structures with low coupling are desirable.
-  * [[Law of Leaky Abstractions]] (LLA): When building abstractions according to MP, keep in mind that there will most likely be abstraction leaks. A good abstraction minimizes those leaks.+
  
 ==== Principle Collections ==== ==== Principle Collections ====
Line 129: Line 127:
   * [[http://martinfowler.com/articles/dblogic.html|Martin Fowler: Domain Logic and SQL]] (other possible to implement a system and their difference to domain models)   * [[http://martinfowler.com/articles/dblogic.html|Martin Fowler: Domain Logic and SQL]] (other possible to implement a system and their difference to domain models)
  
-===== Discussion ===== 
- 
-Discuss this wiki article and the principle on the corresponding [[talk:principles:Model Principle|talk page]]. 
principles/model_principle.txt · Last modified: 2021-10-18 21:47 by christian