6 Adaptable Technology Wrapper

Aligning an API with a Pattern Language give rise to source consistency. A wrapper approach supports underlying technology choice.

Based on experience with “the Company,”[1] an “adaptable technology wrapper” (ATW) can: align the Application Programming Interfaces (APIs) of chosen technologies, provide pattern enforcement, limit API complexity via filtering, reduce duplicate code, assist with JUnit testing, and provide additional benefits.

Perhaps the earliest widespread example of intentionally aligning an API with a pattern collection was provided by the Spring framework in 2004. In the following @Repository Javadoc example, the alignment is made clear by stating the origin of the Repository pattern:[2]

@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Component

public @interface Repository

Indicates that an annotated class is a "Repository", originally defined by Domain-Driven Design (Evans, 2003) as "a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects."

A technology wrapper may be understood by analogy; instead of wrapping a single Java object (class) a technology wrapper normalizes an entire API. A PED technology wrapper aligns an API with our Unified Pattern Language.

Wrapper

This figure suggests an API Wrapper as analogous to a Java Object Wrapper.

In addition to pattern alignment, a creative wrapper author can implement modest pattern enforcement. For example, at “the Company” we have used a coding convention runtime exception if a concrete class name lacks the published suffix from the Unified Pattern Language. Here is an example enforcing the Domain Entity (DE) pattern suffix:

suffix

This figure displays source for enforcing the DE suffix with concrete extending classes.

The 2013 version of Microsoft Word for Windows has 39,900 entries in the Help system. If you studied one of those entries per day it would take over 109 years to learn all the features of this one piece of software! Word is hardly unique; many technologies are feature-bloated beyond an ability to learn them quickly. An ATW can limit API complexity by filtering out seldom used features that do not align with a pattern language.

As an example, consider the following diagram listing nine API methods:[3]

EntityManagerFactory

This figure lists the API for the Java JPA EntityManagerFactory class.

There is an opportunity to reduce the number of public methods used in this class. Presume that the approach calls for the EntityManagerFactory (with its internal shared cache) to remain durable for the life of the application. In this case, there is no need to ever invoke the close() and isOpen() methods. A wrapper can eliminate exposing methods not applicable to a particular design.

Copy-and-paste is perhaps the most obvious practice yielding duplication. Another form of duplication derives from using boilerplate code.[4]  For example, two or more occurrences of boilerplate code may perform virtually identical functions while addressing different user stories. Duplication is sometimes a response to the demands of a verbosity-inducing API.  That is, some APIs lack cohesion and thus impart this short-coming on application source; a wrapper can enhance API cohesion.

It has been interesting to observe that as APIs become more powerful—powerful in that operations accomplish greater amounts of work—JUnit test code sometimes becomes more verbose! Tests requiring excessive operations (lines of code) constitute a test code “smell” indicative of an overlooked opportunity to make effective use of an ATW. Powerful “assert” methods can dramatically ease JUnit test complexity with approaches such as the JUnit Strategy for Testing

An ATW can also provide integrated logging as feedback from the runtime execution of native technologies. In recent years, some newer technologies such as JSF (with its Development Project Stage) have begun to incorporate using additional runtime logging as engineering feedback. The following code sample establishes four discrete modes that augment exception, performance, lifecycle, and trace logging:

Log Modes

This figure displays four discrete modes for declarative logging.

Modern asynchronous logging enables verbosity without a performance penalty.

At least two additional benefits accrue to this principle of wrapping preferred technology APIs. One relates to software flexibility:

Wrapping third-party APIs is a best practice. When you wrap a third-party API, you minimize your dependencies upon it: You can choose to move to a different library in the future without much penalty. One final advantage of wrapping is that you aren't tied to a particular vendor’s API design choices. You can define an API that you feel comfortable with.[5]

A second benefit can derive from decoupling a technology and its API: insulation from security vulnerabilities. In 2006 “the Company” began work on an ATW around Struts intended to enhance convenience and safety. In 2013, a Struts vulnerability was discovered and options for remediation subsequently emerged within the open source community. Because many teams had elected to use “the Company” Struts ATW, we were able to apply remediation for hundreds of software engineers across six continents with a simple JAR update.

References

[1] In 2002, Java was adopted as the standard platform for in-house software engineering at a successful large automotive manufacturing enterprise (“the Company”).

[2] Repository

[3] EntityManagerFactory

[4] In computer programming, boilerplate code or boilerplate is the sections of code that have to be included in many places with little or no alteration.

[5] Feathers, M. 2009. Error Handling, In R. C. Martin, ed., Clean Code. Pearson Education, Inc., p. 109