Lakos Level of a Package

The Lakos Level of a package is an indication of how high up it is when the system is explored in a top-down manner: the topmost packages are those specific to the application (often containing the Main class, whereas low packages typically contain utility classes.

Formally, the level of a package is defined as follows:

  • A package that participates in a dependency cycle does not have a level.
  • A package that depends only on itself has level 0.
  • A package has level 1 if it does not depend on another package that occurs in the source.
  • A package has level n+1 if it depends on a package that has level n.

The above definition can assign multiple level values to the same package; the Lakos level is the maximum of all those values.

There is no recommended range for this metric; it gives guidance on how to view the system in a top-down manner, and in what order to explore packages.

This metric is named after John Lakos, as he first proposed it in his book on large-scale design in C++.

Pre-packaged Query

Query name = "Semmle/Metrics/Packages/Coupling/Packages with high Lakos level"

Reports packages in the source that have a Lakos level higher than 3, in descending order, as a bar chart.

from MetricPackage p, float c
where p.fromSource() and c = p.getLevel() and c > 3
select p, c order by c desc

.QL Source of Metric

This metric is generic, in the sense that it is defined in a separate class that is a super class both of MetricRefType and of MetricPackage. Each of these subclasses override the notion of dependency, in particular in MetricPackage that specialized definition is:

     MetricElement getADependency() {
        exists(RefType t |     
           depends(this.getARefType(),t)
           and
           result = (MetricPackage) t.getPackage())
           and
           result != this
     }

The generic definition of the level metric is as follows:

  MetricElement getADependencySrc() {
      result = this.getADependency() and result.fromSource()
  }

  /* get some level */

  int getALevel() {
       this.fromSource()
       and
       not(this.getADependencySrc+()=this)
       and 
       ( (not(exists(MetricElement t | t=this.getADependency()))
          and
          result=0)
        or
         (not(this.getADependency().fromSource())
          and
          result=1)
        or
         (result = this.getADependency().getALevel() + 1) )
     }

   /* getLevel returns John Lakos's level metric */
   int getLevel() {
       result = max(int d | d = this.getALevel())
   }

Further Remarks

In other metrics tools, it is sometimes suggested that you use the absence of a Lakos level to test for the existence of dependency cycles. In .QL, it is much nicer to write a special query for that, and some hints on how to do that can be found in the description of Cyclic Package Dependencies.

References

John Lakos. Large-scale C++ Software Design Addison-Wesley, 1996.

Antranig Basman. Levelization Wiki Page, 2006.

Patrick Smacchia. NDepend - Level metric , 2006.

Digg!Reddit!Del.icio.us!Facebook!Slashdot!Technorati!StumbleUpon!Ma.gnolia!

Comments
Only registered users can write comments!
 
< Prev   Next >