Posts tagged Architecture

Service-Oriented, Event-Driven Part 1: Events

The real-world does not follow a linear, step-by-step process in order for things to occur.  We may rationalize and tell ourselves that things happen in sequence and that ‘c’ won’t happen before ‘b’.  We model our systems this way and we code this way because we view the world through this lens.  I am beginning to fully believe that we must shatter this lens, because it colors the world with a perspective that doesn’t fit.

The real-world is disorderly, it is chaotic, and it is made up events – notable changes in state – that we must react to.  The traffic light turns green, so you go, except the car in front of us isn’t going so now you can’t go. You order coffee and wait, and then the guy behind you gets his coffee first with yours ready a moment later.

Integrating systems using the lens of events is key to success, especially when the systems you are integrating are not yours or they belong to an entire other organization.  This is where a firm understanding of the information being exchanged as well as when it will be exchanged becomes key.

Udi Dahan posted an article titled “Don’t Delete – Just Don’t” a few weeks back.  In that article Udi explores soft deletes versus hard deletes, but he also raises another interesting thought that I’d like to build on.  Our systems maintain the state of records over time.  That state can be things like “entered”, “active”, “inactive”, “accepted”, “denied”, and whatever the business case may be.  As I have already described events as notable changes in state, so what if we start looking at our systems records and the notable changes in state, what would we see?

Dru Sellers frames this in “Events Are Awesome” where he writes:

“I have also started to think about what it would mean to develop a system ‘event first’, and then you can look at what needs to be done when these events happen. It builds completely different systems, based on some initial drawings.”

Over the last few weeks I have been thinking about the same thing.  So let’s hop on the example bus and see where it takes us.

Suppose we run a pizza delivery business and we’re going to automate what has been a manual process.  At a high-level, we could see a few processes we need: Customers should be able to place orders, the kitchen needs to be able to be notified of orders so they can cook them, the delivery supervisor needs to know where orders are going so drivers can be scheduled, and the store manager needs to know about the volume of orders so that the financials can be reviewed.  Skipping through the normal business analysis that needs to take place, we’ll say that we end up with four systems, each with a distinct job. 

  • The order system processes, validates, and accepts pizza orders from customers.
  • The kitchen management system accepts orders, verifies stock levels, and notifies the cooks so the order can be prepared.
  • The delivery scheduling system accepts orders, determines the route, and schedules a driver to deliver the order.
  • The financial system accepts orders and records details about the underlying transaction amounts.

If we examine the order system using the events lens we can come up with some notable events: “Customer Submitted Order”, “Order Validated”, “Order Accepted”.  With each one of these events a notable change in state has occurred and the information about that order should be communicated.  For example, the delivery scheduling system might want to know about orders when they are validated because it takes longer to schedule a driver, whereas the kitchen management system might not want to know about orders until they are accepted so that ingredients are not used too soon in the process.

You may argue that this is not much different than procedural thinking.  We could just code something to the effect of:

if (order.status == validated) {SendOrderToDeliverySystem(order);}

While that one line of code may be the simplest thing that could possibly work, what have we done?  In essence, we have now coupled our order system to the delivery system.  And this is where procedural thought begins to break down because that line of code is so specific that when we need to change it, the change has an effect that we may not fully understand especially because over time code becomes more complex as systems are expected to do more.

Consider the case where now the Kitchen System wants to know about orders when they are validated instead of accepted.  We now have to refactor our one liner to something like:

if (order.status == validated)
{
SendOrderToDeliverySystem(order);
SendOrderToKitchenSystem(order);
}

Now consider if we used the .NET Framework’s notion of events:

public delegate void OrderValidatedEventHandler(PizzaOrder order);
public event OrderValidatedEventHandler OrderValidated;

…{ //more code and curly braces }

if (order.status == validated && OrderValidated != null) {OrderValidated(order);}

If all of our systems were implemented as components with references to each other we could hook onto these events and reduce our codebase.  But even then we still have a problem – coupling.  Using direct references is a form of coupling that ties those components together.  We can use Dependency Injection to reduce that, but then we still have the question to answer – what if each of our 4 systems comes from a different vendor?

In Part 2, we will discuss autonomous services and why we want to reduce coupling.

“Lessons Learned from Bruce Lee” – An Architect’s Perspective

Clint Edmonson tweeted about this awesome post from Sources of Insight – "Lessons Learned from Bruce Lee".  This post really resonated with me so I thought I would add some of my thoughts to the original author’s work, giving it a software architect’s perspective.

  • "Be YOUR Best" – Self-explanatory.  The only person you should try to top is yourself. 
  • "Absorb what is useful" – "It’s not about blindly adopting patterns and practices.  It’s about taking the best of the best and tailoring it."  The author’s original words are almost straight out of the mouth of a modern architect or software developer.  There are a lot of technologies, patterns, and options but not all of them are proven, take what is and add your own experience to the mix.  ("Mash-it-up" if you want to be Web 2.0 about it :)
  • "Keep an Open Mind" – Sometimes you will learn something in a specific context and attempt to always apply in that context.  Throw away the context and look at it differently.  You may then see that to apply SOA does not mean it has to be implemented with web services.
  • "Stay Flexible" – If you read the Architect’s Creed then you know I am a big proponent of flexibility in software systems.  That flexibility starts with the architect.
  • "Focus on Growth" – Growth is key for an architect and software developer.  You have to keep pushing yourself to the next level.
  • "Know Thyself" Every leadership manual or class has a section on this.  You are your greatest strength and weakness and your knowledge of those factors will affect your designs and your team.
  • "Make Things Happen" – Don’t stop after a big success, keep going.

Be sure to check out the original post on Sources of Insight to catch all of the authors favorite points and perspective.  It’s a great read and there is something for everyone.

Should You Fix Working Software? Part 1: The Question

A few weeks ago I did my first code review on work that I had no involvement with other than some initial brainstorming and high-level architecture.  As I was looking at the code I only saw one or two things that concerned me but even those were not critical.  When I typed up the review I realized that first and foremost I need to clarify that the software was working and frankly, it’s hard to argue with working software.

In this case the component was designed with good object-oriented principles and there was really only one place where I thought a particular class had too many responsibilities.  The developer, who is pretty new to REJIS, was extremely open to the feedback and all in all it was a good experience.

This had me thinking, what if you were reviewing software which wasn’t designed using good object-oriented principles?  If the software was working, what angle would you take to suggest changing the design without offending the author?  This is a tough question because there are many organizations where the development teams have a mix of procedural minded and object-oriented coders.

My friend and colleague David Risko wrote about this in his post "The Elusiveness of Object-Oriented Thinking".  His post highlights some of the challenges of bringing developers into the OO space.  Fundamentally OO breaks many of the traditions of traditional procedural thinking.  It is a mind-shift that can be difficult to make and in a mixed environment where you have those in an OO mindset and those who are not, the differences begin to surface more often.

So what about that 1,000 line class with 3 methods and if statements nested 5 deep?  It works and it’s consistent.  How do you show that developer ways they could improve it’s readability or flow? 

Software Architect’s Creed

Here are the nine points I presented tonight at the St. Louis .NET User Group.  The slides and a printable PDF will be available in the next day or two.  Thanks to all who attended!

Accepting my responsibility as an architect I will strive daily to learn and perfect my trade.

Readily will I defend my organizations IT investments from complexity, our greatest enemy.

Changing requirements will not break my design for it will be flexible and able to change with the requirements.

Helping developers to understand the reasons for the architecture and seeking their input is of great importance to our success.

I will never use acronyms or suggest technologies that are not pertinent to the problem at hand.

Technologies evolve and I know that solid architectures should accommodate and enable these evolutions.

Every day I will strive to help our software achieve ideals that will make it flexible and easy to maintain.

Concern for the success of my organizations IT investments will drive me to make appropriate decisions.

Teaching others about my trade will be an overarching responsibility that I accept as part of my duties.

*Update*

Posted slides to slidshare.net here.

Modularizing WCF with Unity

For a new project at work I thought it best to use dependency injection to deal with some complexities we were facing.  I also wanted to get in and do some mocking in our unit tests to get a good feel for that.  Since we use the Enterprise Library I decided it would be easiest to roll with using Unity.  I have previously blogged about using Unity but this would go even further, because we would be injecting a dependency into the constructor of the service as well as injecting dependencies into the service’s core library.

I did quite a bit of homework and reached the conclusion that in order to do this you would need to hook into WCF’s pipeline and override several key areas during the service host creation and service instance creation.  The best article I found to get me started was this one by Steve Moseley.  Steve broke it down into 6 steps:

  1. Creating a custom instance provider that resolves the service
  2. Creating a custom service behavior to plug in the new instance provider
  3. Creating a custom service host that will add the new behavior
  4. Creating a custom service host factory (which configures your Unity Container)
  5. Changing the service host factory in the .svc file
  6. Inject your objects (through configuration)

His instructions were fantastic for steps 1-5 but step 6 left me to think on my own a bit.  The constructor of the new service we were working on needed an instance of its “core” library which will be the real work horse for the service.  Typically our services only provide a gateway into some other functionality so the service layer handles messaging and translation then delegates the work to a core library which can do whatever it needs to. 

This service would also be a little different than most because we would be relying on both internal and external “suppliers” to provide data to our core library.  These suppliers could be in the form of remote web services, local services, or shared assemblies.  Our core library itself will also need it’s dependencies injected at runtime.

Step 6 involved a bit more detailed study of Unity in which I did the following:

  • Defined typeAliases for each of the dependencies I would be injecting
  • Defined type mappings for the simple dependencies which had only a default constructor
  • Defined typeConfigs for the complex dependencies which required other dependencies passed to their constructor

I chose the constructor injection route because the service should not be created without a core library and the core library should not be created without its supplier dependencies and data access layer.  I believe I could have accomplished something similar had I used default constructors and exposed read/write properties for the dependencies.  This would have removed the constructor requirements but potentially caused issues if someone were using this class without supplying the dependencies to the read/write properties.  So, constructor injection wins for now.

In the end the config looked something like this:

<configSections>
  <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</configSections>
<unity>
  <typeAliases>
    <!-- Lifetime manager types -->
    <typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <typeAlias alias="external" type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager, Microsoft.Practices.Unity, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <!-- User-defined type aliases -->
    <typeAlias alias="ISupplier" type="MyService.Contracts.ISupplier, MyService.Contracts"/>
    <typeAlias alias="MyService" type="MyService.Service.MyService, MyService.Service"/>
    <typeAlias alias="ICore" type="MyService.Contracts.ICore, MyService.Contracts"/>
  </typeAliases>
  <containers>
    <container>
      <types>
        <type type="ISupplier" mapTo="MyService.Suppliers.ExternalSupplier, MyService.Suppliers" name="ExternalSupplier"/>
        <type type="ISupplier" mapTo="MyService.Suppliers.InternalSupplier, MyService.Suppliers" name="InternalSupplier"/>

        <type type="ICore" mapTo="MyService.Core.MyCore, MyService.Core" name="MyCore">
          <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
            <constructor>
              <param name="externalSupplier" parameterType="ISupplier">
                <dependency name="ExternalSupplier"/>
              </param>
              <param name="internalSupplier" parameterType="ISupplier">
                <dependency name="InternalSupplier"/>
              </param>
            </constructor>
          </typeConfig>
        </type>

        <type type="MyService" mapTo="MyService.Service.MyService, MyService.Service">
          <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
            <constructor>
              <param name="myCore" parameterType="ICore">
                <dependency name="MyCore"/>
              </param>
            </constructor>
          </typeConfig>
        </type>
      </types>
    </container>
  </containers>
</unity>  

Once this was working successfully I took a step back to the unit tests project to do some mocking.  I know someone out there is thinking “why would he try that before unit tests?   Couple reasons: 1) This was an entirely new endeavor and its easier for me to get the final concept working 2) The first 5 steps from Steve’s article required some low-level work to hook into WCF.  Rather than unit testing that I decided to flush it out by actually firing up a sample service to work out the kinks.  Next time the unit tests will be done first…

The Calm Before: New Role, New Challenge

I have been quiet the last few weeks though I have been meaning to post a few things.  Since the beginning of 2009 I have been working to get several people on my team up-to-speed on Windows Communication Foundation and service oriented design which has proven to be no easy task.  Condensing two years of study and experience into short lessons has been difficult because there is no cookie cutter mold that you can hand someone so they can bake up some services.  Services take thought and consideration, planning, and careful implementation.  Giving someone a template to start from is helpful, but without understanding why the template is set up the way it is much of that experience and knowledge is lost.  I think this is largely a fault of my own because of the rushed feeling I have to get this knowledge transfer going into 2009.

On Friday the general manager of REJIS announced something that I think most people saw coming; the beginning of our technology migration plan to move from a Mainframe environment into a Windows based environment.  As he outlined it at a very high level we see the picture of a multi-year company-wide effort to make this happen.  This is a major shift for REJIS because we are known for our ?green screens? and our core competencies lie in the processes that are running on our mainframe systems.  REJIS will be redefining itself as it moves in a new direction to offer new products and services to customers.

Just prior to the announcement I learned the role I would play in this new endeavor.  I will be working on the small team that will design the overall architecture as the lead architect.  The team is currently comprised of three people including myself.  One is a Senior.NET developer and the other comes from the mainframe side though she has spent her more recent time studying .NET and assisting with project designs and documentation.  We will be working directly with our IT Director and probably every division of the company as this affects REJIS all the way from the top down.

To say that the coming months and years will be easy would be a gross understatement.  We will be converting a collective hundreds of years of peoples work to a new platform.  Some of my closest colleagues have literally spent their entire careers building these systems.  To call it a conversion is a bit misleading as well.  What is being converted is that knowledge and experience in the industry we serve and in that conversion will be a redefining of REJIS into a more agile company ready to handle the changes the future will bring.

For me this is the best opportunity I could be called for.  Over the last few years I have been one of several voices calling for better attention to architecture and design on our new systems and for constant attention to how new technologies will affect what we can do and how quickly we can do it.  Now will be my opportunity to make REJIS a little bit better and to prepare our IT systems for a future that will allow them to grow, scale, and change in the demanding environment we work in.

I press forward humbled that I will play such a big role in this change and looking to peers and colleagues for their support and advice.  People like David who never cease to amaze with their forward thinking, Clint and Denny who make their mark evangelizing the need for architecture and providing sound advice and wisdom from their experience, and my other (blogless) colleagues at REJIS who go along with my crazy ideas and add a little crazy of their own. 

The next few weeks will involve a lot of groundwork, some travel, and time to reflect on the road ahead.  It will be long and trying and for those of you who subscribe to my feed you will have a front row seat to the transformation that will happen.

Exposing Services: Some Principles Revisited

In my opinion the principles driving service oriented architecture are a great evolution of software design.  I have been working to apply many of those principles in work we are doing to update our core offerings as services.  While the principles are widely published I wanted to add some of my own value to them from recent experience and reflection.

Services should enable business processes. If process can’t be completed "on paper" or no one understands it exposing it as a service may not be successful.  Services should expose that business process in a meaningful way that replicates the paper process as closely as possible.

Services aid in loose coupling between systems.  By exposing services with standard contracts that represent their messages in a canonical format you reduce coupling between systems.  The schemas and WSDL become the contract by which clients and the service communicate.  As long as that contract is not violated the service can do whatever is necessary to fill requests.  Changes to data stores or processes should have no impact on those contracts.

Services exchange messages. I have seen several services which were passing encrypted byte arrays that were strings which were cast into a byte array, encrypted, and serialized  by the service then deserialized, decrypted, and cast into a string and transformed to an XML document on the receiving end.  While this offers security through obscurity it violates other principles including meta data exchange and contract first design which uses that meta data so all clients know what messages to expect.  Services should use messages that are exposed in a canonical format via schemas and WSDL’s (for web services).

Messages should contain all the elements required to complete the business process.  This is a great principle I found via Nicholas Allen’s Indigo Blog in a white paper published by Ythos.  This will allow you the most flexibility in situations where that message will be routed to several services to fulfill the business process.  In a real world context I can think of few, if any, processes where you fill out multiple parts of a form and send it to different entities for processing.  The form contains all the data needed and you send to one place and are not concerned if it needs to be routed to several locations to complete your request.

If systems need data from each other they should ask for it.  This is one of my favorite principles gleaned from Clint Edmonson.  The simplicity of this principle is also its source of elegance.  A good service offers meaningful ways for clients to request the data that service knows about.  The requests should require minimal amounts of "state" or "context" and be flexible to allow for data to be requested multiple times if one attempt fails.

Exposing processes as services lets you focus on the process and build several different UI’s to consume those services.  I have not yet reached a point where this is a reality at my employer but we are very close to getting there.  As you build more services and more processes are enabled in standard ways you can begin to design different types of UI’s to interact with those services.  Do you have a core service exposed as a web service using SOAP but are concerned that is too much lifting for your AJAX clients?  No problem, expose a wrapper service that uses REST and a lighter message format and have that translate to your internal web service.  This keeps your functionality in a central location but has the flexibility to meet special needs for clients.

These are some practical things I and others have been working to apply with great success.  A key to building an SOA from the ground up is to start with simple services and keep them simple.  The trick is to keep an eye to the future and be sure your services will be governable and promote reuse of data models, etc.  While a ground up approach is not always the best in some situations that is where the call to services needs to begin.  Good architects will be looking out for what will better align IT with the business, add value to the processes, and save on costs due to a more maintainable infrastructure.

Building With Lego’s: Using What’s in the Box

My wife and I recently decided to dust off the old Lego sets and start building.  We had collected quite a few Star Wars Lego sets over the years but they were all dismantled with the pieces mixed together in a big Tupperware container.  What I always found fun about Lego’s is that for the basic sets you see a lot of the same pieces over and over and they get used in very clever ways.  Javelins from the Knight set become stabilizers for the wings of the Ewok Attack set.  Revolvers from the cowboy set are the same pistols used by space assassin Boba Fett.  There are very few custom pieces in any of the variety of branded Lego sets.

Lego has obviously made a conscious decision that it is just not sustainable to make all custom bricks for every set produced.

At the August LLF event I had the fortune to speak with a data architect with a very large financial company.  One of the first questions he asked me was if we had developed a canonical data model.  He also asked if our domain had a model we could use, which the justice domain does – NIEM.  This was a very interesting conversation that really clicked while snapping together Lego bricks.

Today I spoke with one of the architects who has done a lot of work on the NIEM data model, in particular LEXS which is a law enforcement specific subset.  I am currently working on an exchange with a victim notification service and have chose to use NIEM for the exchange.  This is a conscious effort on my part to use NIEM for external data sharing and a smaller model for our internal systems.  I also made a decision that rather than piecing together my own custom schema from NIEM that I would reuse an existing one and ended up choosing LEXS.  With some help from the aforementioned NIEM architect I was provided with a schema that expresses about 90% of what I need and left some open ends for me to fill in.

I now have all the pieces I need for the exchange and I just have to fill in a few pieces which I can build myself and still keep within the spirit of LEXS and save some time on schema development.

Now to help my wife find the last piece she needs.  Some times it can be hard to find the color you need but I’m sure we’ll find something in that box that will fit just right.

Technorati Tags: ,,

Push Versus Pull Interfaces

The best analogies for technical things most often come from the completely non-technical sources.  This post on the Four Hour Work Week blog really resonated with me, especially given some of my current projects.

Push versus pull describes the fundamental choice that must often be made when integrating two (or more) connected systems.  I have struggled with this many times and have found myself over complicating things by coming up with elegant strategies to push data from system A to B and C and so on.  While doing so was leveraging appropriate technologies a simpler answer was staring at me the whole time.

Early on I had developed two interfaces which were pull based.  You want this data, come get it and I’ll give you the data you asked and nothing more.  Simple and effective though it put the burden on consumers to come get it.

Neither of those interfaces has failed to date (we have had problems with how they were integrated in a few systems).

In the course of some new projects I was tempted into over complicating them because I had modeled the whole scenario as pushing a message through our systems.  Thanks to some insightful tutelage from Clint Edmonson he pointed me right back to my pull model and reminded me of a quote I am very fond of.

"Doing old things in new ways"

A fundamental principle Clint teaches is that if systems need data from each other, they should ask for it.  This is some what of a reversal of the legacy approach where systems would often send data to another system that it knew needed it.

Take an example where you have a sales system that needs to get information from n number of vendors.  You could have an FTP site or web service where everyone can send their data.  That should work fine, until you really try it.  Then you end up with n number of file formats and n number of incoming FTP connections, user accounts, etc.  It’s a mess to maintain; ask anyone who has to.

What if you reversed that?  What if your company came up with a simple web service definition and each vendor put an instance of that service up and provided their data in the format specified by the web service?  Then your sales system simply has to go down its list of vendors and call them up to get the data?

Perfect, no problems ever.  Right?  Not quite.  Every solution will, hopefully, present you with new or different problems which hopefully have simpler solutions than problems created by other choices.

I mentioned all of this without bringing up publish/subscribe but that is the core of what we’re talking about here.  You have publishers of data and subscribers to that data.  The publisher provides a consistent, well-defined method of getting that data and subscribers come and get it.  It solves a lot of problems.  Service down, no problem, subscribers can catch up later.  Something out of sync, not a problem, the publisher can resend something if needed.

Push versus pull?  Right now I think things should lean towards pull.  It was a good enough model that the Department of Justice began developing WSDLs and asking partners to put up web services that met the specifications of that WSDL so they could come and get from those partners.  To date it has been very successful, at least in our implementation.

The Architect and the Balancing Act

I’m going to depart some from what I have been posting and touch on a topic that will get a little technical because it involves technical things.  Read on even if you are a non-technical kind of person; I promise there will not be any code.

A big part of what I specialize in is distributed systems design and getting computer systems to talk nice with one another.  As a whole the IT industry has been doing this for a very long time so nothing I do is inherently new or revolutionary.  But the way we do it has evolved over time and we’re now in a paradigm which, I think, captures the essence of what computers systems really should do: represent the ‘real’ world processes we are automating.

Because I’ve made a niche for myself in this arena my boss delegates a lot of data sharing projects to me, if at least to review and make recommendations on what approaches we could take.  In the Justice and law enforcement domain data sharing is the hot topic since 9/11 and believe me when I say a lot of data is finally being shared.  This year alone I think I’ve reviewed around 15 new interfaces and we are implementing about a dozen.

I am currently the lead on four interfaces that will be created to share data with an external vendor for a system migration that is happening for one of our clients.  Originally the interfaces were planned with some of our legacy integration patterns but we have since chosen to implement them in newer technologies that will have a longer sustainable life.  Our team in particular has a lot of systems tied to our mainframe which limits our methods of interfacing with other systems and long term will cause an issue because most schools aren’t teaching COBOL as a mainstay of their MIS or CS programs. 

I like to look at the future as well and keep those things in mind as we go forward sharing our data and enabling new interfaces.  As I said, nothing I suggest is inherently new or revolutionary, but hopefully it is sustainable and represents the real world processes in a meaningful way to all the partners in the project.

The four interfaces I have been assigned were four that we had identified as candidates for a Service Oriented Architecture approach using web services or another service such as a queue.  Due to resource constraints we were not going to work on these for some time; until this migration came up.  Because a client needs this immediately we will be able to shift resources to make it happen.  This is where the balancing act begins.

We are integrating with a vendor that we have not worked with yet.  Most of my experience with external vendors has either been with the Department of Justice (which is going really well) or with a few other local vendors, one who’s idea of a project plan consisted of "Just send us what you have and we’ll take care of it" (80 work hours later they finally sent us their data element requirements).  My organization has a lot of experience doing integration and as such we can be seem like a big contract driven beast, but that is from a lot of experiences where the plan resembles "send us what you got" and ends up in huge disputes and a round or two of the blame game.

In our final proposals to the client and vendor we changed our approach to use web services.  A decision that myself and a senior staff member (as in 44 years with the organization) agreed would be best long term, even though he doesn’t speak XML or web services, he understood why we would want to use that approach.  I believe this to be the best choice we can make given all the other variables.

What is beginning to happen now is the inevitable interface creep.  Because every computer system has certain idiosyncrasies in how it works with data or represents those processes things get really fun when you start connecting two systems, especially when the domains you work in already have a history of differences i.e., courts and law enforcement agencies. 

Many of the legacy interfaces I see were developed for specific purposes and for specific systems.  Which really is fine because they get the job done.  System A shares it data to System B and everyone is happy.  But then system C comes along and it has different idiosyncrasies from System B and so System C demands that System A accommodate for those.  The result: Someone copies the code from System A and modifies it to share data with System C thus resulting in two interfaces which share the same strengths and flaws.  And someone has to maintain those.  Indefinitely.

I want to prevent the situation above with Systems A,B, and C from starting at all.  How will I do that?  System A will expose a consistent abstraction of it’s data with a standard contract that is unchanging.  The data will be shared in a meaningful way that, hopefully, will accurately reflect the most common business processes that system performs.

That last sentence is key to this whole balance act.  It is your job as the architect to ensure that your systems interface accurately reflects the processes at a high enough level of abstraction that it is useful to any external parties even with all the little idiosyncrasies their system and your system has.

Undoubtedly as this project goes on requests will be made like "How about you always send us X with this response for this operation and Z for this one?"  This is where the architect has to mediate, protecting the integrity of the external interface while allowing the flexibility to support the needs of known and unknown third parties who need your data.  It will be a delicate act and one that I will be walking once again over the next weeks and months. 

I can’t prescribe a one size fits all approach because a lot of this is situational.  Is it an existing vendor or partner who has worked with you?  Then they most likely understand.  What if it is a new partner?  What if they have no way to speak to you using the same technologies (web services, what are those?). 

As we continue this paradigm shift from one model of systems to the next these situations will continue to put architects in the middle of balancing the integrity and consistency of their own interfaces, growing those systems into the futures in a sustainable way, and all the while meeting contractual obligations.

If you joined technology to get away from these kinds of problems it might be time to find a new job!