I was just reading up on SCA (Service Component Architecture) and was struck by how well this matches my view of how software components should be assembled within an app as well. I touched on pieces of this quite a bit in my “Designing with Dependency Injection” presentation a while back but it has become even clearer to me over time.
My basic view is that an application is made up of components. Components should have a well-defined interface. Components should use other components which are configured via setters (or other dependency injection means). Components have properties, while are also set at assembly time via dependency injection. Both properties and dependent components are points on a continuum of “component configuration” but can be roughly classified as configuring a component vs wiring components together. An application is instantiated by assembling some set of components (configuring and wiring them).
For example, in Spring, this configuration and wiring is all done (typically) via an XML configuration file and BeanFactories in the code. In J2EE, this is conceptually done by the app server (not a good example before Java EE 5, but getting closer to this). I’ve handrolled stuff like this as well for small assemblies.
SCA basically matches these concepts, with essentially the identical terminology. In SCA, “assembly” is being done at a much higher level and is at least partially outside the domain of any one “assembler” as there are typically external services in use along with the internal services of a composite application.
I’ve been thinking for a while that this pattern occurs on many levels (at both the class and component and subsystem and application levels) but had not extended it upward into SOA, but SCA does just that. SCA even talks about the difference between coarse-grained and fine-grained components, which I’ve traditionally talked about as “components” and “classes” in terms of app building.
The key is that dependencies and usage interfaces are well-defined and independent of implementation. That allows visual or automated assembly, easy testing (can mock out
dependencies and test on a per-component level), reuse, separation of concerns for implementer and assembler, etc.