I'm in San Francisco attending QCon 2008 this week.
Session: Golden Rules to Improve Your Architecture, 1PM-2PM
Alexander v. Zitzewitz
hello2morrow, Inc
created hello2morrow in 2005
"The Dragon of Complexity"
- invisible
- snatches you from behind
- your enemy
"You can never kill complexity"
"The friend of the dragon is the Law of Entropy"
Erosion of architecture - a fundamental law?
Architecture erosion is quote a known problem
- System knowledge and skills are not evenly distributed
- Complexity grows faster than size
- Unwanted dependencies are created without being noticed
- Coupling and complexity are growing quickly
Typical symptoms of an eroded architecture are a high degrees of coupling and a lot of cyclic dependencies
- changes become increasingly difficult
- testing and code comprehension become more difficult
- deployment problems of all kinds
"The Truth can only be found in the code"
Mapping of physical elements to logical elements
- Each package is mapped to exactly one subsystem
- If package's contain types of several subsystems, virtual refactorings are helpful
- a good naming convention for package's can make your life every simple
-- com.company.projectName.verticleSlice.layer
- Subsystems should have interfaces
- Work incrementally
-- start with your layering
-- then add the vertical slices (if applicable)
-- define subsystem interfaces
-- fine tune the rules of engagement on the subsystem level
How to measure coupling
- ACD = average component dependency
- average number of direct and indirect dependencies
- rACD = ACD / number of elements
- NCCD: normalized accumulated component dependency
(from the large-scale C++ design book)
__BIG IDEA__
Robert C. Martin: Dependency Inversion Principle
(invert dependencies, add interfaces)
Spring is a big abstract factory pattern
Average component dependency should be below 7% - heuristic target
Spring has no cyclic dependencies greater than +1
__Cyclic dependencies are evil__
- No cycles between packages
- the dependencies between packages must not form cycles
- cyclic physical dependencies among components inhibit understanding, testing, and reuse.
Introducing interfaces allows you to break cyclic dependencies
__Six Golden Rules for a successful project__
Rule 1: define a cycle free logical architecture down to the level of subsystems and a strict and consistent package naming convention
Rule 2: do not allow cyclic dependencies between packages
Rule 3: keep the relative ACD low (<7% for 500 compilation units, NCCD < 6)
Rule 4: limit the size of java files (700 LOC is a reasonable value)
Rule 5: limit the cyclomatic complexity of methods (e.g. 15)
Rule 6: limit the size of a java package (e.g. less than 50 types)
Tools
- JDepend
Neal Ford's presentation: 10 Ways to Improve Your Code, 3:45PM
#1 - Composed Method
Divide your program into methods that perform one identifieable task
refactoring to composed method
__Benefits of composed Method__
method names become documentation
large number of very cohesive methods
discover reusable assets that you didn't know were there
#2 - Test-Driven Development (TDD)
(also Test-Driven Design)
__Benefits of TDD__
- first consumer
#3 - Static Code Analysis
- byte-code analysis: findbugs
#4 - Good Citizenship
singleton is bad because it mixes responsibilities, untestable, the object version of global variables
avoiding singletons
- create pojo for the business behavior (simple, testable)
- create a factory to create one-and-only-one
#5 - yagni
(agile term)
You-ain't-going-to-need-it
build the simplest thing that we need right now
don't indulge in speculative development
increases software entropy
only saves time if you can guarantee you won't have to change it later
if features are weight - then anticipatory design decreases the velocity of the rate of change that is sustainable in a code base.
Top 10 Corporate Code Smells
10 - we invented our own web/persistence/messaging/caching framework because none of the existing ones were good enough
9 - we bought the entire tool suite (even though we only needed about 10% of it) because it was cheaper than buying the individual tools.
8 - We use WebSphere because...(I always stop listening at this point)
7 - We can't use any open source code because our lawyers say we can't
6 - We have an Architect who reviews all code pre-checkin and decides whether or not to allow it into version control
5 - The only JavaDoc is the eclipse message explaining how to change your default JavaDoc template
4 - We keep all of our business logic in stored procedures..for performance reasons
3 - We don't have time to write unit tests (we're spending too much time debugging)
2 - The initial estimate must be within 15% of the final cost, the post-analysis estimate must be within 10%, and the post-design estimate must be within 5%
1 - There is a reason WSAD isn't called WHAPPY
#6 - Question Authority
test names - use underscores (not Camel Case)
non-intuitive
pair-programming studies - pairs produce code 15% slower after adjustment, but with 15% fewer defects
#7 - Single Level off Abstraction Principle (slap)
everything should be at the same level of abstraction
jumping abstraction levels makes code hard to understand / maintain
#8 - Polyglot programming
leveraging existing platforms with languages targeted at specific problems and applications
looming problems/opportunities
- massively parallel threading
-- use a functional language:jaskell, scala (inherently thread save, immutable)
- schedule pressure
-- jruby on rails
- writing more declarative code via dsls
- build fluent interfaces
-- swiby:jruby + swing
--- (swiby is a DSL for UI programming)
"Java will become the glue language"
#9 - Learn Every Nuance of your chosen language/tool
- java's back alleys
-- reflection
- regular expressions
#10 - anti-objects
OOPSLA 2006 - collaborative diffusion presentation
"The metaphor of objects can go too far by making us to create objects that are too much inspired by the real world"
Dr. Dean Wampler's presentation: Radical Simplification Through Polyglot and Poly-Paradigm Programming, 5:15PM
Simplification of code is necessary
Ola Bini's Three Layers
Functional Programming avoids multi-threading/concurrency issues
Functional programming: Declarative rather than imperative
DSLs tend to be very declarative
Examples of Functional Languages:
- Erlang
-- 9-9's reliability for AXD301 switch
-- for distributed, reliable, soft-time
-- All IPC is optimized messaging passing
-- very leightweight and fast processes
-Scala
-- hybrid language (object and functional)
-- targets the jvm
-- "endorsed" by James Gosling at JavaOne
-- could be a popular repalcement for Java
"Is a hybrid object-functional language better than using an object language with a functional language"?
Disadvantages of PPPP
- N tool chains, languages, libraries, "ecosystems"
- impedance mismatch between tools
Advantages of PPP
- use best tool for a particular job
- can minimize amount of code required
- can keep code closer to the domain
- encourages thinking about architectures
Why go mainstream now?
- rapidly increasing pace of development
- pervasive concurrency
- cross-cutting concerns