The phrase "component reuse" to some in the development community can be controversial and as contentious as the term sounds, there have being successful implementations of component reuse patterns. However, with recent trends signifying an exponential increase in code complexity, it may be past the time for component reuse to be the standard (de facto) software design pattern.
In retrospect, multiple software projects that utilized various component reuse patterns in a mixed bundle of sub-optimal designs usually achieved some technical objectives, but barely accomplished their required business objectives.
The Decoupling Principle
One software pattern across successful systems is the key design principle of ensuring we – "code to an interface and not to an implementation" implied in "Design Patterns" by Erich Gamma.That is, the design implementation is focused on the internal and external interfaces including the interactions that make up the system.
I worked on a recent project to develop a reference web application that utilized the Dependency Injection (DI) pattern for a client. The pattern used a decoupling of program logic, explained in "Reducing Coupling" by Martin Fowler, from the implementation using a model of loosely-coupled runtime object binding by relying on interface contracts to achieve a reasonable level for separation of concerns among collaborating components. The reference web application I worked on, utilized the Dependency Injection and Annotation constructs of Spring 3.1.1.
Much Ado About Code
To understand the Dependency Injection pattern, keep in mind that there are two types of interfaces, the normal or ordinary interface and the annotation types. Normal interface contract implementations bind the object template at compile time by locking the interface definition directly to its implementation. This binding limits the flexibility for code modification or changes, while Dependency Injection using Inversion of Control (IoC) frameworks utilize a de-coupled implementation pattern to bind the object at runtime creating the ability to rapidly change constructs using the efficient introspection capabilities of the underlying JVM with configuration files and annotations.
The Hollywood Principle – "Don't call us, we'll call you!"
The phenomenon, as Martin Fowler wrote in a paper cited in 2005, where the underlying application framework calls back into code based on an event that occurred is known as Inversion of Control - IoC (also known as the Hollywood Principle – "Don't call us, we'll call you" first cited in a paper "The Mesa Programming Environment" by Richard E. Sweet in 1985, pp. 218 section 2.2). Dependency Injection is a specific type of Inversion of Control.
Two popular IoC frameworks that use slightly different methodologies to accomplish similar purposes are the Spring Framework and Java EE 6 CDI (Context and Dependency Injection) framework. Both frameworks make it easy to provide DI capabilities to applications developed in Java. The technique currently used to obtain a reference to a component (bean) or service relies on annotation constructs aptly called "@Named" and "@Inject" defined in the JSR 330 for use in Java EE 6 revisions and above. Similar or nearly identical constructs are available in normal Spring Framework annotations namely, "@Component" and "@AutoWired".
Annotation By Any Other Name
@Named and @Component are annotations that provide the same functionality but come from different Dependency Injection API frameworks. @Named belongs to the javax.inject API; it marks a class to be autodetected as a component bean and requires a name to be explicitly specified. @Component belongs to the Spring API framework and marks a class to be autodetected as a component bean, but optionally allows an explicit name to be specified. If a name is not explicitly specified for @Component, the component bean will use the marked class name as its name.
Similarly, @Inject and @Autowired are annotations that provide the same functionality, but come from different API's. @Inject belongs to the javax.inject API; it is used to mark the field where an injection should place an instance of a bean into the instance of another bean via an application context metadata file. @Autowired belongs to the Spring API, and provides the same functionality as @Inject within the application context of the Spring framework.
Note: Spring 3.0 and above has included support for the standard Java Specification Requests - JSR 330 Dependency Injection for Java.
Component Detection - "You know my methods!"
Either @Inject or @Autowired can be used to inject a bean. Likewise, either @Named or @Component can be used to declare a bean by enabling the Spring framework's auto component scanning features using the component-scan annotation tag in the application context to scan and detect all the specified component classes in the assigned package name or to auto-register bean definitions by assigning the autodetect value to the autowire annotation declaration tag when defining a bean component in a context file. Note that these constructs are now available in all Spring versions 3.0 and above. Java EE CDI automatically does bean discovery and does not require any special annotation on a Java class to allow it to be injected. In Java EE CDI, a bean descriptor file is used to explicitly look for bean components in the container and ignore other packages that are not required to be bean components.
Design Reinforcement - "All's well that ends well!"
To reiterate, application components in a Dependency Injection pattern are defined by a loosely-coupled runtime object binding model defined by interface contracts. These contracts align the behavior of collaborating components within an application through the methods implemented to create distinct separation of concerns. Therefore, the concept of utilizing component collaborators lends itself to cleaner code that can easily be modified with minimal impact to the application.
Overall, component reuse based on Inversion of Control (IoC) and Dependency Injection (DI) is an efficient way to rapidly develop applications in Java, and it is well worth taking the time to understand and fully utilize these Spring and Java EE Dependency Injection (DI) and Annotation based constructs.
Note: The Spring Framework is an open source comprehensive Java based infrastructure container for developing Java based applications using managed objects (Beans). It does not impose any programming model, but it is particularly useful for developing applications in the Model-View-Controller pattern.
Thanks to the following reviewers on this blog. Phil Kedy, Eric Miles, Bob Lambert and Jason Ruth.