User Tools

Site Tools


about:navigating_principle_languages

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
Last revisionBoth sides next revision
about:navigating_principle_languages [2013-09-13 16:09] christianabout:navigating_principle_languages [2013-09-15 22:39] christian
Line 43: Line 43:
   * For the data layer there is a data component, a class ''DataImpl'' which aggregates three subcomponents ''Enterprise'', ''Persistence'', and ''Store'' and gives access to them.   * For the data layer there is a data component, a class ''DataImpl'' which aggregates three subcomponents ''Enterprise'', ''Persistence'', and ''Store'' and gives access to them.
  
-FIXME code for Data class+<code java> 
 +public class DataImpl implements DataIf  
 +
 +    public EnterpriseQueryIf getEnterpriseQueryIf()  
 +    { 
 +        return new EnterpriseQueryImpl(); 
 +    } 
 + 
 +    public PersistenceIf getPersistenceManager()  
 +    { 
 +        return new PersistenceImpl(); 
 +    } 
 + 
 +    public StoreQueryIf getStoreQueryIf()  
 +    { 
 +        return new StoreQueryImpl(); 
 +    } 
 +
 +</code>
  
   * There are "factory" classes which lazily create and provide access to single instances of a component.   * There are "factory" classes which lazily create and provide access to single instances of a component.
Line 53: Line 71:
     private static DataIf dataaccess = null;     private static DataIf dataaccess = null;
  
-    private DataIfFactory () {}+    private DataIfFactory() {}
  
-    public static DataIf getInstance () +    public static DataIf getInstance() 
     {     {
         if (dataaccess == null)          if (dataaccess == null) 
         {         {
-            dataaccess = new DataImpl ();+            dataaccess = new DataImpl();
         }         }
         return dataaccess;         return dataaccess;
Line 127: Line 145:
 As a result we get {LC, KISS, RoE, TdA/IE, ML} as the characterizing set. As a result we get {LC, KISS, RoE, TdA/IE, ML} as the characterizing set.
  
-Note that although in this example the principles are examined in a certain order. Nevertheless the method does not prescribe any.+Note that although in this example the principles are examined in a certain orderthe method does not prescribe any.
  
  
 ==== Using the Characterizing Set ==== ==== Using the Characterizing Set ====
 +
 +In order to answer the above question, we have to informally rate the solution based on the principles of the characterizing set:
 +
 +  * LC
 +    * The solution creates a relatively strong coupling to the concrete implementations of the components. If a class uses the "factory" and the components it gives access to, there is no way to have the class use other implementations of the components. There is no way to replace the implementations by a stub for testing purposes, there is no way to smoothly switch to another ''Data'' component possibly using another way of storing the data. Every change in the arrangement of the classes needs a change in the code. LC is rather against this solution.
 +  * KISS
 +    * The solution is pretty easy to implement. Furthermore it is easy to get access to an arbitrary component. So according to KISS this is a good solution.
 +  * RoE
 +    * Getting access to a component is implicit. There is no need to explicitly pass a reference around. There is not even the necessity to explicitly define an attribute for the dependent class. RoE tells, that the solution is bad.
 +  * TdA/IE
 +    * Getting access to a the ''Store'' subcomponent requires asking ''DataIfFactory'' for the ''Data'' component and asking that one for the store. There is no way to tell the "factory" to do something. TdA/IE is against the solution.
 +  * ML
 +    * There are no particular pitfalls with this solution. So ML has nothing against it.
 +
 +So LC, RoE and TdA/IE are against the solution, KISS thinks it's good and ML has nothing against it. As it is not the number of principles which is important, the designer still has to make a sound judgment based on these results. What is more important: Coupling, testability, and clarity or a simple and fast implementation. In this case we'd rather decide that the former are more important, so we should rather think about a better solution.
 +
 +==== Deciding between Alternatives ====
 +
 +In the next step we would think about better alternatives and might come up with [[patterns:dependency injection]] and [[patterns:service locators]]. So there are three alternatives (with several variations): The current solution and the two new ideas.
 +
 +We already constructed a characterizing set. So the only thing to do is to rate the ideas according to the principles:
 +
 +The current "factory" approach is abbreviated "F", dependency injection is DI and SL stands for service locator. In the following a rough, informal rating is described, where "A > B" means that the respective principle rates A higher/better than B. "=" stands for equal ratings.
  
   * LC   * LC
 +    * DI > SL > F 
 +    * Note that in the SL approach there is an additional coupling to the service locator
   * KISS   * KISS
 +    * F > DI = SL
 +    * All three solutions are rather simple but in DI there is complexity for passing around the references and in the SL approach there is complexity in maintaining the registry
   * RoE   * RoE
 +    * The rating of RoE depends on the concrete variant of the pattern. In the DI approach the dependencies are explicitly visible on the interface, which is not the case in the two other approaches. In solution F the dependency is not visible from the interface at all. Same with SL if the service locator is globally accessible. Even if a reference to the service locator is explicitly passed around, it is still not visible which services provided by the locator are used. On the other hand getting a reference is explicit with F and SL. In the DI approach it is only explicit when it is done manually. Typical DI frameworks wire the instances implicitly.
   * TdA/IE   * TdA/IE
 +    * DI > FIXME
   * ML   * ML
 +    * F > DI > SL
 +    * In the DI solution a possible fault would be to have different modules reference different instances of the same class where they should rather reference the same instance. In SL solution there is even a more problematic fault which could be introduced. Eventually somebody might get the idea to change the registered instances in the locator at runtime. This would then be the source for some hard to find defects: Some modules will cache the instance they got from the service locator in an attribute and some won't. In such a case the latter will receive the new instance while the former won't.
about/navigating_principle_languages.txt · Last modified: 2013-09-16 17:27 by christian