1 / 54

Software Design and Metrics

Hayden Melton Computer Science hayden@cs.auckland.ac.nz May 2006. Software Design and Metrics. Overview. Buzzwords for designing software: Loosely-coupled Cohesive Encapsulating Manageable size “Fuzzy terms” – what do they actually mean?

emily
Download Presentation

Software Design and Metrics

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Hayden Melton Computer Science hayden@cs.auckland.ac.nz May 2006 Software Design and Metrics

  2. Overview • Buzzwords for designing software: • Loosely-coupled • Cohesive • Encapsulating • Manageable size • “Fuzzy terms” – what do they actually mean? • Today I’ll try to be rigorous about one form of coupling

  3. Coupling • Two things are coupled if to changing one also requires changing another [Fowler, Stevens] • “Strength of association of established by a connection from one module to another” [Stevens, Myers, Constantine] • Many forms of coupling – dependency at runtime, compile time dependency, change dependency (CVS data).

  4. Java • Java is a strongly typed language, which means the compiler checks the types of expressions etc before allowing compilation • A Java program can be thought of as a collection of types (i.e. classes, interfaces, enums, primitives) • Can view a (reference) type as a composition of other types

  5. Meaning of Compilation Dependency public class Foo {        private A a = new A();        public P m1() {X x = new X(a);K k = x.m();P p  = k.m();                return p;        }        public P2 m2(P3 p3) {P2 p2 = Z.run(a, p3);                return p2;        }}

  6. A P X K Foo P2 P3 Z Meaning of Compilation Dependency public class Foo {        private A a = new A();        public P m1() {X x = new X(a);K k = x.m();P p  = k.m();                return p;        }        public P2 m2(P3 p3) {P2 p2 = Z.run(a, p3);                return p2;        }}

  7. Structure of a typical Java Program

  8. KEY Source-declared type Externally-declared type Structure of a typical Java Program

  9. KEY Source-declared type Externally-declared type Compilation dependency Structure of a typical Java Program

  10. KEY Source-declared type Externally-declared type Compilation dependency Structure of a typical Java Program

  11. KEY Source-declared type Externally-declared type Compilation dependency Structure of a typical Java Program

  12. Observations on Structure • Externally-declared types can’t depend on source-declared types • The graph is connected • Classes must communicate with each other to be part of the same system • The source-declared subgraph is usually connected • Externally declared types can’t instantiate source declared ones, and they’ve got to be instantiated somewhere

  13. Design Principles • Depend entirely on externally-declared types (if possible) • Proven, well-understood, stable, widely-available • Dependency on externally-declared types less detrimental coupling than dependency on source-declared types • Source types change, unique to application – so not well understood

  14. (a) (b) Two Systems: a comparison • Which is most “loosely-coupled”? • Think in terms of reuse, understanding, testing, …

  15. (a) “Layered” or “Hierarchical” Structure • Reuse • Deploying a type in the context of a new system and having it compile • Testing • Unit testing, Integration testing • Understanding • No good place to start [Lakos], go round the cycle many times [Fowler].

  16. Reuse • Why “verbatim reuse”? • Even the smallest changes to reused code can introduce errors [Stark]. • Version proliferation • Divergence from original, hard to integrate updates [Martin]. • For reuse to be effective the class we’re reusing can’t be tied to a large block of unnecessary code • Increases the number of types to be considered in the new system, and potentially more code that could contain bugs • Really a problem – Azureus (logger, internationalization, torrent parser, concurrency). Eclipse (Internal compiler depends on a few thousand classes c.f. Sun’s Java compiler).

  17. Reuse

  18. Reuse

  19. Reuse

  20. Reuse

  21. Reuse

  22. Reuse

  23. Reuse

  24. Reuse

  25. Reuse • Dependency is transitive • If A depends on B, and B depends on C, then A transitively depends on C. • Deploy a source file from one program in the context of another also need all the files it needs to compile. But we also need all the files the others need. We need the transitive closure of its dependency. • Transitively a recurring theme…

  26. (a) (b) Testing • Unit testing – about testing a class “in isolation” • More dependencies it has, potentially more interactions it has  harder to test in isolation

  27. (a) (b) Testing • Integration testing – about testing system “in order” • Test one level, find it’s correct. Test the next level find it’s correct, …

  28. (a) (b) Testing • Integration testing – about testing system “in order” • Test one level, find it’s correct. Test the next level find it’s correct, …

  29. (a) (b) Testing • Integration testing – about testing system “in order” • Test one level, find it’s correct. Test the next level find it’s correct, … Where to start? Need to test it all in one go!

  30. Understanding • Similar argument to reuse – in order to understand a class should only (at most) have to understand the classes on which it transitively depends • Worst case for understanding class indicated in red: • A starting point for understanding a system the first time you look at it (as per integration test order)

  31. Understanding • What about polymorphism? To understand Foo, we also have to understand BarImpl yet Foo doesn’t transitively depend on BarImpl! Baz Foo BarImpl IBar

  32. Understanding • public class Baz { void run() { IBar bar = new BarImpl(); Foo foo = new Foo(bar); //... }}public class Foo { private IBar bar; public Foo(IBar bar) { this.bar = bar; } //...makes extensive use of bar in body} Constructor Dependency Injection

  33. Understanding • Argument still holds if we have good unit tests • Should be able to glean all the pre- and post- conditions from the unit tests of Foo. • The key is the type MockBarImpl • public class TestFoo extends TestCase { public void testFoo() { IBar bar = new MockBarImpl(); Foo foo = new Foo(bar); //... }}

  34. Comparing Hierarchical Structures • Hierarchical/layered structures better than their cyclic analogues • What “shape” of hierarchical structure is best? (c) (b) (a)

  35. Comparing Hierarchical Structures • Number of classes coupled to “nothing” (or “standalone”)? • (a) has 1 • (b) has 4 • (c) has 7 • Recall: Reuse, understanding, testing. (c) (b) (a)

  36. Ideal Hierarchical Structure • So we want a “flatter” hierarchical structure rather than a taller one • Classes in “flat” structures tend to have lower transitive dependencies than those in “tall” structures • We also want the “flat” structure to have small transitive dependencies, not like:

  37. a d b c e f g h i Metric - CRSS • Class Reachability Set Size (CRSS) captures the transitive dependencies of each class

  38. CRSS Histogram

  39. A “Good” CRSS Distribution

  40. A “Bad” CRSS Distribution

  41. Bunch of classes all involved in one, big strongly connected component. Why the big gap in the Histogram? Freq  CRSS 

  42. Bunch of classes all involved in one, big strongly connected component. Why the big gap in the Histogram? Freq  CRSS 

  43. Bunch of classes all involved in one, big strongly connected component. Why the big gap in the Histogram? Freq  CRSS 

  44. Bunch of classes all involved in one, big strongly connected component. Why the big gap in the Histogram? Freq  CRSS 

  45. Using the Metric to Manage a Project

  46. Using the Metric to Manage a Project

  47. Using the Metric to Manage a Project

  48. Using the Metric to Manage a Project • Empirical evidence I have gathered shows if uncontrolled, dependencies seem to get worse over time! • CRSS values grow • Cycles grow and become intertwined v1

  49. Using the Metric to Manage a Project • Empirical evidence I have gathered shows if uncontrolled, dependencies seem to get worse over time! • CRSS values grow • Cycles grow and become intertwined v1 v2

More Related