Previously I’ve mentioned that we’re on a mission (part 1, part 2). We’re instituting a new platform. A central part of this initiative is a remote service layer available to all of our applications. There is a lot of talk out there about services, orchestration, and RESTfulness, but who’s talking about what is IN that service?
Me, that’s who. Buckle up as we’re about to begin part 3 of our journey!
I was originally going to discuss the dangerous phenomenon of scope creep. This is the result of the scope of a project being expanded over its lifecycle. While this is indeed something to watch for, and can lead to disaster, I’m going to go in a different direction for this entry. Recent conversations within our team brought to light a more poignant topic. One that still gets to the heart of the matter I wanted to address!
“It is not the mountain we conquer but ourselves.” – Edmund Hillary
Top Down means to start with the business use case and break it down into parts and implement those parts. From a services standpoint this would mean once the application has defined what it needs appropriate services are created to satisfy those needs.
This is where you’ll see odd service names, or service names that mirror business units. You’ll also see something else if you look closer. Methods that don’t quite fit together. If you take the business use case out do the calls seem to be a jumbled mess? Do they cross specific areas or domains?
Let’s define some more terms:
Separation of Concerns
This is the practice of ensuring there is minimal to no overlap in functionality between any two systems – in our case applications and services.
Areas of Responsibility (AOR)
This is a military term that defines a geographic area that a commander has authority over. For our purposes that refers to logical concepts and models and which application or service is the commanding officer.
If the only things that makes the individual method calls make sense is the common consumption by a single application you have a warning sign. Break the key ideas into groupings. These groupings can lead you to see the real AOR’s.
Something that may not be visible, and it one of the harder ideas to grasp is what you’re missing with Top Down design. You can meet the needs as requested and be successful. You had a request and you responded. Huzzah. You consolidated logic and optimized performance. You’ve applied caching and load balancing and have a robust system. These are all incredibly valuable and worthy in their own right… but would you believe that there’s more?
This is where Bottom Up design comes in.
Step away from the originating application and become the service. You really need to step into these shoes and now look at the world from this point of view. Ask the hard questions! Should my Beach service respond with ratings? Yeah, that makes sense. It’s information that is very specific to the beach. When I want the rating I’ll most naturally want to start there to see if I can find this data.
Should it respond with directions? Should it contain it’s own address? Oh, now we’re approaching the grey area.
How many other objects have an address? How many other objects will need to find directions? These concepts are related to the beach, but are not in the beach’s domain. I recommend keeping them out.
The beach can have a URI to an address object served by the address service. This is logical. The address service can return latitude and longitude coordinates. This is also logical. And the mapping service can give me directions, even if that service is really just Google Maps. Does Google know about my Beaches? Anything about my rating scheme? Nope, it doesn’t have to and is more powerful because it doesn’t.
Fiercely protect what is and is not in the domain of each service. When you do this something grand can now occur. Emergent applications.
When your services are designed to meet the applications needs, and yet remain flexible and locked into a core definition of what that service represents. It can be used by others. Used in ways that you didn’t design. This is the critical part. If you create a Bucket service intended to be used at the beach you could have success defining how much sand it can hold. But what a missed opportunity. The service that simply defines the bucket and rules for the bucket is more powerful. If that Bucket can be used to hold water, oil, rocks… whoa. How about turning it upside down to be stacked! You didn’t think of that one, but the service should. Not. Care. Define the entity and let the use case and applications define the rest.
A system of services that can be leveraged for uses beyond their design. New concepts and ways of assembling applications that were previously impossible. This is what we’re doing. We’re starting to see the potential. We’re fighting for the services because they can’t fight for themselves.
“Tough times never last, but tough people do.” – Robert Schuller
Hold onto the vision, guard and guide it. Success is out there. Bottoms up!