User Tools

Site Tools


principles:principle_of_separate_understandability

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:principle_of_separate_understandability [2013-02-12 12:29] – example 2 christianprinciples:principle_of_separate_understandability [2021-09-02 20:44] – old revision restored (2021-05-19 09:48) 65.21.179.175
Line 10: Line 10:
  
 ===== Principle Statement ===== ===== Principle Statement =====
- 
-Each module shall be understandable on its own -- without knowing anything about other modules. 
  
  
 ===== Description ===== ===== Description =====
- 
-PSU means that: 
-  * By looking at the public methods of a class it should be clear why they are there. That means there should be no method that is only there because a specific other module needs it. 
-  * By looking at the implementation of a module it should be clear how it works and why it was done that way. That means there should be no code that is solely there in order to make another module work. 
-  * By looking at a private method it should be clear what it does. That means there should be no (private) method that is only meaningful in the context of another method. 
  
  
 ===== Rationale ===== ===== Rationale =====
- 
-When a module is separately understandable, it is easier to maintain, as no other modules have to be considered during maintenance. It is furthermore more testable, as a unit test can easily test only this particular module without requiring integration with other modules. 
- 
-Another point of view is that a violation of PSU either means that a part of the functionality does not belong to that module or the module has the wrong abstraction. So this is a sign of a design that needs improvement. 
  
  
 ===== Strategies ===== ===== Strategies =====
  
-When a module does not comply with PSU, this means that either a part of the functionality of the module does not belong here or the module has the wrong abstraction. So strategies for making a solution more compliant with PSU are: 
- 
-  * Move the conflicting functionality to another module where it fits better (see [[Tell don't Ask/Information Expert|IE]]). 
-  * Build up a new module for the conflicting functionality (see [[High Cohesion|HC]]). 
-  * Find the right abstraction for the module that allows the functionality to stay here (see [[Model Principle|MP]]). 
  
 ===== Origin ===== ===== Origin =====
- 
-This principle is newly proposed in this wiki. Nevertheless it is believed that it is not "new" in the sense that its a new insight. Its rather something that is commonly known but hasn't been expressed as a principle, yet. 
  
  
 ===== Evidence ===== ===== Evidence =====
 /* Comment out what is not applicable and explain the rest: */ /* Comment out what is not applicable and explain the rest: */
-  * [[wiki:Proposed]] (see origin) 
- 
 /* /*
 +  * [[wiki:Proposed]]
   * [[wiki:Examined]]   * [[wiki:Examined]]
   * [[wiki:Accepted]]   * [[wiki:Accepted]]
Line 75: Line 56:
 ===== Example ===== ===== Example =====
  
-==== Example 1: Parsing Data ==== 
- 
-Suppose a program parses data stored in an spreadsheet file. There are three classes: 
-  * ''SpreadsheetReader'': This reads the spreadsheet and creates ''DomainObject'' objects. 
-  * ''DomainObject'': This is the data which was contained in the spreadsheet and is now processed by the program in some way. 
-  * ''SpreadsheetWriter'': This class takes a ''DomainObject'' and writes it back to the spreadsheet. 
- 
-In such a scenario it might be convenient to simplify ''SpreadsheetWriter'' by adding information about the spreadsheet to ''DomainObject''. This might be some cell coordinates for example. ''SpreadsheetReader'' can store them into the newly created ''DomainObject'' and ''SpreadsheetWriter'' uses the data to store the ''DomainObject'' to the correct position in the spreadsheet. The problematic method is ''DomainObject.getCellPositionInSpreadsheet()'' 
- 
-This is a simple solution (see [[Keep It Simple Stupid|KISS]]) but it violates PSU. ''DomainObject'' is not understandable on its own. It holds data (namely the cell position in the spreadsheet) that is only meaningful in the context of the other two modules. During maintenance this data could accidentally be altered (resulting in a corrupted output file). Maintenance effort is also increased simply by distracting the maintainers who might wonder what this data is and if it is relevant for their task. 
- 
-A better solution (wrt. PSU) would be to give ''SpreadSheetWriter'' the ability to determine the correct position in the spreadsheet itself. This is more complicated and may involve searching the spreadsheet for the correct position. But ''DomainObject'' is easier to understand and less prone to errors. 
- 
-==== Example 2: Dependent Private Methods ==== 
- 
-In a module that computes results in a bowling game there might be a method ''strike()'' which returns true when the player has thrown a strike, i.e. hit all 10 pins with only one ball throw. 
- 
-<code java> 
-private int ball; 
-private int[] itsThrows = new int[21]; 
-   
-private boolean strike() 
-{ 
-    if (itsThrows[ball] == 10) 
-    { 
-        ball++; 
-        return true; 
-    } 
-    return false; 
-} 
-</code> 
- 
-Here the method not only computed if the current throw is a strike but also advances the counting variable ''ball''. This is only meaningful in the context of another module. If this is correct behavior or a defect cannot be told solely by looking at this method. Should ball be increased by 1 or 2? Should it also be increased when the throw is not a strike? Should it be increased at all? It cannot be told without looking at other parts of the code. So this method violates PSU. 
- 
-The following solutuion is better: 
-<code java> 
-private int rolls[] = new int[21]; 
- 
-private boolean isStrike(int frameIndex) 
-{ 
-    return rolls[frameIndex] == 10; 
-} 
-</code> 
-Here no counting variable is increased in some way. Furthermore this  method does not rely on a correctly set counter variable but gets a parameter. 
- 
-This example is taken from Robert C. Martin.  
-  * First version: ((http://www.objectmentor.com/resources/articles/xpepisode.htm)) or ((Robert C. Martin: //Agile Software Development, Principles, Patterns, and Practices//)) 
-  * Second version: ((http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata)) or ((http://www.slideshare.net/lalitkale/bowling-game-kata-by-robert-c-martin)) 
  
 ===== Description Status ===== ===== Description Status =====
 /* Choose one of the following and comment out the rest: */ /* Choose one of the following and comment out the rest: */
-/*[[wiki:Stub]]*+[[wiki:Stub]] 
- +/*[[wiki:Incomplete]]*/
-[[wiki:Incomplete]] +
 /*[[wiki:Complete]]*/ /*[[wiki:Complete]]*/
  
principles/principle_of_separate_understandability.txt · Last modified: 2021-10-18 22:13 by christian