A Tale of Two, Three, Four (or More) Interfaces
Summary: This article covers the art and science of identifying an application's need for common services. (6 printed pages)
One of our best technical leads stopped by my desk and asked, "You're familiar with the e-mail delivery work we're doing right now—correct?"
I replied, "Sure." We had recently discussed adding a feature to our product line that would allow our customers to improve the personalization aspects of e-mails that they send to their users. It would be an easy feature to add, while providing some pretty slick functionality—new-feature nirvana: little work, big payoff.
"Well," he said with a bit of concern in his voice, "we might not be sure what we've gotten ourselves into."
"How could adding this e-mail feature be difficult?" I asked. "Can't we just build on what we already have?"
He went on to explain that adding the feature to any particular piece of the product would not be difficult at all. However, we were in the process of bringing diverse packages together, and there were multiple existing e-mail interfaces, as well as a host of questions on how to handle each one.
We had been experiencing growth like never before. Sales were good. Everyone was excited. We had just made two acquisitions to bolster our competitive portfolio. Anticipation abounded. Work was fun. Marketing was ready to put our newly acquired technology to use with a concept that would open a number of possibilities for us. Product and technical strategies were put into place—allowing us to evolve our current offerings, while assimilating the new technology. We had all been around long enough to know that there would be bumps in the road as we brought all this code together. We looked forward to tackling the technical challenge.
We had three separate existing mechanisms for configuring and sending e-mail. This new easy–to-add feature had to provide the same functionality across the product line. Were we going to make the customer configure three different e-mail interfaces? I could already envision our sales and support teams heading down the hall to our area, as customers lit up the phone lines. Were we to write three different interfaces to provide the functionality and try to hide the inevitable differences and incompatibilities? Marketing was already breathing down our backs about the delivery schedule. What would happen if we added another package? Which of these poor options would we choose? If there was this much work for just sending an e-mail, what other similar problems lurked in our development cycle that we had yet to uncover? It was time to get a team together and head to our off-site conference center—better know as the local coffee shop.
Send an e-mail? That's easy. As we sat in our initial planning sessions, each team—representing different areas of our product line—looked at the new feature and said, "No problem. Piece of cake."
The Web interface team was the first to finish their implementation. It turned out great. We all agreed that we would follow their lead for the rest of the project. One of the server teams was next to tackle the new feature. Even though the Web team worked primarily in Java, and this server team worked primarily in C++, there was no great concern. The C++ code had an existing e-mail interface, but it did not support adding Cc or Bcc recipients. It did, however, have nice logging capabilities. To match the Java interface, the Cc and Bcc had to be added to the C++ interface. Although the C++ logging capabilities were nice, they were too complicated to add to the Java interface.
One of the subsystems did not yet have an e-mail interface. Because that subsystem was written in Java, the server team decided to use the Web team's interface. However, the two projects did not share the same source-code repository. In the process of extracting the code of the Web interface team, there were references to various Web constructs and specific user-interface data that were irrelevant to the other team.
A refactoring job was required for the Java interface, if it was to be used by multiple teams—let alone finding a code repository that the projects could share. The third e-mail interface lacked in many features, but it integrated natively with Microsoft Exchange, which opened up other possibilities. This was a concern for those who were working on the UNIX and Linux versions of the product.
Now, we found ourselves back at the coffee shop, trying to figure out how we were going to work through the explosion of problems. While we were enjoying the shop's latest music tracks and strong coffee, there was a sense of unease, knowing that we were possibly looking at the tip of an iceberg. There really were no concerns about making it all work. There was not any rocket science here; it was pretty basic code. Our concerns dealt more with the amount of effort that it would take to develop and maintain multiple interfaces that provided the same functionality, and the effect on customer satisfaction that our solution would have. Did we have to consider consolidating e-mail and other common functionality into separate stand-alone services? Were there already existing services that we could use that would help?
Regardless of application, the need to consolidate common functionality and services exists. It is easy to draw the analogy between common application services and program libraries. Like a program library, a common application service provides functionality through a common interface that is shared throughout a larger code base. Access to the service functionality is often delivered through a program library. However, where is the line drawn between library and common service?
Consider the problem previously described; a number of excellent programming libraries existed to provide e-mail functionality. However, an e-mail application service might provide functionality, such as automatic data transformation or encryption based on recipient; it might retry scheduling if an e-mail server is down, report errors, perform logging, and so forth on behalf of a calling process. Consider a service as a program library delivered with an independently operating gateway. The work is handed off to be performed by another process, either on the same system or across systems.
Capabilities Tend to Grow
Take the e-mail service one step further and consider that, if a requirement exists to send data from point A to point B by using e-mail, it is almost a sure bet that additional requirements will be made to send data from point A to point C by using FTP, fax, or some other messaging protocol. What began for us as a basic e-mail interface was turning into a full-blown delivery service—capable of sending data by using any number of protocols, in any number of formats, and providing a plethora of administrative functions. This service, accessed through a single gateway interface, would provide an application with access to a rich set of data-delivery capabilities that cooperated with one another, yet operated independently.
This e-mail interface story is based loosely on an actual experience of mine. Because of the specific requirements and capabilities of our software, we had to write our own delivery service much like the one described earlier. I have been involved in the writing of others, too. In the world of infrastructure architecture, experience teaches that the consolidation of services is a very good thing. As soon as a need is identified, see what already exists to meet that need. There are a lot of smart people who are writing a lot of good code, and it's quite possible—in fact, most likely—that the need for a service has been already solved by someone else. It then becomes a buy-versus-build proposition for your organization. It is also quite possible that an open-source effort exists that might help the cause.
You might be thinking, "I get this idea, and it makes sense. But how do I identify the need for an application service?" Look at another example of an application service: a database-management system. Unless you are a database-management company, or your application has unique data requirements, an existing database system will be selected for you to provide for your data-storage needs. It might come from a commercial vendor or from an open-source project. In either case, it is unlikely that your project plan will include a set of tasks to write a database server from scratch.
This might appear to be an obvious choice of an application service, but stop and think about what makes it an obvious choice:
- The functionality required is of use to multiple areas of an application.
- Beyond its own capabilities, the service must be independent of any particular application functionality.
- It must enable independent coordination and control of resources.
- Allow requests are made by a caller to be executed by the service on behalf of the caller.
- It must provide its own logging, diagnostic, and administrative features.
- It can be upgraded or enhanced independently of your application.
- It must provide location transparency. The service might or might not be running on the same system as your application.
Even though these requirements could be applied to a database-management system, note that none of them has anything to do specifically with database management. These are some of the high-level attributes that define an application service.
During your next development process, take a step back on a regular basis. Identify the common functions that are being used by various parts of the project. This can actually be a difficult process, but it becomes easier with time. Not all services can be as easily identified as a database-management system. Ask everyone on the team to help in this process. Unless they are occasionally reminded, most members of a team will not be looking for commonality. This is not because they are lazy. Instead ,each individual is dealing with their respective task at hand, and that is what is going to occupy their mind. Visit with team members. In most cases, the big picture will reveal itself through casual discussion.
Evaluate your findings. In most cases, certain functions are best served by introducing shared program libraries. Address these accordingly. As soon as areas have been identified in which a common service might be best utilized, determine a course of action for the development and/or integration of each service. You might have to purchase a solution. If you are developing software for resale, it might be possible to partner with a few vendors based on various business factors or constraints. Otherwise, the service might have to be developed. This could happen if there is a fairly unique set of criteria that is not addressed by existing solutions. Look around carefully, however. It's likely that something close enough to what you need does exist. It might be necessary to write an application service if you're a software vendor, and there's a service unique to the market segment. In that case, of course, using a competitor's solution would not typically be an option.
Look to Standards
In researching my own projects, I use the Web as my reference, as most of us do. It can be difficult at times to filter through the noise, but I have developed a pattern that helps me identify either potential application services that we must address in a current development cycle or ones to watch for possible inclusion in future cycles. I review standards specifications. They might be industry specifications, such as the ebXML or HL/7. Sometimes, they are lower level, such as the various Java Specification Requests (JSRs). Seeing what is going on in these standards bodies tends to point out what others in the software industry consider application services. If available, I take a look at the offerings of the companies that make up the specification committees. In general, I find that this provides a fairly good overview of many application services for several segments of the software industry. Even if I cannot find what I am looking for, I typically walk away from the exercise with a better understanding of what we might have to develop to provide a necessary service.
Very few, if any, would argue against the need for common application services. The trick becomes identifying the specific need for any common application services. As is the case with much software development, this is a mix of science and art. The science is what you learned in school. The art is a combination of creativity and knowledge gained through experience. Sometimes, the decision is very obvious, as with the case of the database-management system. Other times, the need evolves and becomes apparent over time.
Ask yourself these questions:
- Can I abstract this problem to suit all the needs of my application?
- Can the abstraction be taken to a higher level, encompassing additional yet similar functionality?
- Is the issue better solved by just writing a shared program library, or would an independent process be more appropriate?
- What general trends in the software industry address my problem?
- With how many people within my organization have I talked about this problem, both technically and business-wise?
- Is there an industry specification that addresses the issue? Who has implemented the specification, and how?
- How does our competition address the problem?
Work with your team. Help them to help you. Listen to what they are saying. Stay informed on the direction of your particular industry, from both a business and technical standpoint. Share that information throughout your organization. Keeping all of these communication channels open eventually will reveal the needs that your project has or will have for various application services.
Gain an understanding of the industry standards that affect your organization, and bookmark those Web sites. Subscribe to relevant journals. This is often tedious reading; but, after some time, you will be able to navigate to the portions of the information that will be of particular interest.
Even if you do not use the technologies that are offered by application-server vendors, regular visits to their sites will provide insight to both low- and high-level application services. Sites that I visit regularly include:
- Java Community Process.
The purpose of the Java Community Process is to further the evolution of the Java platform collaboratively. There are a lot of ideas that pass through this site. Many of the JSRs define various application services. It is a great site to learn what many organizations are thinking and how they solve problems.
- IBM WebSphere Software.
- Microsoft Developer Network (MSDN).
- Oracle Application Server.
- GlassFish Community.
About the author
For over 20 years, Ray Elenteny has worked primarily on server-side, cross-platform infrastructure development for software products. He thoroughly enjoys the rapid pace of the software industry. Applying relevant technology to business problems, interacting at all levels within an organization, and mentoring are some of the day-to-day activities in which he takes pleasure. Ray participates in Atlanta's IASA Chapter and Java User's Group as both an attendee and a speaker.
This article was published in Skyscrapr, an online resource provided by Microsoft. To learn more about architecture and the architectural perspective, please visit skyscrapr.net.