Samuel Johnson once said that he was astonished one day to come to the realization that he had been speaking prose all his life without realizing it. Similarly, we in the software industry often attach weighty meanings to what should be simple words and concepts. In the process, the simplicity is lost and the words intimidate us rather than support us.
Today we're laboring under what seems to be a requirement to express all of our business applications using a service-oriented architecture (SOA). When you hear the word "service," all the simple meanings seem to disappear (such as, something that serves us) and only the weight and the burden remain. To say "service" somehow automatically means using Web services for all the communication between the parts of our applications, let alone with all the other applications out there that we are required to have the ability to talk to in order to survive and prosper. It brings with it a list of groan-inducing three-and-four-letter acronyms - SOAP, WSDL, SSL, SAML - along with such a host of burgeoning standards that they have to be lumped together as WS* (read "WS splat") as you're splattered by the implications of juggling security, routing, reliability, eventing, addressing and more without dropping anything on the floor.
Why did it get so difficult? Wasn't this all supposed to make it easier for us to build successful applications that handle our business needs? Do we even remember the business needs after we're done struggling with all the technology requirements?
I'd like to suggest that, like Johnson's ironic observation that a highfalutin word can really be applied to commonplace things, you should think about the services of an SOA as serving you in your business needs, not making your life more complicated. And, like all the mundane statements that can be given a greater cachet by labeling them as prose, the right expression of the solutions to your business problems can turn into services and even fit into a true SOA if you think about the simplicity of the business task at hand and let the technology serve you without getting in the way. Let me offer some examples of what I mean.
Separate UI from Business Logic
What is the first step that has been recommended for years, maybe decades, to turn the spaghetti code of a typical older application into something more flexible and forward looking or future-proof? Separate your user interface from your business logic. Take the logic that really captures your business rules and extract it from the code that puts the old green-screen interface or somebody's proprietary client-server graphical user interface (GUI) in front of the user who needs to do data entry that the business rules deal with. Now you're on the right path to being able to keep the value of those business rules intact when the user interface (UI) fashions change out from under you, as you know they will (as often as the folks in Redmond and elsewhere can manage to make it happen). What's the alternative to nicely separated duties between the logic and the UI? As people kept saying with a quiet smile at an architecture conference I attended, "Thank goodness for screen-scraping tools."
Instead, with a proper separation of roles, when you're confronted with the next revolution that's the equivalent of having to deploy your old application on the Web - or dealing with the fact that you still haven't managed to deploy your current application on the Web — you won't have to scrap your core business value and code it all over again. You'll be set up to get to your data and your domain logic from a variety of interfaces. You'll even be able to let parts of the application that don't have a user interface at all access the data by using the same application programming interface (API) calls that your nicely separated code now uses. You'll even be most of the way to letting other applications you never heard of before get at your data by publishing the API for them, which will make your code look a lot like a service.
Here's another example. What's one of the most common elements of a bloated application, one that has grown and grown over the years without much coding discipline? What do harried programmers on a deadline do whenever they need a function that's sort of like something already in the application, or maybe even exactly like something that's already in the application? They copy and paste code into a new procedure and make the necessary changes to do what the specified requirements say they need. They could go through the code and factor out all the common parts that apply to both cases, or all of a growing number of cases, taking care not to break the code they started with and then parameterize the variations. But as Calvin - of Calvin and Hobbes fame - screamed as he read the directions on the back of the macaroni and cheese, "Six minutes to microwave this?! Who's got that kind of time??"
Many applications have so much repeated and copied code that the similarity among all the resulting procedures is the closest thing they have to an architecture. A lead developer on a large enterprise resource planning (ERP) application once admitted to me that she had identified 157 different places in the application where it does a price calculation.
What's the well-architected solution to this kind of problem? You have to encourage - and enforce, if necessary - the discipline of not just copying code into a new procedure whenever it is the handiest thing to do. Instead, you need an architecture that gathers all the logic that supports a related set of data in one place, so that whenever someone needs to make a change or an addition to the logic, they go to that one place to do it. Any other part of the application that needs to use or update that data knows where to go to get it. If you provide a sufficient set of calls into that one procedure, or perhaps a set of related procedures that always run together, it can satisfy all the requests in a consistent way. The reduction in the code bloat of the application can be staggering. When you develop in this way, other applications that need to access the same data someday can use nearly the same interface to get at it. Then it is close to becoming a service.
What's the next consideration in our quest for a useful and flexible architecture? The good old days when everything ran on a single machine (what was wrong with those days, anyway?) seem to be long gone. Truth be told, there are advantages to having the database sitting who-knows-where and users all over the world using devices of every imaginable description to get at the data. Anybody who's ever asked a store clerk whether the last red shirt on the shelf is also in stock in blue and had the clerk answer by pointing his or her scanner at the red shirt to read the bar code can attest to that. If you want to build an application you won't regret, make sure that all the code that really belongs together runs as a unit under all circumstances, and that all the other code that might want to talk to it runs in an independently defined unit, without any dependencies between the two. If you don't, you'll be sorry when you discover that for some configuration you never considered, the two chunks need to run on two different machines. Separating out the user interface is only the beginning. If you make sure that every business object that manages a rational chunk of data can happily run independently of every other business object, you're on the right track. And then when someone tells you that one of those chunks has information badly needed by somebody on another corner of the planet, you can respond with a confident smile and not a shiver of dread.
One of the hot buttons in application development now is what people call workflow. Developers, especially people designing and building applications for a larger audience than just one unified user group, realize that requirements differ for how all the steps in a business process have to take place. Just when you thought you were done coding, you are informed that Susie Q - and Susie Q has clout - insists on entering the stock code before the customer ID rather than the other way around, as it was originally specified. This isn't as simple as it sounds. Entering the stock code requires running a whole business object that validates the stock code for the country of origin, assesses its availability and more. Entering the customer ID requires accessing another similarly complex object. But wait! You coded each of those business objects so that it didn't matter where they run or if they're both in the same place or whether the caller is a user interface or a batch program. You can tell Susie Q, "Nothing simpler; it'll be done in a jiffy."
In a more serious scenario, that highly complex multistep ordering and pricing algorithm you worked so hard on (remember the 157 price calculations you replaced with one?) now must be applied in another country you never considered, but where your company has discovered it needs to do business in order to survive. Telling your prospective new customers, "Well, that's not how we do things where we come from" just won't cut it. All your pricing work is going to have to be torn apart so that step five can execute in front of step four, and so that step seven can be replaced altogether by a brand new step that reflects the tax requirements of the new customers. Well, you are so ready to take care of this requirement. After all, you coded the business object that manages each step independently so that there weren't any data dependencies or ordering dependencies between them. With such nicely behaved code, you can reverse step four and step five and replace step seven without any of the rest of your application being the wiser. It's the most natural thing in the world to you to express all of your business objects as, you know, services.
Armed with such civilized code, SOAP and WSDL can hold no terrors for you. You want the output as XML? Nothing simpler. It just becomes another call in a well-defined API. Your boss wants to be able to resell the pricing algorithm without the rest of the ordering code? No problem. They'll never miss each other.
Services as Best Practices
Jason Bloomberg at ZapThink reminds us, "You can't get SOA from software because SOA consists of best practices." Bingo. You need to create an architecture that sets you up for success when the world changes, regardless of what technologies they throw at you. New technologies should be merely new wrinkles in an already familiar and comfortable suit, no more distressing than Susie Q's special data entry requirements. You can't let technology dictate how you think about the basic job you came to work to solve - solving your company's business problems and letting yourself and your company succeed in a changing world.
Does this mean that SOA is simple? No, not automatically. After all, there's been enough sloppy code written to demonstrate that it is easier to write poorly architected applications than good ones. But with the right motivations in place, architects and developers should have what is needed to build applications where everyone understands how the right architecture makes everybody's job easier in the long run. Anyone who's had to code that 158th pricing algorithm variation will know exactly what I mean. So a good architecture becomes its own reward. And as for the service-oriented part of it? Well, everybody thinks of their business logic as a set of services, don't they? It makes life so much easier.
Register or login for access to this item and much more
All Information Management content is archived after seven days.
Community members receive:
- All recent and archived articles
- Conference offers and updates
- A full menu of enewsletter options
- Web seminars, white papers, ebooks
Already have an account? Log In
Don't have an account? Register for Free Unlimited Access