Bridging the gap between architectural design and implementation
In my last post, I pointed out that there is a gap between architectural description and implementation of software systems. Taylor et al. refer to this as the “mapping problem” in their chapter about implementation in . In other words, architectural design decisions should be mapped to specific implementation constructs in order to prevent architectural erosion. Ideally, this mapping would include mappings for all kinds of architectural artifacts such as components, connectors, configurations, behavioral properties, and even non-functional properties, etc.
One reason that the mapping problem can be difficult to solve is that most programming languages are not architecture-aware. Eichberg et al. have done some work on maintaining constraints on structural program dependencies defined over arbitrary groupings of code elements called ensembles . They rightly point out that the module system built into a programming language is orthogonal to the module system in the architecture. I would agree with this whole-heartedly, especially when it comes to connectors which are by their very nature prone to being highly distributed at the implementation level. It is perhaps a bit easier to form one-to-one mappings between architectural components and program modules, but even this should not be assumed. In the Eichberg work, ensembles are defined using a domain-specific language based on Datalog and myriad different Java constructs may be identified as being part of an ensemble (e.g., class, interface, method, field, method call, etc.). This means that an ensemble definition may cross-cut Java modules. This is similar in spirit to the way that pointcuts are used in aspect-oriented programming to select “where” in the program (statically or dynamically) an aspect’s code should be executed.
Architectural integrity, then, can be maintained by creating ensembles that represent architectural concerns (e.g., a component or a layer) and then constraining the dependency relationships among ensembles (e.g., only factory classes can execute certain object constructors or classes in layer N must only “use” classes in layer N-1). Through the use of Datalog-like expressions, a wide range of constraints can be specified. It’s not clear to me exactly how to quantify the expressiveness of this language without a formalization of possible architectural constraints, but at first blush it seems expressive enough to write even complex static structure-based constraints. Kudos to the authors for including a visual language with notions of in-ports and out-ports that can be connected with arrows. Also included are Java annotations which are used to define ensemble membership right in the code. This work is primarily targeted at maintaining architectural integrity as an application evolves. Through integration with the Eclipse IDE, constraints can be checked with every incremental build and any violations of the architecture are immediately made known to the developer. At this point, it is not clear to me how this approach would work for a development methodology in which an architecture is designed up front before any coding constructs exist (i.e., it is hard to define ensemble memberships unless the code structures already exist). Also, there is lack of support for ensembles based on dynamic properties of the implementation.
The Archface work in  is another technology designed to bridge the gap between architecture and implementation. An “archface” is a type of interface that represents an architectural component or connector. The building blocks of Archface are pointcuts from aspect-oriented programming. The pointcuts identify architecturally-relevant program points (e.g., method execution, method call, field read/write, etc.) and they can be exposed as ports (in or out). Connector interfaces are used to link ports–that is, they coordinate the program points exposed via ports. So, just like the Eichberg work described above, a pointcut-like mechanism is used to expose program “locations” that are architecturally-relevant. Although somewhat hard to compare, there appears to be a difference in what you can do with the exposed program points: In the Eichberg work, constraints can be defined over the dependency relationships among the ensembles in an architecture. In Archface, a kind of mediation happens when connectors are linked–for example, the call of a method in one port is linked to the execution of a method in another port. This is a kind of indirection that is mediated by the connector using the AOP notion of advice. I think a major reason for this difference is that Eichberg et al. do not recognize a first-class connector. That being said, it is not clear to what degree the Archface connectors correspond to connectors as defined in the classic software architecture literature. Perhaps I get this feeling only because the connector examples given in the Archface paper  are only used to connect ports and do very little processing on their own. I guess, then, that the expressiveness of the connectors boils down to what advice mechanisms are available. Another major difference between Eichberg and Archface is that Archface inherits dynamic pointcuts from AspectJ whereas the former is strictly static.
But, bottom-line takeaway from both of these papers is that some of the the latest thinking about spanning the gap between architecture and implementation involves some kind of mechanism to abstract and expose architecturally-relevant programs points and then manipulate them in some way either by constraining their dependency relationships or mediating their interactions. Both of these mechanisms seem very powerful allowing for the expression of all kinds of architectures. A concern I have with both–but especially Archface–is whether they offer intuitive mechanism for specifying the relationship between architectural concerns and the implementation. For example, even in the simple examples given in  you have to do a kind of mental code-weaving to get a feel for an architecture described by Archface. It could get pretty ugly if a complex architecture were described.
 Richard Taylor, Nenad Medvidovic, Eric M. Dashofy. Software Architecture: Foundations, Theory, and Practice. Wiley, 2009.
 Michael Eichberg, Sven Kloppenburg, Karl Klose, and Mira Mezini. “Defining and Continuous Checking of Structural Program Dependencies.” ICSE 2008.
 Naoyasu Ubayashi, Jun Nomura, Tetsuo Tamai. “Archface: A Contract Place where Architectural Design and Code Meet Together.” ICSE 2010.