Tuesday, August 26, 2008

TDD and Layered Architecture

I just read the blog post of Jeffrey Palermo about the Onion Architecture (see also the similar pattern Hexagonal architecture). Aspects of this patterns are used in an architecture our team defined for a healthcare information system.

Interesting is Jeffrey's rationale for moving certain components to the outer layer: The "infrastructure is pushed out to the edges where no business logic code couples to it", because "this code is most likely to change frequently as the application goes through years of maintenance". I think this is absolutely true.

Eric Evans presented a pattern called Layered Architecture in his book Domain-Driven Design: Tackling Complexity in the Heart of Software. His rationale for for moving certain components to the outer layer: The domain model should be separated from the technical details so it contains only the concepts we want to discuss with the domain experts. That is also a very good guideline when we have decide in which layer a certain piece of code belongs.

A third rational for moving certain components to the outer layer we get when we are using TDD: All components which can't be tested by pure unit tests should be placed on the outer layer. These components should be as thin as possible, because we want to test as much code as possible by pure unit tests. Components which do not have an API defined in the implementation language like GUI components, Windows Services, Wrapper to other languages and platforms and so on are candidates for the outer layer. Here we can't use pure unit tests. Slower or more awkward tests type have to be used. Data access components for databases contain or generate SQL statements. These data access components should be tested in conjunction with the real database to verify the correctness of the SQL statements. I call these tests database unit tests. They are much slower than the pure unit tests.